• 已解决 73482 个问题
  • 已帮助 5993 位优秀工程师

51单片机能接收不能发送

kissmey 2016-03-14 浏览量:1678

采用c8051f040进行串口通讯,通过max3072,现在的问题是能够接收,但发送就死在while(TI0==0)这句了。

麻烦大家帮忙找下原因。

应该是个简单的程序,怎么就总是死在while了?

#include "c8051F040.h"

#define uchar unsigned char
#define uint unsigned int
void port_init();
void os_init();
void uart_init();
void time_init();
uchar g;

uchar flag = 0;//接收数据标志
sbit RD0  = P7^7;//使能 

void main()
{
        
 WDTCN = 0xDE;     // 关闭看门狗 地址是OxFF
 WDTCN = 0xAD;     //防止意外产生的禁止操作
 os_init();         //系统时钟初始化
 port_init();       //端口初始化
 time_init();
 uart_init();


 SFRPAGE   = CONFIG_PAGE; //0x0F
 EA  = 1;  //开总中断,开串行中断
 ES0 = 1;


 while(1)
 {
    if(flag==1)
{
        RD0 = 1;
        TI0= 0;

SBUF0=g;
       while(TI0==0);
    TI0= 0;

    flag=-0;
}
 
 }

}

void port_init()
{
    SFRPAGE   = CONFIG_PAGE;
 
    XBR0      = 0x04;
    XBR1      = 0x00;
    XBR2      = 0x44;

    P0MDOUT   = 0x01;//TX0-high,TX0-p0.0

    P7MDOUT   = 0xFF;
    RD0 = 0;
}

void os_init()
{
    unsigned short i = 0;
    SFRPAGE   = CONFIG_PAGE;   //me Ox84=0x0F代表读或修改的时候所使用的SFR页
    OSCXCN    = 0x77;   //即01110111,0:晶体振荡器未稳定;111:晶体振荡器二分频方式
                                  //0:读;111:10Mhz~30Mh, 外部22.1184M晶振,系统时钟不分频
    for (i = 0; i < 3000; i++);                         //等待外部晶振稳定,等待至少1ms
    while ((OSCXCN & 0x80) == 0);             //第7位代表内部振荡器使能
    CLKSEL    = 0x01;           //源自外部震荡器

void time_init()
{
    SFRPAGE   = TIMER01_PAGE;//0x00
 
    TMOD      = 0x20;   //TIMER1 MODE2
    CKCON     = 0X01;      //时钟控制寄存器0x8E,[NET]//ckcon^01=0x01,sysclk*1/4;  ckcon^01=0x00,sysclk*1/12;
                                      // ckcon^01=0x02,sysclk*1/48; //ckcon^01=0x03,extra clk *1/8;ckcon=0x08,sysclk,(这个未证实);
    TH1       = 0xEE;          //见[c8051f040 datasheet]p259 T0方式2原理
                                   //图,SMOD0=1,方式1波特率为:1/16*T1CLK/(256-TH1)                  
    TR1       = 1;              //启动TIMER1         
 }   

void uart_init()
{
    SFRPAGE   = UART0_PAGE;              //0x01,
    SSTA0     = 0x10; //Timer1溢出产生uart0波特率,SMOD=1
    SCON0     = 0x50; //允许uart0,8位UART
}

void UART0_Interrupt (void) interrupt 4 //串口0接收
{
if (RI0==1){
          RI0 = 0;                          // Clear interrupt flag
          g = SBUF0;                    // Read a character from UART
          flag = 1;
   }
 }

0 0 收起

我来回答

上传资料:
选择文件 文件大小不超过15M(格式支持:doc、ppt、xls、pdf、zip、rar、txt)
最佳答案
  • 我还是建议你,在收到数据后,先把使能端拉高,然后等几毫秒,然后再开始发送数据,试试……

    我之前调试485的时候就遇到类似的问题,一收到数据然后马上发送就会发送不了,但是接受到数据之后,立马将使能端拉高,然后我用定时器延时6毫秒,再发送数据,就能正常发送……




    你可以试试看……


    还有一个问题,你在写

    WDTCN = 0xDE;     // 关闭看门狗 地址是OxFF

    WDTCN = 0xAD;     //防止意外产生的禁止操作

    这两句这前,建议你加几百毫秒的延时,也就是说,上电延时几百毫秒等待电源稳定再开始写这两句,试试……



    经楼主确认,原来是:无法发送的原因是没有加SFRPAGE   = UART0_PAGE;  寄存器分页

    索德斯呢…………

    • 发布于 2016-03-14
    • 举报
    • 评论 0
    • 0
    • 0

其他答案 数量:14
  • 首先我想知道,你是怎么确定你能收到数据的?比如,你收到数据的时候flag会置1,那么你当flag=1的时候,你输出一个LED让他亮灯,这样就可以判断你是不是收到数据了,下一步再来验证是不是能发送出去;同样的道理,验证发送出去可以用另外一个指示灯,发送完成便让另一个指示灯亮,就可以证明,是不是你所说的,卡在发送while(TI0==0)这里了。


    还发现个问题,你这个max3072是跟485一样半双工通信的是吧?你在接收到数据后,小延时一段时间再发送试试,我之前也是在用485通信,应该跟你这个差不多……

    • 发布于2016-03-14
    • 举报
    • 评论 0
    • 0
    • 0

  • 在线调试啊,能够进入接收中断的断点,flag能置1,一步步往下走,在while就走不下去了
    • 发布于2016-03-14
    • 举报
    • 评论 0
    • 0
    • 0

  • 你这个还带在线仿真功能的啊,那应该很好查问题吧?像我说的这些都不用了……我看下这款芯片的资料先……
    • 发布于2016-03-14
    • 举报
    • 评论 0
    • 0
    • 0

  • 不客气,要是你的问题解决了,记得来吼一声,好让我们知道是不是这个问题,呵呵……
    • 发布于2016-03-14
    • 举报
    • 评论 0
    • 0
    • 0

  • 选将TX、RX短接后,测试接收发送,若是这都有问题,485那里更是不用看了。从你的描述看,程序卡在TI0那里,应该是串口这一块都是有问题的。示波器看单片机TX口有没有波形。

    先测试如下程序,上位机通过串口发送数据给单片机,单片机接收后并回发给上位机,以确定是不是硬件的问题。

    #include
    unsigned int flag,a;
    void main()
    {
    
    	TMOD=0x20; 	               
    	TH1=0xfd; 
    	TL1=0xfd; 			     
    	SM0=0; 
    	SM1=1; 			     
    	TR1=1; 					 
    	REN=1; 					
    	EA=1; 					 
    	ES=1; 					   
    	 while(1)
    	 {
    		if(flag==1)
    		{
    			 ES=0;
    			 flag=0;
    			 SBUF=a;
    			 while(!TI);
    			 TI=0;
    			 ES=1;
    		 }
    	 }
    }
    void srei()interrupt 4 
    {	 
    	 RI=0;
    	 P0=SBUF;          
    	 a=SBUF;
    	 flag=1; 
    		
    }
    

    另,不知道你的485的使能是不是自动换向的。做成自动换向的就简单多了。

    • 发布于2016-03-14
    • 举报
    • 评论 0
    • 0
    • 0

  • 呵呵,都485了还TX、RX短接。你这种测试方法是用在RS232上面的。
    • 发布于2016-03-15
    • 举报
    • 评论 0
    • 0
    • 0

  • 不知道楼主问题是否解决了呢?是否能结贴了?
    • 发布于2016-03-15
    • 举报
    • 评论 0
    • 0
    • 0

  • 对于上面这个单独的串口程序,无法发送的原因是没有加SFRPAGE   = UART0_PAGE;  寄存器分页。
    • 发布于2016-03-15
    • 举报
    • 评论 0
    • 0
    • 0

  • 强制让串口输入输出为高低电平,用示波器测一下
    • 发布于2016-03-16
    • 举报
    • 评论 0
    • 0
    • 0

相关问题

问题达人换一批

51单片机能接收不能发送