关于单片机串口通信的几个问题

来源:互联网 发布:java object类 编辑:程序博客网 时间:2024/04/19 17:13

串口通信:(从单片机的角度考虑)


过程:(无论中断开关与否,数据都能进出SBUF,且RI和TI都能硬件置1,只是CPU未进行接收)

接收:PC发一个字节-->RI硬件置1-->进入中断,接收数据(RI手动置0)-->返回现场

发送:单片机发一个字节-->发送完成,TI硬件置1 ---开启中断,进入中断-->返回现场-->发送完成

          ---未开启中断,检测TI,后软件置0-->发送完成

——————————————————————————————————————————————————

1.接收(只能用中断来接收PC来的信息,如果一直扫描的话,浪费CUP就很厉害,接收到的数据也未必完整)

2.发送

--查询法(发送前关闭ES,发送完开启ES)

--中断法 (开启中断发送)

备注:

中断发送优点:省去循环等待时间,以上面例子为例,9600bps时查询发送约占用单片机10ms多,而中断发送只占单片机几十微秒(单片机速度 越快,占用时间越少)。  
中断发送缺点:代码稍复杂,发送过程不易控制。


查询法代码:

中断法:(中断法,必须有中断函数)

           1.在主函数中完成发送

    2.在中断函数中完成发送

//主函数

void main(){

while (1)                       
    {
    SendStr("U");
    }

}
//中断函数

void UARTInterrupt(void) interrupt 4
{
    if(RI)
    {
        RI = 0;
        //add your code here!
    }
   if(TI){

}

}

void SendByte(unsigned char dat)
{
 SBUF = dat;
 while(!TI);
    TI = 0;

}

重点分析:

错误1:

void SendByte(unsigned char dat)
{
 SBUF = dat;
 while(!TI);
    TI = 0;

}

当发送完毕后,TI会硬件置1,这样就会进入中断程序中,而此时在TI中一定不能写TI=0,否则while(!TI)这里就会进入死循环

错误2:

void SendByte(unsigned char dat)
{
 SBUF = dat;
  //while(!TI);
   //TI = 0;

}

void SendStr(unsigned char *s)
{
 while(*s!='\0')// \0 表示字符串结束标志,
                //通过检测是否字符串末尾
  {
  SendByte(*s);
  s++;
  }
}

如果这样写,并在中断中写TI=0,看上去两个是一样的,但是,如果你在写发送字符串的函数中调用了SendBYte,那么SendStr也只能发送字符串的第一个字符

(原因:在你发送第一个字符的时候,串口就会将第一个字符锁存,但是这时你又向其中发送第2,3个字符,而SBUF只能保存缓存1个字节,所以在第一个发送完之前,第2,3个字符都不会保存



查询法:

void SendByte(unsigned char dat)
{

   ES=0;
SBUF = dat;
  while(!TI);
TI=0;
ES=1;

}

直接在主程序中调用,不经过中断就会发送。

备注:本人小白,错误之处还请大神指明,O(∩_∩)O谢谢

0 0