UART通信_深入理解(理论+实践)
1. 理论知识
1.1 定义和概述
UART是 "通用异步收发器" ( Universal Asynchronous Receiver/Transmitter ) 的缩写,通常简称为UART。是一种异步串行通信接口,用于将数据通过串列通信进行传输。
1.2 硬件组成
常见的串口板会有四根线,VCC供电线、GND地线、TX数据发送端口、RX数据接收端口。使用上,GND连接保证两设备共地,有统一的参考平面;一方tx接另一方rx;vcc按需连接。
1.3 工作原理
- 发送端将数据写入移位寄存器,然后发送数据帧;
- 接收端通过内部时钟信号控制,在每个时钟脉冲采样接收到的信号状态;
- 数据帧由起始比特、数据比特、奇偶校验和停止位组成;
- UART提供缓冲区存储接收的数据,并向处理器报告新数据可用。
串口参数及时序图:
波特率:串口通信的速率(发送和接收各数据位的间隔时间),每秒传输的bit数;
波特率通常是通过系统定时器转化而来:
校验位:用于数据验证;
停止位:用于数据帧间隔;
8位数据格式(LSB最低有效位,MSB最高有效位,一般默认地位优先传输):
9位数据格式:
串口模式图:
1.4 主要特点
- 异步通信,不用同步信号;
- 串行通信,数据按比特顺序逐个发送,而不是像并行通信那样一次发送整个字节;
- 自动同步,接收端会自动识别数据帧的起始点;
- 可靠性高,有停止位和奇偶校验来检测传输错误;
- 低成本,单向只需要一根线就可进行通信,比并行通信硬件成本更低。
1.5 应用
- 手机设计和测试中控制CPU与其他部分的消息传送;
- 连接调制解调器(modem)的串口;
- PC机上的异步通信串口通信(COM接口);
- 嵌入式系统中的低成本串口通信解决方案。
1.6 补充说明
-
UART串口通信指是硬件电路类型,具体电平通信协议通常是采用 TTL电平。
TTL电平 :+5V 表示 1 ,0V 表示 0;
RS232电平: -3 ~ -15V 表示 1 ,+3V ~ +15V表示 0;
RS485电平:两线压差 +2 ~ +6V 表示 1 ,-2 ~ -6V 表示0;
更多RS232协议相关内容见随笔: -
由于电脑上大多数RS232接口的淘汰,现在大多采用串口板实现UART串口通信,其电路设计原理等相关内容见随笔:
-
USART与UART的区别是多了同步通信功能;
USART 通用同步异步收发机(Universal Synchronous Asynchronous Receiver Transmitter)
2. 实践验证
2.1 寄存器方式
验证的硬件环境:AI8051U实验箱 (STC公司产品,搭载当前最新的ai8051芯片)
2.1.1 串口相关寄存器
补充:
四种串口模式的特点应用场景如下:
- 同步位移串行方式
特点:同步信号进行数据传输,数据位移位与同步信号对齐
应用场景:高速数据传输,并且需要精确控制传输时间 - 可变波特率8位数据方式
特点:波特率可变,数据帧为8位
应用场景:计算机外设,嵌入式等,相对灵活,兼容性强 - 固定波特率9位数据方式
特点:数据帧9位,多出的一位常用来作为地址/数据标识位或者奇偶校验,增加通信的可靠性或实现多机通信协议
应用场景:对通信可靠性要求比较高的场景,如工业控制中的多点通信 - 可变波特率9位数据方式
特点:波特率可变,9位数据帧,平衡了数据传输速率和数据完整性的要求
应用场景:需要动态调整传输参数的应用,如智能传感器网络、复杂分布式控制系统
串口中断及波特率涉及到定时器,见随笔:
2.1.2 代码
main.c
/************* 功能说明 **************本例程基于AI8051U为主控芯片的实验箱进行编写测试。使用Keil C251编译器,Memory Model推荐设置XSmall模式,默认定义变量在edata,单时钟存取访问速度快。edata建议保留1K给堆栈使用,空间不够时可将大数组、不常用变量加xdata关键字定义到xdata空间。串口1全双工中断方式收发通讯程序。通过PC向MCU发送数据, MCU收到后通过串口1把收到的数据原样返回.下载时, 选择时钟 24MHz.******************************************/#include "ai8051u.h" // 调用头文件
#include "stdio.h"
#include "intrins.h"
#include "UART.h"unsigned char srcc = 1;void Delay100ms(void) //@24.000MHz
{unsigned long edata i;_nop_();_nop_();i = 599998UL;while (i) i--;
}/******************** 主函数 **************************/
void main(void)
{WTST = 0; // 设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快EAXFR = 1; // 扩展寄存器(XFR)访问使能CKCON = 0; // 提高访问XRAM速度P0M1 = 0x00; P0M0 = 0x00; // 设置所有IO口为准双向口P1M1 = 0x00; P1M0 = 0x00; P2M1 = 0x00; P2M0 = 0x00; P3M1 = 0x00; P3M0 = 0x00; P4M1 = 0x00; P4M0 = 0x00; P5M1 = 0x00; P5M0 = 0x00; P6M1 = 0x00; P6M0 = 0x00; P7M1 = 0x00; P7M0 = 0x00; Uart1_Init();while (1){P40 = 0;P0 = ~srcc;
// UART_SendByte(srcc);
// Delay100ms();
// srcc++;}
}void Uart1_Isr(void) interrupt 4
{if (TI) //检测串口1发送中断{TI = 0; //清除串口1发送中断请求位}if (RI) //检测串口1接收中断{srcc = (unsigned char)SBUF;UART_SendByte(srcc);RI = 0; //清除串口1接收中断请求位}
}
UART.c
#include "ai8051u.h"void Uart1_Init(void) //9600bps@24.000MHz
{SCON = 0x50; //8位数据,可变波特率AUXR |= 0x40; //定时器时钟1T模式AUXR &= 0xFE; //串口1选择定时器1为波特率发生器TMOD &= 0x0F; //设置定时器模式TL1 = 0x8F; //设置定时初始值TH1 = 0xFD; //设置定时初始值ET1 = 0; //禁止定时器中断TR1 = 1; //定时器1开始计时ES = 1; //使能串口1中断EA = 1;P_SW1 = (P_SW1 & ~0xc0) | 0x40;
}void UART_SendByte(unsigned char Byte)
{SBUF = Byte;while(TI);TI=0;
}
2.1.3 现象
-
单片机向上位机发送信息
-
上位机向单片机发送信息后返回
串口界面:实验板子:0x45 :小端模式, 1010 0010
![image-20250110153429821](C:\Users\Thomas\AppData\Roaming\Typora\typora-user-images\image-20250110153429821.png)
2.1.4 难点
- ai8051u这款芯片是最近才接触到的,它烧录程序用的是USB-UART形式,串口1和烧录口是同一引脚。一开始想着怎么在同一引脚完成串口通信,它烧录完后,串口自动掉了。USB-CDC模式也是首次了解,这个模式的源码啃了一天没啃下来(后续再深入学习)。后面在手册中找到了可以把串口1转移到其他引脚进行通信。
- 中断中不能操作寄存器,while循环中就可以,想把串口传的值直接在串口中断给到P0,P0直接没反应了。通过中间变量传递,在while中赋值就没事。
2.2 库函数方式(贴近实际的高效开发)
验证的硬件环境:洋桃开发版 (成品开发板可以省去手动接线)