波特率就是发送二进制数据位的速率, 习惯上用 baud 表示, 即我们发送一位二进制数据的持续时间=1/baud。 在通信之前, 单片机 1 和单片机 2 首先都要明确的约定好它们之间的通信波特率, 必须保持一致, 收发双方才能正常实现通信, 这一点大家一定要记清楚。约定好速度后, 我们还要考虑第二个问题, 数据什么时候是起始, 什么时候是结束呢?不管是提前接收还是延迟接收, 数据都会接收错误。 在 UART 通信的时候, 一个字节是 8 位,规定当没有通信信号发生时, 通信线路保持高电平, 当要发送数据之前, 先发一位 0 表示起始位, 然后发送 8 位数据位, 数据位是先低后高的顺序, 数据位发完后再发一位 1 表示停止位。 这样本来要发送一个字节的 8 位数据, 而实际上我们一共发送了 10 位, 多出来的两位其中一位起始位, 一位停止位。 而接收方呢, 原本一直保持的高电平, 一旦检测到了一位低电平, 那就知道了要开始准备接收数据了, 接收到 8 位数据位后, 然后检测到停止位, 再准备下一个数据的接收。
#include<reg52.h>
sbit PIN_RXD = P3^0;
sbit PIN_TXD = P3^1;bit RxdEnd = 0;
bit RxdOrTxd = 0;bit TxdEnd = 0;unsigned char RxdBuf = 0;unsigned char TxdBuf = 0;void ConfigUART(unsigned int baud);
void StartRXD();void StartTXD(unsigned char dat);void main()
{ EA = 1; ConfigUART(9600); while(1) { while(PIN_RXD); StartRXD(); while(!RxdEnd); StartTXD(RxdBuf+1); while(!TxdEnd); }}void ConfigUART(unsigned int baud)
{ TMOD &= 0xF0; TMOD |= 0x02; TH0 = 256 - (11059200/12)/baud;}void StartRXD()
{ TL0 = 256 - ((256 - TH0)>>1); ET0 = 1; TR0 = 1; RxdEnd = 0; RxdOrTxd = 0;}void StartTXD(unsigned char dat)
{ TxdBuf = dat; TL0 = TH0; ET0 = 1; TR0 = 1; PIN_TXD = 0; TxdEnd = 0; RxdOrTxd = 1;}void InterruptTimer0() interrupt 1
{ static unsigned char cnt = 0;if(RxdOrTxd)
{ cnt++; if(cnt <= 8) { PIN_TXD = TxdBuf & 0x01; TxdBuf >>= 1; } else if(cnt == 9) { PIN_TXD = 1; } else { cnt = 0; TR0 = 0; TxdEnd = 1; } } else { if(cnt == 0) { if(!PIN_RXD) { RxdBuf = 0; cnt++; } else { TR0 = 0; } } else if(cnt <= 8) { RxdBuf >>= 1; if(PIN_RXD) { RxdBuf |= 0x80; } cnt++; } else { cnt = 0; TR0 = 0; if(PIN_RXD) { RxdEnd = 1; } } }}