moonf99

串行口通信

2023/07/24

关于串行口通信的一些理解与想法。

串口

串口是一种应用广泛的通信接口,能够实现单片机与电脑,单片机与单片机之间的相互通信。
由于51单片机内部自带UART(Universal Asynchronous Receiver Transmitter,通用异步收发器),可实现单片机的串口通信。

串口的硬件电路

这是图片
这是图片

简单双向串口通信有两根通信线(发送端TXD和接收端RXD)。
TXD与RXD要交叉连接。
当只需单向的数据传输时,可以直接一根通信线。
当电平标准不一致时,需要加电平转换芯片。
Uart的通信方式是异步,全双工。(通信双方各自约定通信速率,通信双方可以在同一时刻互相传输数据)

串口模式(模式1)

这是图片
设置好定时器T1后,当把数据从控制门写入SBUF后立马从TxD发出,通过发送控制器(若进行中断使能的话)引起中断请求;当数据从RxD输入到位移寄存器,位移寄存器把数据写入SBUF后立马从SBUF中读出,通过接收控制器(若进行中断使能的话),引起中断请求。

波特率由定时器1产生。

波特率该如何计算?
256-设定的初值=差值
1/差值 能够算出溢出率(单位是MHZ)
再将 溢出率/16(若波特率加倍则/32)*10^6 就能算出波特率了(单位是HZ)

串口和中断系统(模式1)

这是图片
由图中可以看出,串行通信模式发送时,数据由串行发送端TxD输出,并且串行口1发送中断标志(TI)置1;若软件置位接收允许位(REN)置1时,接收器便以选定波特率的16分频的速率采样串行接收端口RxD接收数据,并且串行口接收中断标志(RI)置1,(需要注意的是,无论时RI还是TI置1都会触发中断函数,需要对他们进行分开判断!),打开串行口1中断允许位(ES),再打开总中断(EA),设定中断源优先级(IP),进入中断函数。

串行口相关寄存器

这是图片

串行口控制寄存器SCON(可位寻址)

这是图片

SM0/FE:当PCON寄存器中的SMOD0/PCON.6为1时,该位用于帧错误检测。当检测到一个无效停止位时,通过UART接收器设置该位。它必须由软件清0;当PCON寄存器中的SMOD0/PCON.6位为0时,该位和SM1一起制定串行通信的工作方式,如下表所示:这是图片
SM2:允许方式2或方式3多机通信控制位。
REN:允许/禁止串行接收控制位。由软件置位REN,即REN=1为允许串行接收状态,可启动串行接收器RxD,开始接收信息。软件复位REN,即REN=0,则禁止接收。
TI:发送中断请求标志位。在除方式0的其他方式中,则在停止位开始发送时由内部硬件置位,必须由软件复位。
RI:接收中断请求标志位。在除方式0的其他方式中,串行接收到停止位的中间时刻由内部硬件置位,即RI=1,必须由软件复位,即RI=0。

注意:TI和RI均不能由硬件自动置位,必须通过软件清0,否则将出现一次请求多次响应的错误!

1
SCON=0x50;//将SM0位置0,SM1位置1,设定为方式1;REN位置1

电源控制寄存器PCON(不可位寻址)

这是图片

SMOD:波特率选择位。当用软件置位SMOD,即SMOD=1,则使串行通信方式1,2,3的波特率加倍;SMOD=0,则各工作方式的波特率加倍。复位时SMOD=0。
SMOD0:帧错误检测有效控制位。当SMOD0=1,SCON寄存器中的SM0/FE位用于FE(帧错误检测)功能;当SMOD0=0,SCON寄存器中的SM0/FE位用于SM0功能,和SM1一起指定串行口的工作方式。复位时SMOD0=0。

1
PCON |= 0x80;//将SMOD位置1

串行口数据缓冲寄存器SBUF

SBUF是串口数据缓存寄存器物理上是两个独立的寄存器,但占用相同的地址。写操作时,写入的是发送寄存器,读操作时,读出的是接收寄存器。


从机地址控制器SADEN和SADDR

用于多机通信,SADEN是从机地址掩模寄存器,SADDR是从机地址寄存器。


中断允许寄存器IE(可位寻址)

这是图片

EA:CPU的总中断允许位。
ES:串行口中断允许位,ES=1,允许串行口中断;ES=0,禁止串行口中断。


中断优先级控制寄存器高IPH(不可位寻址)/低IP(可位寻址)

这是图片
这是图片
PSH,PS:串口1中断优先级控制位。

当PSH=0且PS=0时,串口1中断为最低优先级中断(优先级0)
当PSH=0且PS=1时,串口1中断为较低优先级中断(优先级1)
当PSH=1且PS=0时,串口1中断为较高优先级中断(优先级2)
当PSH=1且PS=1时,串口1中断为最高优先级中断(优先级3)

食用例

电脑通过串口控制LED
这是图片
UART.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <REGX52.H>

/**
* @brief 串口初始化,4800bps@12.000MHz
* @param 无
* @retval 无
*/
void UART_Init()
{
SCON=0x50;
PCON |= 0x80;
TMOD &= 0x0F; //设置定时器模式
TMOD |= 0x20; //设置定时器模式
TL1 = 0xF3; //设定定时初值
TH1 = 0xF3; //设定定时器重装值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
EA=1;
ES=1;
}

/**
* @brief 串口发送一个字节数据
* @param Byte 要发送的一个字节数据
* @retval 无
*/
void UART_SendByte(unsigned char Byte)
{
SBUF=Byte;//SBUF若在等号左边则为发送;若在等号右边则为读取
while(TI==0);//等待TI置1 若TI=1,则数据帧已发送
TI=0;//手动清0
}

/*串口中断函数模板
void UART_Routine() interrupt 4
{
if(RI==1)
{

RI=0;
}
}
*/

main.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void main()
{
UART_Init(); //串口初始化
while(1)
{

}
}

void UART_Routine() interrupt 4
{
if(RI==1) //如果接收标志位为1,接收到了数据
{
P2=~SBUF; //读取数据,取反后输出到LED
UART_SendByte(SBUF); //将受到的数据发回串口
RI=0; //接收标志位清0
}
}

CATALOG
  1. 1. 串口
    1. 1.1. 串口的硬件电路
    2. 1.2. 串口模式(模式1)
    3. 1.3. 串口和中断系统(模式1)
    4. 1.4. 串行口相关寄存器
      1. 1.4.1. 串行口控制寄存器SCON(可位寻址)
      2. 1.4.2. 电源控制寄存器PCON(不可位寻址)
      3. 1.4.3. 串行口数据缓冲寄存器SBUF
      4. 1.4.4. 从机地址控制器SADEN和SADDR
      5. 1.4.5. 中断允许寄存器IE(可位寻址)
      6. 1.4.6. 中断优先级控制寄存器高IPH(不可位寻址)/低IP(可位寻址)
  2. 2. 食用例