串口
# 串口通信
# 1、串口的基本原理
- 详细看两位大佬的博客,这里只简单写寄存器的配置和函数
(13条消息) 『51单片机』串口通信配置_謓泽的博客-CSDN博客_51单片机串口配置 (opens new window)
(七)51单片机基础——串口通信_51单片机串口分时复用_花园宝宝小点点的博客-CSDN博客 (opens new window)
# 2、初始化窗口函数
void UART_Init()
{
//**1.配置SCON串行控制寄存器**
SCON = 0x40;
TMOD &= 0x0F;//0000 0000 & 0000 1111 定时器1的话高四位清0 定时器0的话低四位清0
TMOD |= 0x20;//0000 0000 | 0010 0000
//2.设置初始时间
TL1 = 0xFA;
TH1 = 0xFA;
//3.禁止T1(定时器1)中断
ET1 = 0;
//4.配置TCON
TR1 = 1; //开启T1
}
2
3
4
5
6
7
8
9
10
11
12
13
14
# 2.1 配置SCON串行控制寄存器
注→串行控制寄存器为可位寻址:可以单独的对一位寄存器进行赋值。
B7→FE:检测帧错误,也就是说它有一个奇校验和偶校验。如果错误的话就会在这一位当中检测FE这个帧错误。注:当我们去使用⒏位串口的时候就不需要来检测这个帧错误了。这里所说的是『模式1:8位UART[⒈个字节],波特率可变』— 最常用的一个模式。
B7→SM0 = 0
B6→SM1 = 1 [决定工作模式,在这里我们是工作模式⒈]
B5→SM2 = 0 [多机通信是方式⒉和方式⒊的,如果是这两个的话设置SM2 = 1反之SM2 = 0]
B4→REN = 1||0 [是否允许它进行接收RXD,如果REN = 0的话就是不允许接收 REN = 1的话就是允许接收。想让单片机接收数据的话就置为1,不想让单片机接收就置为0]
B3→TB8 = 0 [方式三和方式二置1用于发送第⑨位数据,方式一置0]
B2→RB8 = 0 [方式三和方式二置1用于接收第⑨位数据,方式一置0]
B1→TI = 0 [初始化配置给0]
B0→RI = 0 [初始化配置给0]
关于为什么接收到数据就会中断的说明:
- 首先和内部结构有关,要结合串口通信内部结构来理解。
- 串口在接收到数据之后,硬件会自动将RI=1。
- 控制串口中断的逻辑门是或门
- 只要RI>=1或者TI>=1就会触发串口中断。前提是程序打开了总中断和串口中断。
# 2.2 配置定时器1
# 2.2.1 配置TMOD
注→这个串口只能配置定时器⒈这是它专用的。
这里配置定时器1的M1=1,M0=0,即为8位重装定时器。
😎模式2→8位自动重装模式,这个算是第二个最常用的一个模式。第二种模式主要用于串口通信产生波特率**来用的『在电子通信领域,波特(Baud)即调制速率,指的是有效数据讯号调制载波的速率,即单位时间内载波调制状态变化的次数』
# 2.2.2 配置 TCON
- IE和IT都是外部中断使用的,所以我们不用去管
# 3、电脑通过串口控制LED
main.c
#include <REGX52.H> #include "UART.h" void main() { UART_Init(); while(1) { } } void UART_Routine() interrupt 4 { //如果接收标志位为1,接收到了数据.[之所以需要判断是因为我们要区分接收RI=TXD和发送TI=RXD] if(RI==1) { P2=~SBUF; //读取数据,取反后输出到LED SBUF在等号的右边说明它是接收位 UART_SendByte(SBUF); //将接收到的数据发回串口 RI=0; //将接收到的数据发回串口 } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24UART.c
#include <REGX52.H> /** * @brief 串口初始化,4800bps@11.0592MHz * @param 无 * @retval 无 */ void UART_Init() { PCON |= 0x80; //使能波特率倍速位SMOD SCON = 0x50; //8位数据,可变波特率(本次代码不需要去接收数据,所以写0x40就行,要接收就应该是0x50) TMOD &= 0x0F; //清除定时器1模式位 TMOD |= 0x20; //设定定时器1为8位自动重装方式 TL1 = 0xF4; //设定定时初值 TH1 = 0xF4; //设定定时器重装值 TR1=1; //启动定时器1 ET1 = 0; //禁止定时器1中断 //开启串口中断 ES=1; EA=1; } /** * @brief 串口发送一个字节数据 * @param Byte 要发送的一个字节数据 * @retval 无 */ void UART_SendByte(unsigned char Byte) { SBUF=Byte; //发送-单片机向电脑发送数据 while(TI==0); //判断是否发送成功,发送成功TI会硬件置1 TI=0; //软件置0 } //串口中断函数模板 //void UART_Routine() interrupt 4 //{ // if(RI==1) //接收到数据,RI会自动置1,然后我们想要软件置0 // { // RI=0; //软件置0 // } //}
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
45
46
47
48
49
50
51
52
53
54