搜索
bottom↓
回复: 16

C8051F040单片机P4~P7端口输入设置问题请教

[复制链接]

出0入0汤圆

发表于 2016-4-19 10:00:15 | 显示全部楼层 |阅读模式
C8051F040单片机低位端口P0~P3可以通过PnMDOUT和PnMDIN设置IO口的输入输出,但是P4~P7在c8051F040.h文件里只有PnMDOUT寄存器,只能设置它的输出模式,没有设置输出模式的寄存器,请问大家
怎么操作才能吧P4~P7设置成输入模式

出0入0汤圆

发表于 2016-4-19 10:12:09 | 显示全部楼层
对照下手册,是不是被阉了

出0入0汤圆

 楼主| 发表于 2016-4-19 10:17:45 | 显示全部楼层
sxmilovebb2 发表于 2016-4-19 10:12
对照下手册,是不是被阉了

http://blog.sina.com.cn/s/blog_6edf67100101oivd.html
看了一些资料不是太理解

出0入0汤圆

发表于 2016-4-19 10:35:36 | 显示全部楼层
17.2.3. Configuring Port Pins as Digital Inputs
A Port pin is configured as a digital input by setting its output mode to "Open-Drain" in the PnMDOUT register
and writing a logic 1 to the associated bit in the Port Data register. For example, P7.7 is configured as
a digital input by setting P7MDOUT.7 to a logic 0, which selects open-drain output mode, and P3.7 to a
logic 1, which disables the low-side output driver.



哥们看官方手册啊  

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2016-4-19 11:23:51 | 显示全部楼层
麻烦能给我讲一下吗,这个只P4的数据和P4的工作模式寄存器,我都看了,还是不明天怎么设置为输入模式

出0入0汤圆

发表于 2016-4-20 10:06:48 | 显示全部楼层
陶新成 发表于 2016-4-19 11:23
麻烦能给我讲一下吗,这个只P4的数据和P4的工作模式寄存器,我都看了,还是不明天怎么设置为输入模式 ...

看手册不认真。

PnMDIN是设置输入模式,模拟模式还是数字模式,对于纯数字口,哪里来的模拟输入模式?所以当然只能是数字输入,没有PnMDIN寄存器。


To configure a Port pin for digital input, write ‘0’ to the corresponding bit in register PnMDOUT, and write ‘1’ to the corresponding Port latch (register Pn).

对于没有和ADC/比较器等模拟模块共用的脚,只是纯粹的数字脚,当输入时,只要按上面说的配置就好了。

出0入0汤圆

 楼主| 发表于 2016-4-26 16:53:36 | 显示全部楼层
sme 发表于 2016-4-20 10:06
看手册不认真。

PnMDIN是设置输入模式,模拟模式还是数字模式,对于纯数字口,哪里来的模拟输入模式?所 ...

你好,我按照手册上设置P4口为输入模式,P4MOUT = 0X00;P4 = 0xFF;没有设置成功,我的设置方式有问题吗

出0入0汤圆

发表于 2016-4-27 09:22:28 | 显示全部楼层
设置不成功是什么意思?

出0入0汤圆

发表于 2016-4-28 16:47:11 | 显示全部楼层
我给你发个中文的图,我也跟楼上一样不明白楼主说的  设置不成功  是什么意思?

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2016-5-3 15:41:50 | 显示全部楼层
mvpgpz 发表于 2016-4-28 16:47
我给你发个中文的图,我也跟楼上一样不明白楼主说的  设置不成功  是什么意思? ...

按照资料中设置P5口全部为输入口,代码如下:
P5MDOUT  =  0X00;
P5  = 0XFF;
然后再将P5口的所有IO外加上拉电阻,这样就可以将P5口设置成输入模式了?
我尝试了,但是P5不能读出高低电瓶,这就是我说的没有设置成功

出0入0汤圆

发表于 2016-5-3 16:13:45 | 显示全部楼层
怎么读的?,输入模式只是有数字输入和模拟输入两种类型,P4~P7没有模拟功能,所以就没有输入模式寄存器

出0入0汤圆

发表于 2016-5-3 16:32:47 | 显示全部楼层
陶新成 发表于 2016-5-3 15:41
按照资料中设置P5口全部为输入口,代码如下:
P5MDOUT  =  0X00;
P5  = 0XFF;

读取的时候的SFR页配置了没有?
你看的是在线调试数据么?
你先看看我说的这两个问题
我一会儿下班给你写一个简单的测试程序,顺便上一下简单测试的原理图

出0入0汤圆

 楼主| 发表于 2016-5-4 11:16:19 | 显示全部楼层
modbus 发表于 2016-5-3 16:13
怎么读的?,输入模式只是有数字输入和模拟输入两种类型,P4~P7没有模拟功能,所以就没有输入模式寄存器 ...


XBR0      = 0x04;
XBR2      = 0x40;             
P4MDOUT   = 0X00;
P4 = 0XFF;
P5MDOUT   = 0X00;
P5 = 0XFF;
这是配置


IO_DAT = P4;
if(IO_DAT != ZERO)
send_byte_usart0(0x01);
这是读
还有那些地方没有设置?

出0入0汤圆

发表于 2016-5-4 16:20:08 | 显示全部楼层
陶新成 发表于 2016-5-4 11:16
XBR0      = 0x04;
XBR2      = 0x40;             
P4MDOUT   = 0X00;

你的程序没看到SFR页的配置。
另外你直接读取P4口的状态后的if(IO_DAT != ZERO)这里的意思是什么?
IO_DAT是unsigned char 类型?
ZERO是0?
你的意思是P4口所有脚状态都是0的时候,send_byte_usart0(0x01)  ?
I/O口的状态不只跟配置有关系跟你的电路也有关系(我后面贴的图上给你简单写了一下),感觉你对P4口整体的判断这种方式需要注意的地方比较多
给你发个简单测试程序吧

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2016-5-20 16:44:13 | 显示全部楼层
#include <c8051F040.h>          
#define UCHAR unsigned char
#define UINT unsigned int  
#define SYSCLK       24500000
#define BAUDRATE     9600         

UCHAR usart0_txd_buf[8] = {0x0e,0xaa,0x00,0x00,0x00,0x00,0x00,0xb8};
UCHAR usart0_rxd_buf[8];
UCHAR usart0_txd[8];
UCHAR flag_usart0_rx;         
UCHAR send_conts;  
UCHAR Power_Chenl[6];
UCHAR Data_Chenl[6];
UINT   FOC_CONTS;
UCHAR  FOC_FLAG;
static UCHAR rx_conts;
static UINT  FOC_OUT;
static UCHAR sen_flg;

void PORT_INIT(void);
void OS_INIT(void);
void USART_INIT(void);
void TIME_INIT(void);
void send_byte_usart0(UCHAR usart0_dat);
void timer0_init(void);
void port_init();
void os_init();
void uart_init();
void time_init();

   
void send_byte_usart0(UCHAR usart0_dat)
{
   SFRPAGE = UART0_PAGE;
   SBUF0= usart0_dat;
   while(TI0 == 0);
   TI0 = 0;
}
void main()
{
   WDTCN = 0xDE;          //关闭看门狗 地址是OxFF
   WDTCN = 0xAD;          //防止意外产生的禁止操作
   port_init();           //端口初始化  
   os_init();             //晶振初始化
   uart_init();
   time_init();
   SFRPAGE   = CONFIG_PAGE;    //0x0F
   IE |= 0x90;            //开中断,开总中断,开串行中断                    
   while(1)
   {
      if(flag_usart0_rx == 0)
          {
             send_byte_usart0(P4);
                 send_byte_usart0(P5);
                 send_byte_usart0(P6&0X07);
          }       
   }
}

void uart0_ISR() interrupt 4
{              
    if(((rx_conts != 0) || (SBUF0 != 0))&&(flag_usart0_rx == 0))
        {
       usart0_rxd_buf[rx_conts] = SBUF0;
           rx_conts ++;
           if(rx_conts >= 8)
           {                                             
             rx_conts = 0;
             if(usart0_rxd_buf[7] == ((usart0_rxd_buf[0] + usart0_rxd_buf[1] + usart0_rxd_buf[2])&0x00ff))
                 {
                     flag_usart0_rx = 1;
                     send_byte_usart0(P4);
                         send_byte_usart0(P5);
                         send_byte_usart0(P6&0X07);
                     flag_usart0_rx = 0;
                 }                     
           }
        }       
    SFRPAGE=0x00;     
    if(SCON0&0x01)
      SCON0&=0xfe;     
    if(SCON0&0x02)      
      SCON0&=0xfd;
}


void port_init()
{          
        SFRPAGE = CONFIG_PAGE;
        P0MDOUT        = 0xfc;               
        P0                = 0xff;
        P1MDIN        = 0xff;
    P1MDOUT        = 0x00;
        P1                = 0xff;
        P2MDIN        = 0xff;
        P2MDOUT        = 0x00;
        P2                = 0xff;
        P3MDIN        |= 0x08;
        P3MDOUT        = 0xFF;
        P3                = 0xff;
        P4MDOUT        = 0x00;
        P4                = 0xff;
        P5MDOUT        = 0x00;
        P5                = 0xff;
        P6MDOUT        = 0x00;
        P6                = 0xff;
    P7MDOUT        = 0x00;
        P7                = 0xff;
       
        XBR0        = 0x04;
        XBR1        = 0x00;
        XBR3        = 0x00;
    XBR2        = 0x40;                                                                                        //使能交叉开关
}

void os_init()
{
   SFRPAGE   = CONFIG_PAGE;   //me Ox84=0x0F代表读或修改的时候所使用的SFR页     
        OSCXCN    = 0x00;
        CLKSEL    = 0x00;           
        OSCICN    = 0x83;
}
       
void uart_init()
{
    SFRPAGE   = UART0_PAGE;                      //0x01,
    SCON0     = 0x50;    //允许uart1,同51 SCON用法,8位UART,开始接收
}

void time_init()
{
   SFRPAGE   = TIMER01_PAGE;         //0x00
   TCON      = 0X40;                 //启动TIMER1
   TMOD      = 0x20;                 //TIMER1 MODE2
   CKCON     |= 0X10;                //时钟控制寄存器0x8E,[NET]//ckcon^01=0x01,sysclk*1/4;  ckcon^01=0x00,sysclk*1/12;
   PCON      |= 0x80;
   TH1    = -(SYSCLK/BAUDRATE/16); // ckcon^01=0x02,sysclk*1/48; //ckcon^01=0x03,extra clk *1/8;ckcon=0x08,sysclk,(这个未证实);
   TL1    = -(SYSCLK/BAUDRATE/16); //图,SMOD0=0,方式1波特率为:1/32*T1CLK/(256-TH1)                    
   TR1=1;                          //TCON^6 timer1开关  
   TI1 = 1;
}         

出0入0汤圆

 楼主| 发表于 2016-5-20 16:48:31 | 显示全部楼层
mvpgpz 发表于 2016-5-4 16:20
你的程序没看到SFR页的配置。
另外你直接读取P4口的状态后的if(IO_DAT != ZERO)这里的意思是什么?
IO_DA ...

这是我写的C8051F040P4~P7IO口配置成输入程序,但是不成功啊,你帮忙看一下是我初始化错了还是读的方式不对



#include <c8051F040.h>           
#define UCHAR unsigned char
#define UINT unsigned int  
#define SYSCLK       24500000
#define BAUDRATE     9600         

UCHAR usart0_txd_buf[8] = {0x0e,0xaa,0x00,0x00,0x00,0x00,0x00,0xb8};
UCHAR usart0_rxd_buf[8];
UCHAR usart0_txd[8];
UCHAR flag_usart0_rx;         
UCHAR send_conts;  
UCHAR Power_Chenl[6];
UCHAR Data_Chenl[6];
UINT   FOC_CONTS;
UCHAR  FOC_FLAG;
static UCHAR rx_conts;
static UINT  FOC_OUT;
static UCHAR sen_flg;

void PORT_INIT(void);
void OS_INIT(void);
void USART_INIT(void);
void TIME_INIT(void);
void send_byte_usart0(UCHAR usart0_dat);
void timer0_init(void);
void port_init();
void os_init();
void uart_init();
void time_init();

   
void send_byte_usart0(UCHAR usart0_dat)
{
   SFRPAGE = UART0_PAGE;
   SBUF0= usart0_dat;
   while(TI0 == 0);
   TI0 = 0;
}
void main()
{
   WDTCN = 0xDE;          //关闭看门狗 地址是OxFF
   WDTCN = 0xAD;          //防止意外产生的禁止操作
   port_init();           //端口初始化  
   os_init();             //晶振初始化
   uart_init();
   time_init();
   SFRPAGE   = CONFIG_PAGE;    //0x0F
   IE |= 0x90;            //开中断,开总中断,开串行中断                    
   while(1)
   {
      if(flag_usart0_rx == 0)
          {
             send_byte_usart0(P4);
                 send_byte_usart0(P5);
                 send_byte_usart0(P6&0X07);
          }        
   }
}

void uart0_ISR() interrupt 4
{              
    if(((rx_conts != 0) || (SBUF0 != 0))&&(flag_usart0_rx == 0))
        {
       usart0_rxd_buf[rx_conts] = SBUF0;
           rx_conts ++;
           if(rx_conts >= 8)
           {                                             
             rx_conts = 0;
             if(usart0_rxd_buf[7] == ((usart0_rxd_buf[0] + usart0_rxd_buf[1] + usart0_rxd_buf[2])&0x00ff))
                 {
                     flag_usart0_rx = 1;
                     send_byte_usart0(P4);
                         send_byte_usart0(P5);
                         send_byte_usart0(P6&0X07);
                     flag_usart0_rx = 0;
                 }                     
           }
        }        
    SFRPAGE=0x00;     
    if(SCON0&0x01)
      SCON0&=0xfe;     
    if(SCON0&0x02)      
      SCON0&=0xfd;
}


void port_init()
{           
        SFRPAGE = CONFIG_PAGE;
        P0MDOUT        = 0xfc;               
        P0                = 0xff;
        P1MDIN        = 0xff;
    P1MDOUT        = 0x00;
        P1                = 0xff;
        P2MDIN        = 0xff;
        P2MDOUT        = 0x00;
        P2                = 0xff;
        P3MDIN        |= 0x08;
        P3MDOUT        = 0xFF;
        P3                = 0xff;
        P4MDOUT        = 0x00;
        P4                = 0xff;
        P5MDOUT        = 0x00;
        P5                = 0xff;
        P6MDOUT        = 0x00;
        P6                = 0xff;
    P7MDOUT        = 0x00;
        P7                = 0xff;
        
        XBR0        = 0x04;
        XBR1        = 0x00;
        XBR3        = 0x00;
    XBR2        = 0x40;                                                                                        //使能交叉开关
}

void os_init()
{
   SFRPAGE   = CONFIG_PAGE;   //me Ox84=0x0F代表读或修改的时候所使用的SFR页     
        OSCXCN    = 0x00;
        CLKSEL    = 0x00;           
        OSCICN    = 0x83;
}
        
void uart_init()
{
    SFRPAGE   = UART0_PAGE;                      //0x01,
    SCON0     = 0x50;    //允许uart1,同51 SCON用法,8位UART,开始接收
}

void time_init()
{
   SFRPAGE   = TIMER01_PAGE;         //0x00
   TCON      = 0X40;                 //启动TIMER1
   TMOD      = 0x20;                 //TIMER1 MODE2
   CKCON     |= 0X10;                //时钟控制寄存器0x8E,[NET]//ckcon^01=0x01,sysclk*1/4;  ckcon^01=0x00,sysclk*1/12;
   PCON      |= 0x80;
   TH1    = -(SYSCLK/BAUDRATE/16); // ckcon^01=0x02,sysclk*1/48; //ckcon^01=0x03,extra clk *1/8;ckcon=0x08,sysclk,(这个未证实);
   TL1    = -(SYSCLK/BAUDRATE/16); //图,SMOD0=0,方式1波特率为:1/32*T1CLK/(256-TH1)                    
   TR1=1;                          //TCON^6 timer1开关  
   TI1 = 1;
}   

出0入0汤圆

发表于 2016-5-25 11:53:08 | 显示全部楼层
陶新成 发表于 2016-5-20 16:48
这是我写的C8051F040P4~P7IO口配置成输入程序,但是不成功啊,你帮忙看一下是我初始化错了还是读的方式不 ...

简单看了下你的程序
send_byte_usart0(P4);
send_byte_usart0(P5);
send_byte_usart0(P6&0X07);
P4不能直接使用,应该是
unsigned char a;
a = P4;
send_byte_usart0(a);
P6&0X07这里也是错的,不可以直接运算。
关于端口状态的问题,你可以直接看IDE中端口寄存器的状态栏。
我估计你的程序  端口是有变化的,只不过是你发送的不对。(这里也可以看UART寄存器的状态栏)
善用IDE和JTAG,会让你程序调试起来比较简单。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-9 23:37

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表