您的位置:首页 > 其它

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

2014-07-29 13:51 197 查看
串口通信:(从单片机的角度考虑)

过程:(无论中断开关与否,数据都能进出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谢谢
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: