(5)串口

串口是一种应用十分广泛的通讯接口,串口成本低、容易使用、通信线路简单,可实现两个设备的互相通信。

单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信,极大的扩展了单片机的应用范围,增强了单片机系统的硬件实力。

51单片机内部自带UART(Universal Asynchronous Receiver Transmitter,通用异步收发器),可实现单片机的串口通信。

请添加图片描述

电平标准:是数据1和数据0的表达方式,是传输线缆中人为规定的电压与数据的对应关系

串口常用的电平标准有如下三种:

  1. TTL电平:+5V表示1,0V表示0
  2. RS232电平:-3-15V表示1,+3+15V表示0
  3. RS485电平:两线压差+2+6V表示1,-2-6V表示0(差分信号)

请添加图片描述

  • 全双工:通信双方可以在同一时刻互相传输数据
  • 半双工:通信双方可以互相传输数据,但必须分时复用一根数据线
  • 单工:通信只能有一方发送到另一方,不能反向传输
  • 异步:通信双方各自约定通信速率
  • 同步:通信双方靠一根时钟线来约定通信速率
  • 总线:连接各个设备的数据传输线路(类似于一条马路,把路边各住户连接起来,使住户可以相互交流)

请添加图片描述

  • STC89C52有1个UART
  • STC89C52的UART有四种工作模式:
    • 模式0:同步移位寄存器
    • 模式1:8位UART,波特率可变(常用)
    • 模式2:9位UART,波特率固定
    • 模式3:9位UART,波特率可变

波特率:串口通信的速率(发送和接收各数据位的间隔时间),即异步时约定的间隔时间,用于数据同步

比特率:发送和接收各bit位的间隔时间,用于数据同步

检验位:用于数据验证

奇偶校验
8位数据格式:0110 0011
9位数据格式:0110 0011 1 // 有偶数(4)个1,所以第9位置1 

停止位:用于数据帧间隔

请添加图片描述

请添加图片描述

请添加图片描述

SCON

请添加图片描述

请添加图片描述

请添加图片描述

发送完后硬件将TI置1,中断后必须要再将TI置0

请添加图片描述

SM0/FE	SM1	SM2	REN	TB8	RB8	 TI  RI
  0		 1	0	0	0	0	0	0 // 使用8位UART波特率可变,禁止接收
SCON = 0x40;

SBUF发送接收缓存,不需要初始化设置

请添加图片描述

定时器配置:

默认使用定时器1,8位自动重装模式(模式2)

8位自动重装模式:16位定时器/计数器由两个8位(0~65535)组成,中断时需要置初始值,否则从0开始计数,这种操作会消耗一定时间,所以精度较低。而8位自动重装同样由两个8位组成,但只用一个8位计数,另一个8位负责记录初始值,当中断时记录初始值的8位会自动重装(Auto Reload)到负责计数(CNT)的8位上,省略了手动置初始值的操作,但是计数范围减少到0~255

void UART_Init(){
    
    
    SCON = 0x40;
    
    TMOD = 0x20; // 0010 0000 定时器1,模式2
    
    PCON |= 0x80; // SMOD=1 波特率加倍
	//TF0 = 0; // 标志位初始化,防止产生中断
	TR1 = 1; // 运行控制位,开始计数工作
    
	TH1 = 0xF4; // 给计数单元赋初值
	TL1 = 0xF4;
	
	ET1 = 0;// 溢出中断允许位=0,禁止溢出中断
	//EA = 1; // 总中断允许控制位
	//PT0 = 0; // 定时器0中断优先级控制位
    //进行串口时钟定时不需要中断,只需要计数后溢出,通过计数溢出速率即可得到波特率
}
void UART_SendByte(unsigned char Byte){
    
    
	SBUF = Byte; // 写操作
	while(TI == 0);
	TI = 0; // 手动恢复TI
}

波特率越低,通讯越稳定,误差越小,也可以Delay几毫秒缓冲一下

串口接收:

REN置1
SCON = 0101 0000 = 0x50;// 或位寻址REN = 1;
EA = 1; // 启动总中断
ES = 1; // 启动串口中断(发送/接收)
void UART_Rountime() interrupt 4 {
    
    
	if(RI == 1){
    
    
		// 串口接收SBUF
		RI = 0;
	}
}

波特率的计算:

通过T1定时器进行波特率计算,并且因为使用8位自动重装模式所以不需要在每次中断后给TH1、TL1赋初始值

TH1 = 0xF4; // 244
TL1 = 0xF4;
256(8位定时器计数上限) - 244 = 12 // 每计12个数就溢出一次,晶振12MHz,每隔1us计一次数,即每隔12us溢出一次
溢出频率 = 1 / 12us = 0.083333MHz

若SMOD=1则溢出频率直接÷16 = 0.0052083MHz // 双倍波特率
SMOD=0则溢出频率先÷2再÷16 = 0.0026042MHz

波特率 = 0.0052083MHz * 1000 * 1000 = 5208.3Hz
或0.0026042MHz * 1000 * 1000 = 2604.2Hz

数据显示模式:

  • HEX模式/十六进制模式/二进制模式:以原始数据的形式显示
  • 文本模式/字符模式:以原始数据编码后的形式显示

文本模式即将单片机发送的数据根据ASCII进行编码后展示

请添加图片描述

猜你喜欢

转载自blog.csdn.net/Falling_Asteroid/article/details/130736724