文章目录
UART(Universal Asynchronous Receiver/Transmitter 通用异步收发器)是一种异步串行通信协议,广泛应用于嵌入式系统、工业控制、传感器通信等领域。以下从协议层、物理层、技术特点和代码示例四个维度展开详细说明。
一、协议层
UART协议层定义了数据传输的帧格式、时序规则和错误检测机制,其核心是异步通信,无需共享时钟信号。
1. 数据帧结构
每帧数据由以下部分组成(以最常见的8N1
格式为例):
-
起始位(Start Bit)
- 电平:低电平(逻辑0)
- 作用:标志数据帧开始,接收端通过检测下降沿触发同步。
-
数据位(Data Bits)
- 位数:5/6/7/8位(常用8位)
- 传输顺序:LSB(最低有效位)优先
- 示例:发送字符
A
(ASCII 0x41 =01000001
),实际传输顺序为1 0 0 0 0 0 1 0
(从右到左)。
-
校验位(Parity Bit)(可选)
校验类型 规则 特点 无校验 不添加校验位 节省时间,无检错能力 奇校验 数据位+校验位中1的总数为奇数 检测单比特错误 偶校验 数据位+校验位中1的总数为偶数 检测单比特错误 Mark 固定为1 作为第9位数据使用 Space 固定为0 作为第9位数据使用 -
停止位(Stop Bit)
- 电平:高电平(逻辑1)
- 位数:1位、1.5位(罕见)、2位
- 作用:标志帧结束,并为下一帧提供缓冲时间。
2. 时序与波特率
-
波特率(Baud Rate)
- 定义:每秒传输的符号数(1符号=1位),常见值:9600、115200等。
- 计算:
位时间(秒)= 1 / 波特率 (例如:9600bps → 104μs/位)
- 误差要求:通常需控制在±2%以内,否则可能采样错误。
-
采样点
- 接收端在每位中心点(如16倍过采样时,取第8、9、10次采样的多数值)进行采样。
- 抗干扰机制:三次采样表决(提高噪声环境下的可靠性)。
3. 错误检测
- 帧错误(Framing Error):停止位未检测到高电平。
- 奇偶校验错误:数据与校验位不匹配。
- 溢出错误(Overrun Error):接收缓冲区未及时读取,新数据覆盖旧数据。
4. 高级协议配置
- 数据流控制(可选):
- 硬件流控:使用RTS(请求发送)和CTS(清除发送)信号线。
- 软件流控:通过XON/XOFF字符控制数据流。
二、物理层
UART的物理层定义了电气特性、接口标准和硬件连接方式。
1. 电平标准
-
TTL/CMOS电平
- 逻辑0:0V(或接近0V,如<0.8V)
- 逻辑1:3.3V或5V(如>2.4V为有效高电平)
- 典型应用:单片机之间、芯片内部通信(传输距离<1米)。
-
RS232电平
- 逻辑0:+3V ~ +15V
- 逻辑1:-3V ~ -15V
- 特点:抗干扰强,支持长距离(最长15米@20kbps)。
-
RS485电平(差分信号)
- 通过A、B两线的电压差表示逻辑:
- 逻辑1:B线电压 > A线电压
- 逻辑0:A线电压 > B线电压
- 特点:支持多点通信,最长1200米。
- 通过A、B两线的电压差表示逻辑:
2. 接口定义
-
基本引脚:
- TX(Transmit):数据发送线
- RX(Receive):数据接收线
- GND(Ground):共地参考
-
扩展引脚(用于流控):
- RTS(Request to Send):请求发送
- CTS(Clear to Send):允许发送
- DTR(Data Terminal Ready):设备就绪
- DSR(Data Set Ready):数据就绪
3. 典型连接方式
- 直接连接(TTL电平):
设备A.TX → 设备B.RX 设备A.RX ← 设备B.TX 共地连接:GND ↔ GND
- RS232连接(使用DB9接口):
TXD(Pin3) ↔ RXD(Pin2) RXD(Pin2) ↔ TXD(Pin3) GND(Pin5) ↔ GND(Pin5)
- 需交叉连接(DTE与DCE设备)。
4. 电平转换电路
- TTL转RS232:使用MAX232芯片。
- TTL转RS485:使用MAX485芯片(支持半双工)。
三、技术特点
1. 核心特性
- 异步通信:无共享时钟,依赖预定义的波特率。
- 全双工:可同时发送和接收数据(需独立TX/RX线路)。
- 点对点:通常支持1对1通信,需扩展硬件支持多设备。
- 配置灵活:可自定义数据位、停止位、校验方式、波特率。
2. 关键参数
参数 | 典型值/选项 | 影响 |
---|---|---|
波特率 | 9600, 19200, 115200 bps | 速度与抗干扰的平衡 |
数据位 | 5/6/7/8位 | 数据精度与效率 |
停止位 | 1/1.5/2位 | 帧间隔与同步稳定性 |
校验方式 | None/Even/Odd/Mark/Space | 检错能力与传输开销 |
3. 优势与局限
优势:
- 实现简单,仅需2根信号线(TX/RX)。
- 成本低,几乎所有微控制器内置UART模块。
- 支持全双工实时通信。
局限:
- 传输距离短(TTL电平<1米,RS232<15米)。
- 无硬件寻址机制,难以直接支持多设备通信。
- 依赖精确的波特率匹配,时钟误差敏感。
4. 典型应用场景
- 设备调试:通过UART输出调试信息(如STM32的printf重定向)。
- 模块通信:GPS模块、蓝牙模块(HC-05)、WiFi模块(ESP8266)。
- 工业控制:PLC与HMI(人机界面)的RS232通信。
- 芯片级通信:SoC与外围传感器(如温度传感器DS18B20)。
四、实际开发注意事项
- 波特率匹配:双方设备必须设置相同波特率(误差<3%)。
- 电平兼容:不同电平设备间需加转换芯片(如MAX232)。
- 抗干扰设计:
- 长距离通信使用RS485差分信号。
- 添加终端电阻(120Ω)消除信号反射。
- 数据缓冲:使用FIFO缓冲区防止数据溢出。
五、代码示例
以下是一个基于 STM32 HAL库 的UART应用示例代码,包含 初始化配置、数据发送、接收中断 和 printf重定向 的实现。
1、硬件配置要求
- MCU型号:以STM32F103C8T6为例(其他型号需调整引脚)
- UART接口:USART1(PA9-TX, PA10-RX)
- 波特率:115200, 8N1(8位数据,无校验,1停止位)
- 开发环境:STM32CubeIDE + HAL库
2、代码实现
1). UART初始化配置
// 在 main.c 中添加以下代码
UART_HandleTypeDef huart1;
void UART_Init(void) {
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK) {
Error_Handler();
}
// 启用接收中断(可选)
HAL_UART_Receive_IT(&huart1, &rx_buffer, 1); // rx_buffer为接收缓冲区
}
2). GPIO与时钟配置(CubeMX自动生成)
// 在 stm32f1xx_hal_msp.c 中添加:
void HAL_UART_MspInit(UART_HandleTypeDef* huart) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
if (huart->Instance == USART1) {
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
// PA9-TX, PA10-RX
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// 启用USART1全局中断(若使用中断)
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
}
}
3). 发送数据(阻塞模式)
// 发送字符串
void UART_SendString(char *str) {
HAL_UART_Transmit(&huart1, (uint8_t*)str, strlen(str), HAL_MAX_DELAY);
}
// 发送字节数组
void UART_SendBytes(uint8_t *data, uint16_t len) {
HAL_UART_Transmit(&huart1, data, len, 100);
}
4). 接收数据(中断模式)
// 定义接收缓冲区
uint8_t rx_buffer;
// 中断回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
if (huart->Instance == USART1) {
// 处理接收到的数据(示例:回显)
HAL_UART_Transmit(&huart1, &rx_buffer, 1, 100);
// 重新启用接收中断
HAL_UART_Receive_IT(&huart1, &rx_buffer, 1);
}
}
5). 重定向printf到UART
// 在 main.c 中添加以下代码
#include <stdio.h>
// 重写 _write 函数
int _write(int fd, char *ptr, int len) {
HAL_UART_Transmit(&huart1, (uint8_t*)ptr, len, HAL_MAX_DELAY);
return len;
}
// 使用示例
printf("System Clock: %ld Hz\r\n", HAL_RCC_GetHCLKFreq());
3、主函数调用
int main(void) {
HAL_Init();
SystemClock_Config();
UART_Init();
printf("UART Initialized\r\n");
while (1) {
// 主循环中可添加其他任务
// 例如:每隔1秒发送数据
HAL_Delay(1000);
UART_SendString("Hello World!\r\n");
}
}
4、关键功能说明
功能 | 实现方式 | 特点 |
---|---|---|
初始化配置 | HAL_UART_Init + MSP配置 | 自动生成引脚和时钟初始化代码 |
数据发送 | HAL_UART_Transmit | 阻塞式发送,简单可靠 |
中断接收 | HAL_UART_Receive_IT + 回调函数 | 非阻塞接收,适合实时性要求高场景 |
printf重定向 | 重写 _write 函数 | 方便调试信息输出 |
5、常见问题解决
-
无输出/乱码
- 检查波特率是否匹配(PC端串口工具与代码设置一致)
- 验证TX/RX引脚是否交叉连接(MCU TX → USB-TTL RX,MCU RX → USB-TTL TX)
-
中断接收不触发
- 确认已调用
HAL_UART_Receive_IT
并重新启用中断 - 检查NVIC中断优先级配置
- 确认已调用
-
printf无法使用
- 确保工程设置中勾选 “Use MicroLIB”(Keil)或正确链接
syscalls.c
- 确保工程设置中勾选 “Use MicroLIB”(Keil)或正确链接
6、扩展功能
-
DMA传输
// 发送DMA HAL_UART_Transmit_DMA(&huart1, data, len); // 接收DMA HAL_UART_Receive_DMA(&huart1, rx_buf, len);
-
RS485半双工控制
// 发送前使能DE引脚(MAX485) HAL_GPIO_WritePin(DE_GPIO_Port, DE_Pin, GPIO_PIN_SET); HAL_UART_Transmit(...); HAL_GPIO_WritePin(DE_GPIO_Port, DE_Pin, GPIO_PIN_RESET);
通过上述代码,可实现STM32的UART基础通信功能。实际开发中建议使用 STM32CubeMX 生成初始化代码,确保配置正确性。
六、与其他协议的对比
特性 | UART | SPI | I²C |
---|---|---|---|
时钟 | 异步 | 同步(主控) | 同步(主控) |
数据线数量 | 2(TX/RX) | 3(SCK/MOSI/MISO) | 2(SDA/SCL) |
最大速率 | 1Mbps | 50Mbps | 3.4Mbps |
寻址方式 | 无 | 片选信号 | 7/10位地址 |
拓扑结构 | 点对点 | 主从 | 多主多从 |
七、总结
UART凭借其简单性、灵活性和广泛兼容性,成为嵌入式系统的“基础设施级”通信协议。尽管存在传输距离短和缺乏多设备支持的局限性,但通过电平转换芯片(如RS232/RS485)和协议扩展(如Modbus),仍可满足大多数中低速通信需求。在实际开发中,需重点关注电平匹配、波特率精度和抗干扰设计。