UART串口通信
-
串行通信
是将数据按位发送的通信机制。比如:101010100,用0-0-1-0-1-0-1-0-1来发送,每次只发一位,所以速度是比较慢的。
而UART串口通信则是串行通信的一种,下面是单片机的UART串口通信原理 -
UART通信
0)类比
UART通信可以比作小学的听写句子。首先老师会说:“准备好没有?拿出本子听写,李小明你的本子像个咸菜!”。同学听到老师说的话,就知道听写开始了。然后,老师开始把句子读给学生听。每个句子老师必须从头开始逐字念。一些同学和老师的速度一致,有些同学比老师更快,还有同学比老师慢半拍。结果就是比老师快的,有些字写了几遍,比老师慢的,没有完整写下一个句子。都造成了句子的损坏。这个速度,在UART中称为波特率。只有和老师速度完全相同,才能保证句子不会出错。句子念完了,老师要说:“听写完毕,小组长把本子收上来!”小明就知道听写结束了。
1)UART串口通信的具体流程
UART串口通信通过两个接口进行,TXD(输出端),RXD(接收端)。着重理解1个参数,2个特殊信号。RXD需要开始信号和结束信号。在没有信号需要接受时通信线路保持高电平,当需要接受时保持低电平。所以在接受信号前,先要发送有个低电平,并让通信线路电平保持为低。当8位数据传输结束之后要发送给通信线路一个高电平,表示接受结束,并让通信线路保持高电平。RXD想要正确接收一位数据是需要时间的。所以发送的每位数据都需要一段保持时间,并和RXD接受时间一致。这段时间为1/波特率。波特率表示信号传递的速度。
【注】 通信线路指的是发送端和RXD间的线路
流程总结:1.统一发送端和RXD的波特率,并将1/波特率作为各个信号的持续时间 -->2.发送低电平给RDX–>3.由低位到高位发送数据–>4. 8位之后发送高电平给RDX
2)单片机的UART串口模块和代码
单片机的TDX是P3_0,RDX是P3_1。
SCON是串行控制寄存器,用来控制单片机通信的状态,包括串行通信的方式,开始,结束等等。这次实验SCON有4个重要的引脚:
0.SM0=0,SM1=1
1.RI,低电平时表示接受开始,但是由于每次数据传输结束之后硬件都会自动将其置1,所以要开始新的接受,要用程序将其置0.
2.TI,高电平表示传输结束,硬件会在数据传输结束之后将其置1,所以要开始新的数据接受,要用程序把它置0;
有了SCON就不用自己发送特殊信号了。
而SBUF(全称:serial data buffer,中文名为串行数据缓冲器。)则是用来缓存接受到的串行数据的,SBUF会将数据按照字节的方式整理并储存。有两个寄存器都叫SBUF,但是一个只能读,一个只能写(实现数据的异步同向交流)。代码会自动判断什么时候用写,什么时候用读。比如rdxByte=SBUF为读,SBUF=rdxByte为写。再比如:SBUF=SBUF+1,左边写,右边读。
基本的接收流程是:先将RI,TI置0 --> SBUF接受8位数据并整理–>TI,RI置为1
TI,RI和SBUF的配合使用:
RI=1时表示SUBF已经有了8位数据了,所以可以把数据读出来。RI=1和SBUF接收到整个字节是等价的。
TI=1比RI=1来的慢,
代码结构是
1.配置寄存器SCON,设定通信模式为UART
—此时硬件在运行—
2.如果RI=1,将其置0,在这段可以插入读取数据的代码
3.如果TI=1,将其置0
4.2,3的循环,这样就可以实现通信了
单片机接收信号的代码:
#include <reg52.h>
void ConfigUART(unsigned int baud);
void main () {
ConfigUART(9600); // 1 配置波特率为 9600,设置通信为UART
while(1); // 循环2,3步
}
void ConfigUART(unsigned int baud) //串口配置函数,baud 为波特率
{
SCON = 0x50; //配置串口为模式 1 TMOD &= 0x0F; //清零 T1 的控制位
TMOD |= 0x20; //配置 T1 为模式 2
TH1 = 256 - (11059200/12/32) / baud; //计算 T1 重载值
TL1 = TH1; //初值等于重载值
ET1 = 0; //禁止 T1 中断
TR1 = 1; //启动
T1 ES = 1; //打开串口中断
EA = 1; //打开总中断
}
void InterruptUART() interrupt 4 //2,3步
{
if (RI) //SBUF接收到了字节
{
RI = 0; //手动清零接收中断标志位
SBUF = SBUF + 1;//接收数据+1 发回去,左边为发送 SBUF,右边为接收 SBUF。*可以改变成接受数据
}
if (TI) //字节发送完毕
{
TI = 0; //手动清零发送中断标志位
}
}
参考:2014 清华大学出版社 宋雪松《手把手教你学单片机》
网址