一、什么是UART
UART一般用于板间通信,即单片机和外围设备之间的通信。如图所示,两个单片机相互通信。
二、什么是串口
串口就是COM口,串口是发送数据的媒介,通过媒介一个个地发送数据位,常见的是9针串口。但在我们使用C51和开发版上都有集成CH340转换芯片,用usb口就可以代替串口,只要插上usb线就可以进行串口测试。
三、SBUF
SBUF是一个寄存器,作为一个缓冲区。
注意:发送和接收,存储的数据,都在同一个地址(同一个地方)
比如:一栋房子里面有两间房间,但是门牌号是一样的(即:第一间叫SBUF,第二间也叫SBUF).
通熟的讲,就是一个专门存储数据一个空间,发送的数据,放在第一间SBUF里,当发送端结束后。想要接收端接收到,只需要让第一间SBUF里的数据赋值给第二间SBUF里,接收端就会把第二间SBUF里的数据读出来。(注意:SBUF不可更改名,它是单片机里面内部已经定义好的)
四、工作方式的选择与SCON的设置(常用的是方式1)
你有没有发现跟之前讲解选择 定时器0 还是 定时器1 流程很像,不同的是 串行通信 只有一种。
选择了方式1,就需要把SMO=0 ,SM1=1;
REN:允许接收控制位,软件置位或者清零。(如果不打开它,如何让对方收到信息)
因此,REN=1;
TI: 发送中断标志,发送一帧结束,TI=1,必须软件清零。
解析; 可以通过此判断,判断是否发送完成。初始化设为TI=0;
RI: 接收中断标志,接收一帧结束,RI=1,必须软件清零。
解析; 可以通过此判断,判断是否接收完成 。初始化设为R1=0;
赋值如下 SCON = 0X50;
五、PCON,波特率加倍寄存器 87H
5.1、PCON示意图
常见使用,都是选择0. 即串行口波特率不变,系统复位时默认为SMOD=0.
5.2、什么是波特率(重点)
波特率(baud):是每秒传输二进制数码的位数。
常见的波特率:2400bit/s 、 9600bit/s 、 115200 bit/s 等等
注意:在串口通信中,收发双方对发送或接收数据的速率有约定,即双方要有相同的波特率。
你有没有发现,在选择工作方式的时候,有出现过波特率。这三个字。(看图如下)
SYSclk:晶振频率
SMOD:看5.1小节,默认情况SMOD=0;
除此之外,我们是不是还发现了定时器1,接下来复习一下定时器1相关内容。
如何选择定时器0,还是定时器1。看赋值给紫色,还是黄色。
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
GATE | C/T | M1 | M0 | GATE | C/T | M1 | M0 |
赋值给黄色,选择的是定时器1,赋值给紫色选择的是定时器0.(由于图中规定是定时器1)
赋什么值,看选择哪个工作模式。(串口通信,一般都选择工作模式2,即让M1=1,MO=0)
M1 | M0 | 工作模式 | 说明 |
0 | 0 | 0 | 13位计时计数器 (8192) |
0 | 1 | 1 | 16位计时计数器 (65536) (本次讲解使用此模式) |
1 | 0 | 2 | 8位计时计数器,可自动重新载入计数值 (256) |
1 | 1 | 3 | 当成两组独立的8位计时器(256,T0和T1不能同时用) |
问题1:为什么不选择定时器1的工作方式1:
答:如果我们使用定时器1的工作方式1在中断中装初值的方法来T1溢出率的话,在进入中断、需要手动重装赋值、出中断这个过程中很容易产生时间上的微小的误差,当多次操作时微小的误差不断累积,终会产生错误;
问题2:为什么选择定时器1的工作方式2:
答:因为方式2为自动重装初值的8位定时器/计数器模式(自动重装载就是在定时器溢出后自动装入设定的初值),这样的好处当然是显而易见的,不需要在中断服务器里手动赋值了,所以可以精确的定时,用它来做波特率发生器最恰当。
5.3、8位计时计数器,可自动重新载入计数值 (256)
5.4、如何计算得出定时1初始值(重点)
废话不多说(此公式只适用于串行通信的方式1,即上图红色字体)
SYSclk:晶振频率
SMOD:看5.1小节,默认情况SMOD=0;
你学会了??
6、非中断法串口通信(代码如下)
#include "reg52.h"
void UartInit(void)
{
PCON &= 0x7F;
SCON = 0x50;
TMOD &= 0xCF;
TMOD |= 0x20;
TL1 = 0xFD;
TH1 = 0xFD;
ET1 = 0;
TR1 = 1;
}
void Delay2000ms()
{
unsigned char i, j, k;
i = 15;
j = 2;
k = 235;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void main()
{
UartInit();
char mesg='a';
while(1)
{
SBUF = mesg;
Delay2000ms();
}
}
运行结果
每2秒发送一个字符a。
7、中断法串口通信(代码如下)
#include "reg52.h"
sbit led = P3^7;
char num;
void UartInit(void)
{
PCON &= 0x7F;
SCON = 0x50;
TMOD &= 0xCF;
TMOD |= 0x20;
TL1 = 0xFD;
TH1 = 0xFD;
ET1 = 0;
TR1 = 1;
EA=1;
ES=1;
}
void main()
{
UartInit();
while(1)
{
}
}
void Uart_Handler() interrupt 4
{
if(RI==1)
{
RI=0;
num = SBUF;
if(num == 'k') //开灯
{
led =0;
}
if(num == 'g') //关灯
{
led =1;
}
}
}
代码运行正确。