打印

单片机的串口通信

[复制链接]
1471|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zch305|  楼主 | 2019-7-21 10:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 zch305 于 2019-7-21 11:40 编辑

void UartInit(void)                //9600bps@11.0592MHz
{
        SCON = 0x50;                //8位数据,可变波特率
        AUXR |= 0x01;                //串口1选择定时器2为波特率发生器
        AUXR |= 0x04;                //定时器2时钟为Fosc,即1T
        T2L = 0xE8;                //设定定时初值
        T2H = 0xFF;                //设定定时初值
        AUXR |= 0x10;                //启动定时器2

        REN = 1;        //允许接收
        ES  = 1;        //允许中断

        EA = 1;                //允许全局中断                 
        
}
void weizhi()
{
         int send_num=0;
        B_TX1_Busy = 0;
        RX1_Cnt = 0;
        TX1_Cnt = 0;


        S1_8bit();                                //8位数据
        S1_USE_P30P31();                //UART1 使用P30 P31口        默认
        //UartInit();        
          while (1)
          {
         
        if((TX1_Cnt!=RX1_Cnt)&&(!B_TX1_Busy))        //收到数据,发送空闲
                {
                                
                           
                                SBUF = RX1_Buffer[TX1_Cnt];        //把收到的数据远样返回
                                       
                                
                     B_TX1_Busy = 1;                //标志发送忙
                        
                                 send_num=send_num+1;
                        
                     if(++TX1_Cnt >= RX1_Lenth)        TX1_Cnt = 0;        //避免溢出处理
                                
                 }
                        /*        if(send_num==4)                 {break;}  */
      }         
           
}
void UART1(void) interrupt 4  // 串行口1中断函数
{

        if(RI)
        {
                RI = 0;
                RX1_Buffer[RX1_Cnt] = SBUF;        

                if(++RX1_Cnt >= RX1_Lenth)        RX1_Cnt = 0;        //避免溢出处理
        }  

        if(TI)
        {
                TI = 0;
                B_TX1_Busy = 0;                //清除发送忙标志
        }
}
void main()
{
UartInit();
weizhi();
(1);
weizhi();

}
我想用串口1将接收的数据发送出去,但是程序在while循环里出不来,执行不了(1),大家有什么办法可以跳出while循环或者是不用while循环也可实现,并且第二次也可以将发送给串口的数据发送出去


使用特权

评论回复

相关帖子

沙发
tianxj01| | 2019-7-21 11:12 | 只看该作者
void main()
{
weizhi();
(1);
weizhi();

}
????????这是个什么鬼??????????

使用特权

评论回复
板凳
zch305|  楼主 | 2019-7-21 11:16 | 只看该作者
tianxj01 发表于 2019-7-21 11:12
void main()
{
weizhi();

weizhi()函数就是将接收到的数据发送出去,然后在主函数使用这个函数将接收到数据发送出去,然后(1)是我接下来要执行的程序

使用特权

评论回复
地板
tianxj01| | 2019-7-21 11:30 | 只看该作者
zch305 发表于 2019-7-21 11:16
weizhi()函数就是将接收到的数据发送出去,然后在主函数使用这个函数将接收到数据发送出去,然后(1)是 ...

程序还没编好呢这个,语法都不对。
我算是看明白了,你在weizhi()函数里面设置了一个while(1),那当然是直接死循环了哈。
你这里设置死循环的本意是什么呢?这个子函数,初步看看目的是收到数据,然后直接反弹,这也是我们做串口测试经常做的动作,不过你编的糊里糊涂的,不好看明白。
如果需要从死循环里面跳出来也不是不可以,你必须设置一个if条件检测,符合某条件则打断while循环即可。
一般你这样成组处理的,我们可以设置一个超时或者字长或者干脆就是缓冲区满作为条件来打断该循环。

使用特权

评论回复
5
tianxj01| | 2019-7-21 11:34 | 只看该作者
zch305 发表于 2019-7-21 11:16
weizhi()函数就是将接收到的数据发送出去,然后在主函数使用这个函数将接收到数据发送出去,然后(1)是 ...

顺便说一下,用拼音来做函数名可不是一个好习惯,基本功能模块,命名最好是英语或者英语缩写,这样哪怕日子久了或者别人一看,至少能大致上读懂,增加程序的可读性和可移植性。才
才开始学习写程序,一些基本规则最好能够从现在开始就老老实实的遵守起来。

使用特权

评论回复
6
zch305|  楼主 | 2019-7-21 11:39 | 只看该作者
tianxj01 发表于 2019-7-21 11:30
程序还没编好呢这个,语法都不对。
我算是看明白了,你在weizhi()函数里面设置了一个while(1),那当 ...

我试过用用字长方法解决,如下,if(send_num==4), {break;},可以跳出while循环,但是第二次给单片机发送4个字节的数据时,它就不能将接收数据发出去了

使用特权

评论回复
7
zch305|  楼主 | 2019-7-21 11:42 | 只看该作者
tianxj01 发表于 2019-7-21 11:34
顺便说一下,用拼音来做函数名可不是一个好习惯,基本功能模块,命名最好是英语或者英语缩写,这样哪怕日 ...

以后知道了,谢谢指导

使用特权

评论回复
8
zxa198610| | 2019-7-21 21:35 | 只看该作者

使用特权

评论回复
9
ttaniscy| | 2019-9-11 11:47 | 只看该作者
同求帮助,我遇到和LZ类似的问题,单片机上电后只能正常接收一次串口通信,第二次就无法正常了。关电再上电后还是可以正常接收一次。和LZ一样程序卡在哪里了

使用特权

评论回复
10
airwill| | 2019-9-15 12:17 | 只看该作者
while 应该放在主程序 main() 里,  你这个结构一定会有问题的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

11

主题

21

帖子

0

粉丝