UART作为嵌入式系统中最基础的通信接口之一,其功能设计直接影响着系统通信的可靠性和效率。ARM架构下的UART模块在传统异步串口基础上,通过硬件FIFO、错误检测机制和IrDA支持等特性,为开发者提供了更强大的通信能力。
接收FIFO不仅仅是简单的数据缓冲区,其设计包含了完整的错误状态跟踪系统。当字符被接收到FIFO时,会伴随4个关键错误状态位:
位11(Overrun):溢出标志独立于具体字符,当FIFO已满且新字符完全接收时触发。此时移位寄存器中的数据会被丢弃,直到FIFO有空位时才恢复。这种设计避免了传统UART中溢出导致数据完全丢失的问题。
位10(Break):检测到线路保持低电平超过完整字符传输时间(起始位+数据位+校验位+停止位)。在FIFO模式下,Break条件仅会向FIFO压入一个0字符,后续数据需等待线路恢复高电平后才继续接收。
位9(Parity):校验错误标志,当接收字符的校验位与UARTLCR_H寄存器中配置的校验模式不匹配时触发。
位8(Framing):帧错误标志,当检测到无效停止位(停止位应为1)时触发。
实际调试中发现,FIFO满时的溢出处理需要特别注意:虽然新数据不会覆盖FIFO内容,但移位寄存器中的数据会丢失。建议在接收高负载数据时,合理设置中断水位线并及时读取数据。
通过设置UARTLCR_H寄存器的FEN位为0可禁用FIFO,此时UART退化为传统的单字节缓冲模式:
这种模式虽然降低了性能,但在某些需要严格时序控制的场景(如Modbus RTU)中反而更有优势,因为每个字符的传输都能被精确控制。
IrDA SIR ENDEC模块在UART数据流和红外信号之间建立数字桥梁,其主要特点包括:

图:IrDA 3/16调制波形示意图(逻辑0产生光脉冲,逻辑1无脉冲)
低功耗模式的核心是IrLPBaud16信号的生成,其配置步骤包括:
计算分频系数:ILPDVSR = FUARTCLK / FIrLPBaud16
设置UARTILPR寄存器写入分频系数
置位UARTCR寄存器的SIRLP位启用低功耗模式
c复制// 低功耗IrDA配置示例
#define UARTCLK_FREQ 48000000
#define DESIRED_IRLPBAUD16 1843200
void configureLowPowerIrDA(void) {
uint8_t ildpvsr = UARTCLK_FREQ / DESIRED_IRLPBAUD16;
UARTILPR = ildpvsr; // 设置分频系数
UARTCR |= (1 << 2); // 置位SIRLP启用低功耗模式
}
实测中发现,低功耗模式对时钟精度要求较高,建议使用PLL提供稳定的UARTCLK。分频系数必须大于0,否则无法产生IrLPBaud16脉冲。
硬件流控制通过nUARTRTS和nUARTCTS信号实现设备间的流量协调:
RTS发送控制:
CTS接收控制:
mermaid复制sequenceDiagram
participant DeviceA
participant DeviceB
DeviceA->>DeviceB: nUARTRTS(低)表示可接收
DeviceB->>DeviceA: 发送数据(CTS有效时)
DeviceA->>DeviceB: FIFO满→nUARTRTS(高)
DeviceB->>DeviceA: 停止发送(检测到CTS无效)
通过UARTIFLS寄存器可设置触发流控制的水位值,典型配置建议:
| FIFO深度 | 接收水位线 | 发送水位线 | 适用场景 |
|---|---|---|---|
| 32字节 | 8字节 | 24字节 | 低延迟 |
| 32字节 | 16字节 | 16字节 | 平衡模式 |
| 32字节 | 24字节 | 8字节 | 高吞吐 |
在115200bps及以上波特率时,建议接收水位线不低于8字节,避免频繁中断影响系统性能。同时要注意RTS/CTS信号走线长度,过长会导致流控制响应延迟。
UART提供两种DMA请求模式,通过UARTDMACR寄存器配置:
| 信号类型 | 触发条件 | 适用场景 |
|---|---|---|
| 单次请求 | 接收FIFO≥1字符/发送FIFO≥1空位 | 零星数据传输 |
| 突发请求 | 接收FIFO>水位线/发送FIFO<水位线 | 连续大数据块传输 |
典型DMA配置流程:
c复制// DMA接收配置示例
void configureUARTDMA(void) {
UARTIFLS = (2 << 0) | (2 << 3); // RX/TX水位线设为1/4 FIFO
UARTDMACR |= (1 << 0); // 启用接收DMA
// 此处应配置DMA控制器参数...
}
UART中断系统包含11种可屏蔽中断源,归纳为5类:
接收中断(UARTRXINTR):
发送中断(UARTTXINTR):
接收超时中断(UARTRTINTR):
错误中断(UARTEINTR):
调制解调器状态中断(UARTMSINTR):
中断处理最佳实践:
ARM UART采用分频系数=IBRD + FBRD/64的配置方式:
计算分频系数:BRD = UARTCLK / (16 × Baud Rate)
分离整数和小数部分:
c复制IBRD = (uint16_t)BRD;
FBRD = (uint8_t)((BRD - IBRD) * 64 + 0.5);
写入UARTIBRD和UARTFBRD寄存器
实测案例:在UARTCLK=48MHz下配置115200bps时:
BRD = 48e6/(16×115200) ≈ 26.041667
IBRD=26, FBRD=round(0.041667×64)=3
实际波特率=48e6/(16×(26+3/64))=115207bps,误差仅0.006%
UARTCR寄存器包含多个重要控制位:
| 位域 | 名称 | 功能说明 |
|---|---|---|
| 15 | CTSEn | 启用CTS硬件流控制 |
| 14 | RTSEn | 启用RTS硬件流控制 |
| 9 | SIRLP | 低功耗IrDA模式 |
| 8 | SIREN | 启用IrDA SIR模式 |
| 7 | LBE | 回环测试模式 |
| 1 | UARTEN | 全局使能UART |
| 0 | TXE | 使能发送器 |
重要编程规范:
| 错误类型 | 可能原因 | 解决方案 |
|---|---|---|
| 帧错误 | 波特率不匹配/停止位配置错误 | 检查双方波特率配置和UARTLCR_H设置 |
| 校验错误 | 校验模式不一致/线路干扰 | 确认收发方校验设置,检查信号质量 |
| 溢出错误 | 接收处理不及时 | 优化中断处理或启用DMA |
| Break | 线路被长时间拉低 | 检查硬件连接和对方设备状态 |
无通信:
通信不稳定:
距离短:
我在实际项目中曾遇到IrDA通信距离不达标的案例,最终发现是UARTILPR寄存器配置值计算错误导致脉冲宽度不达标。通过精确计算分频系数并验证实际波形后问题得以解决。这提醒我们,对时序敏感的应用必须严格验证硬件信号质量。