1. UART寄存器从硬件接口到软件控制的桥梁在嵌入式开发和通信接口调试中UART通用异步收发传输器是我们最常打交道的模块之一。无论是通过串口打印调试信息还是与传感器、蓝牙模块通信UART都扮演着核心角色。很多开发者习惯使用操作系统或库函数提供的封装好的API比如printf、read、write这确实方便但一旦遇到通信不稳定、数据丢失或者需要极致优化性能的场景仅仅停留在API层面就显得力不从心了。这时深入寄存器层面理解每一个控制位的含义就成了解决问题的关键。这就像开车会踩油门刹车能上路但懂发动机原理和变速箱逻辑才能玩转性能改装和故障排查。UART通信的本质是CPU通过一组特定的内存地址即寄存器与一个专用的硬件模块对话。这个模块内部有移位寄存器负责串行数据的收发有FIFO先进先出队列缓冲数据还有一套复杂的状态机和中断逻辑来协调整个流程。我们写的每一行配置代码最终都转化为对特定寄存器比特位的读写操作。RHR接收保持寄存器和THR发送保持寄存器是数据进出的门户IER中断使能寄存器和IIR中断标识寄存器则是整个系统的“神经系统”负责及时通知CPU有事件需要处理。而FCRFIFO控制寄存器、LCR线路控制寄存器等则像是一系列旋钮和开关精细地调整着通信的波特率、数据格式和缓冲策略。本文将基于一份详实的芯片手册以TI某款支持UART/IrDA/CIR的多模式芯片为例拆解这些关键寄存器的每一个比特并结合实际驱动开发中的场景分享如何配置它们来构建稳定、高效的串口通信。无论你是正在调试一个棘手的通信丢包问题还是希望为自己的产品设计一个健壮的串口驱动这些寄存器级的细节都将为你提供坚实的底层支撑。2. 核心数据通道RHR与THR寄存器详解2.1 接收保持寄存器RHR数据抵达的第一站RHR全称Receiver Holding Register是CPU从串口读取接收数据的唯一窗口。它的工作原理背后隐藏着UART接收路径的精巧设计。接收数据从RX引脚进入首先由一个接收移位寄存器Receiver Shift Register进行串并转换。这个移位寄存器像是一个小型的传送带每一位数据起始位、数据位、校验位、停止位随着波特率时钟依次移入。当一整帧数据例如8个数据位接收完毕且校验如果使能通过后这整个字节才会被并行地“搬运”到RHR中等待CPU读取。手册中指出RHR实际上是一个64字节的FIFO。这是一个至关重要的优化。如果没有FIFORHR就只是一个单字节的存储单元。这意味着CPU必须在下一个字节被接收并覆盖当前值之前及时读走数据否则就会发生数据覆盖Overrun。而64字节的FIFO提供了缓冲能力允许CPU在一定时间内不处理数据而硬件可以持续接收多达64个字节极大地减轻了CPU的中断响应压力。当FIFO被禁用时通过FCR寄存器这个FIFO的“0号位置”就被当作一个单字节的RHR来使用。注意手册特别强调了一点——“If an overflow occurs, the data in the RHR is not overwritten.” 这句话需要正确理解。这里的“overflow”指的是接收移位寄存器中的数据已经准备好移入RHR FIFO但FIFO已满的情况。此时移位寄存器中的新数据会丢失这就是Overrun错误但FIFO中已存的数据是安全的不会被新数据冲掉。这保证了已接收数据的完整性但代价是丢失了最新的数据。对应的错误状态会在LSR线路状态寄存器的RXOE位标记。从编程角度看RHR是一个只读寄存器。你无法向它写入数据只能从中读取。它的位域非常简单低8位Bit 7-0就是接收到的数据字节高8位Bit 15-8保留。读取RHR的操作会同时做两件事一是将数据返回给CPU二是使FIFO的读指针前进一位如果FIFO使能或者清空单字节缓冲区。因此在中断服务程序中我们通常通过循环读取RHR来清空FIFO直到LSR寄存器显示RX FIFO为空RXFIFOE位为0。2.2 发送保持寄存器THR数据出发的起点与RHR相对应THRTransmit Holding Register是CPU向串口写入待发送数据的入口。其工作流程是CPU将需要发送的数据字节写入THR。如果FIFO功能使能数据会先进入64字节的发送FIFO中排队。然后UART模块内部的发送移位寄存器Transmit Shift Register会从发送FIFO中取出数据将其从并行格式转换为串行比特流加上起始位、校验位和停止位最终通过TX引脚一位一位地发送出去。THR也是一个FIFO这同样是为了提升效率。CPU可以一次性写入多个字节到THR即发送FIFO而不必等待每个字节发送完毕。UART硬件会自主地、连续地从FIFO中取出数据发送从而解放了CPU。当FIFO被禁用时THR同样退化为一个单字节的寄存器。从寄存器描述看THR的低8位Bit 7-0是有效数据位高8位保留。关键点在于THR是一个只写寄存器对CPU而言。这意味着你向这个地址写入数据操作的是发送保持器但你从这个地址读取读回来的值是不确定的手册标注为W-unknown并非当前FIFO中等待发送的数据。要了解发送FIFO的状态需要查询LSR线路状态寄存器的TXFIFOE发送FIFO空和TXSRE发送移位寄存器空位。实操心得THR写入与流控制在实际编程中向THR写入数据前一个良好的习惯是检查LSR的TXFIFOE位。如果该位为1表示发送FIFO已空可以安全写入。如果使用FIFO且未使能硬件流控盲目连续写入超过FIFO深度的数据会导致数据丢失。更稳健的做法是结合IER中的THRIT发送保持寄存器中断。当发送FIFO中的数据量低于某个阈值例如变空时会触发中断在中断服务程序中再填充新的数据这样可以实现无缝的连续发送。3. 中断系统的指挥官IER与IIR寄存器解析中断是提高CPU效率、实现异步事件处理的关键机制。UART的中断系统主要由IER和IIR这一对寄存器协同管理。3.1 中断使能寄存器IER决定谁可以“打报告”IERInterrupt Enable Register就像一个总开关板决定哪些UART内部事件可以产生中断请求IRQ。手册中展示了三种模式下的IERUART模式、IrDA模式和CIR模式。我们以最常用的UART模式为例进行深度解析。UART模式的IER寄存器图24-30低8位每一位控制一个中断源的使能Bit 0 - RHRIT接收保持寄存器中断使能。当RHR接收FIFO中的数据达到触发阈值由FCR或TLR设置或发生接收超时如果支持时此中断被触发。这是最常用的数据接收中断。Bit 1 - THRIT发送保持寄存器中断使能。当发送FIFO中的数据量低于触发阈值通常为空时此中断被触发通知CPU可以发送更多数据。Bit 2 - LINESTSIT接收线路状态中断使能。当发生接收错误如溢出OE、奇偶校验错PE、帧错误FE、线路间断BI时触发。这是一个错误处理中断优先级通常最高。Bit 3 - MODEMSTSIT调制解调器状态中断使能。当CTS、RTS、DSR等调制解调器控制线的状态发生变化时触发。用于硬件流控制。Bit 4 - SLEEPMODE睡眠模式使能。此位用于在UART空闲时停止波特率时钟以节能。Bit 5 - XOFFITXOFF/特殊字符中断使能。当接收到XOFF流控字符或特定字符时触发。Bit 6 - RTSITRTS中断使能。当RTS引脚状态变化时触发。Bit 7 - CTSITCTS中断使能。当CTS引脚状态变化时触发。关键点Bit 5, 6, 7 (XOFFIT, RTSIT, CTSIT) 和 Bit 4 (SLEEPMODE) 的写入有一个前提条件必须当EFR[4]增强功能寄存器第4位为1时才可写。这是一个硬件保护机制防止意外修改这些高级功能位。在初始化时如果需要使用这些功能必须先解锁EFR。配置策略 对于大多数简单应用通常使能RHRIT接收中断和LINESTSIT线路错误中断即可。如果需要高效的连续发送如打印大量日志可以同时使能THRIT发送中断。如果设备连接了调制解调器或需要硬件流控则需要使能MODEMSTSIT、CTSIT等。初始化代码通常如下所示假设寄存器地址映射到uart_base// 假设已设置好波特率、数据格式LCR // 1. 如果需要设置高级中断如CTSIT先解锁EFR如果支持 // *(uart_base EFR_OFFSET) | (1 4); // 解锁具体地址取决于硬件 // 2. 配置IER使能接收中断和线路状态中断 *(uart_base IER_OFFSET) (1 0) | (1 2); // 使能 RHRIT 和 LINESTSIT // 如果需要发送中断 // *(uart_base IER_OFFSET) | (1 1); // 使能 THRIT3.2 中断标识寄存器IIR识别是谁“打了报告”当CPU接收到UART中断请求时第一个动作就是读取IIRInterrupt Identification Register。这是一个只读寄存器它的核心作用是告诉CPU当前所有已使能的中断源中优先级最高的是哪一个。IIR的读取本身不会清除中断但提供了识别中断源所需的信息。UART模式下的IIR图24-33关键字段如下Bit 0 - IT_PENDING中断挂起标志。这是你首先要看的位。0有中断待处理。1无中断待处理。注意这个逻辑是反的0表示有中断1表示没有。这是历史原因为了兼容早期16550 UART芯片。Bit 5-1 - IT_TYPE中断类型字段。这是一个5位字段其值直接对应最高优先级的中断源。手册表24-15给出了详细的映射0Modem状态中断优先级4。由CTS、RTS、DSR等变化引起。1h(1)THR中断优先级3。发送FIFO空或低于阈值。2h(2)RHR中断优先级2。接收FIFO达到触发阈值。3h(3)接收线路状态错误优先级1。包括OE、PE、FE、BI。这是最高优先级的可屏蔽中断。6h(6)接收超时中断优先级2。当接收FIFO非空但在一段时间内没有收到新字符也没有被读空时触发。8h(8)XOFF/特殊字符中断优先级5。10h(16)CTS/RTS从低到高变化中断优先级6。Bit 7-6 - FCR_MIRRORFCR[0]的镜像。反映了FIFO是否使能。中断处理流程与优先级 中断优先级是固定的由硬件决定。线路状态错误优先级1最高因为它表示通信链路出了问题需要立即处理。其次是接收数据就绪RHR中断和超时中断优先级2确保数据不被覆盖。然后是发送就绪THR中断优先级3最后是其他状态中断。在中断服务程序ISR中标准的处理模式是一个循环因为一次中断可能对应多个事件尤其是读取RHR后FIFO中仍有数据或者处理完一个高优先级中断后低优先级中断依然存在。伪代码如下void UART_ISR(void) { uint16_t iir_value; do { iir_value *(uart_base IIR_OFFSET); // 检查是否有中断挂起Bit 0为0表示有 if (iir_value 0x01) { break; // 无中断挂起退出循环 } // 根据中断类型字段Bit 5-1处理不同中断 switch ((iir_value 1) 0x1F) { // 提取IT_TYPE字段 case 0x03: // 011b线路状态错误优先级1 handle_line_status_error(); break; case 0x02: // 010b接收数据就绪优先级2 case 0x06: // 110b接收超时优先级2 handle_receive_data(); break; case 0x01: // 001b发送保持寄存器空优先级3 handle_transmit_ready(); break; case 0x00: // 000bModem状态变化优先级4 handle_modem_status(); break; // ... 处理其他中断类型 default: // 未知中断类型可能是错误 break; } // 某些中断如读LSR清除错误、读RHR减少数据会改变中断状态 // 循环检查是否还有其他挂起的中断 } while (1); }重要提示手册在IIR描述的开头有一个关键注释“An interrupt source can be flagged only if enabled in the IER register.” 这意味着即使硬件发生了某个事件如接收FIFO满如果IER中没有使能对应的中断位这个事件也不会在IIR中标识出来更不会向CPU发起中断请求。IIR只反映那些“已使能且已发生”的中断源中优先级最高的一个。因此IER和IIR必须配合理解。4. 数据缓冲与流程控制FCR、TCR与TLR寄存器4.1 FIFO控制寄存器FCR缓冲区的管理核心FCRFIFO Control Register是管理64字节收发FIFO的核心。它是一个只写寄存器这意味着你无法通过读FCR来确认当前设置其设置会反映在IIR的FCR_MIRROR位上。Bit 0 - FIFO_ENFIFO总使能位。此位只能在波特率时钟停止时即DLL和DLH分频器为0时更改。这通常意味着需要在UART初始化早期、设置波特率之前配置它。置1启用64字节FIFO置0则禁用FIFO使THR和RHR退化为单字节寄存器。Bit 1 - RX_FIFO_CLEAR接收FIFO清除位。写1会立即清空接收FIFO并重置其内部计数器。该位会在操作完成后自动清零。在通信开始前或发生错误后清空FIFO是个好习惯。Bit 2 - TX_FIFO_CLEAR发送FIFO清除位。写1会立即清空发送FIFO并重置其内部计数器。同样会自动清零。Bit 3 - DMA_MODEDMA模式选择。此位也需在波特率时钟停止时更改。如果SCR[0]0此位有效。0为DMA模式0无DMA1为DMA模式1使用特定的DMA请求信号。启用DMA可以进一步解放CPU让数据在内存和UART FIFO之间直接搬运。Bit 5-4 - TX_FIFO_TRIG发送FIFO触发水平。仅在EFR[4]1时可写。它定义了在DMA模式或中断模式下发送FIFO在什么情况下产生DMA请求或THR中断当FIFO数据量低于此阈值时。具体阈值取决于SCR[6]和TLR[3:0]的配置是一个多层选择逻辑详见表24-29。Bit 7-6 - RX_FIFO_TRIG接收FIFO触发水平。定义了接收FIFO在达到多少字节时产生RHR中断或DMA请求。其配置逻辑与TX_FIFO_TRIG类似取决于SCR[7]和TLR[7:4]详见表24-28。FIFO触发水平配置逻辑详解 手册表24-28和24-29的描述初看复杂实则是一个灵活的优先级配系统。以接收FIFO触发水平RX_FIFO_TRIG为例如果SCR[7] 0 且 TLR[7:4] ≠ 0000触发水平由TLR[7:4]单独决定范围为4到60字节步进为4字节。此时FCR[7:6]被忽略。如果SCR[7] 1触发水平由TLR[7:4]和FCR[7:6]拼接成一个6位的值决定TLR[7:4]为高4位FCR[7:6]为低2位范围为1到63字节步进为1字节。这提供了最精细的控制。如果SCR[7] 0 且 TLR[7:4] 0000触发水平由FCR[7:6]决定有四个固定档位00b对应8字符01b对应16字符10b对应56字符11b对应60字符。这种设计允许开发者根据系统中断响应时间、数据包大小和CPU负载在灵活性1字节步进和配置简便性4个预设档位之间做出选择。对于发送FIFO触发水平TX_FIFO_TRIG逻辑完全对称只是相关的控制位是SCR[6]和TLR[3:0]。4.2 触发水平寄存器TLR与传输控制寄存器TCRTLRTrigger Level Register和TCRTransmission Control Register提供了更高级的FIFO和流控制功能。TLR寄存器图24-45直接存储了用于DMA和中断生成的收发FIFO触发水平值。它分为高4位RX_FIFO_TRIG_DMA和低4位TX_FIFO_TRIG_DMA分别对应接收和发送。如前所述它们的实际作用与SCR寄存器的设置紧密相关。TLR的价值在于当SCR相应位为1时它与FCR中的2位组合能实现1字节步进的精细控制当SCR为0且TLR非零时它能提供4字节步进的中等粒度控制。TCR寄存器图24-43专门用于硬件流控制如自动RTS/CTS。它定义了接收FIFO的“水位线”Bit 3-0 - RXFIFOTRIGHALT接收FIFO触发水平用于停止传输。当接收FIFO中的数据量达到或超过此阈值时如果使能了自动RTSUART会拉高RTS信号变为无效通知对端停止发送。Bit 7-4 - RXFIFOTRIGSTART接收FIFO触发水平用于恢复传输。当接收FIFO中的数据被CPU读走存量低于此阈值时UART会拉低RTS信号变为有效通知对端可以恢复发送。手册中的关键警告必须确保TCR[3:0] TCR[7:4]即停止传输的水位线必须高于恢复传输的水位线形成一个“滞回区间”。这是为了防止RTS信号在临界点附近频繁跳变导致通信不稳定。例如设置RXFIFOTRIGHALT48当FIFO数据48字节时请求暂停RXFIFOTRIGSTART16当FIFO数据16字节时恢复。这样只有当FIFO从48字节以上被消耗到16字节以下时才会恢复通信避免了在48字节附近震荡。5. 通信参数与状态监控LCR、LSR与MSR寄存器5.1 线路控制寄存器LCR定义通信协议LCRLine Control Register决定了UART通信的“语言规则”即一帧数据的具体格式。所有通信双方必须使用相同的LCR设置。Bit 1-0 - CHAR_LENGTH字符长度。005位016位107位118位。最常用的是8位数据11。Bit 2 - NB_STOP停止位数量。01个停止位适用于5-8位字长。1如果字长为5位则为1.5个停止位如果字长为6、7、8位则为2个停止位。绝大多数应用使用1个停止位0。Bit 3 - PARITY_EN奇偶校验使能。0无校验1使能校验位生成和检查。Bit 4 - PARITY_TYPE1与Bit 5 - PARITY_TYPE2共同定义校验类型。当PARITY_EN1时如果PARITY_TYPE20则PARITY_TYPE1选择奇偶性0奇校验1偶校验。如果PARITY_TYPE21则为强制校验模式PARITY_TYPE10则强制校验位为1PARITY_TYPE11则强制校验位为0。此模式较少使用。Bit 6 - BREAK_EN间断控制位。这是一个需要谨慎使用的功能。当此位置1时TX线路会被强制拉低逻辑0并持续保持直到此位被清零。这用于向对端发送一个“间断”信号通常表示通信中断或作为特定协议的帧起始/结束标志。手册特别用Note强调“As soon as LCR[6] is set to 1, the TX line is forced to 0 and remains in this state as long as LCR[6] 1.” 编程时务必控制好置位时间通常是一个字符帧的时间长度。Bit 7 - DIV_EN分频器锁存使能位。这是一个特殊功能位。当需要设置波特率时我们必须先写LCR将DIV_EN置1这样才能访问DLL波特率低分频锁存器和DLH波特率高分频锁存器进行波特率设置。设置完成后通常需要将DIV_EN清零以恢复正常操作访问RHR、THR等数据寄存器。LCR配置示例8位数据1位停止无校验// 设置通信格式8位数据1停止位无校验 *(uart_base LCR_OFFSET) 0x03; // 二进制 0000 0011 CHAR_LENGTH11, 其他位为0 // 如果需要设置波特率先置位DIV_EN // *(uart_base LCR_OFFSET) | (1 7); // 设置DIV_EN1 // ... 然后写入DLL和DLH ... // *(uart_base LCR_OFFSET) ~(1 7); // 清除DIV_EN恢复正常模式5.2 线路状态寄存器LSR实时通信健康仪表盘LSRLine Status Register是一个只读寄存器提供了数据收发状态和错误信息的实时快照。它是诊断通信问题最重要的工具。UART模式的LSR图24-39各位含义如下Bit 0 - RXFIFOE接收FIFO空。0FIFO中有数据1FIFO空。这是轮询方式接收数据时最常查询的位。Bit 1 - RXOE接收溢出错误。1表示发生溢出。当接收移位寄存器中的数据已准备好但接收FIFO已满无法存入时此位置1并且移位寄存器中的数据会丢失。此位在读LSR时被清除。Bit 2 - RXPE接收奇偶校验错误。1表示当前位于RX FIFO顶部的字符即下一个将被RHR读出的字符存在奇偶校验错误。Bit 3 - RXFE接收帧错误。1表示当前位于RX FIFO顶部的字符存在帧错误如缺少有效的停止位。Bit 4 - RXBI接收间断指示。1表示检测到线路间断RX线被拉低超过一个完整字符帧的时间。Bit 5 - TXFIFOE发送FIFO空。0发送FIFO非空1发送FIFO空。注意此位为1仅表示FIFO空但发送移位寄存器可能还在发送最后一个字节。Bit 6 - TXSRE发送移位寄存器空。0发送移位寄存器非空1发送移位寄存器和发送FIFO都为空。此位为1才表示所有数据已物理发送完毕。Bit 7 - RXFIFOSTS接收FIFO错误状态。1表示接收FIFO中至少存在一个带有错误PE、FE或BI的字符。只有当FIFO中所有错误字符都被读取后此位才会清零。LSR使用要点错误位关联性Bit 2, 3, 4 (RXPE, RXFE, RXBI) 反映的是下一次通过RHR读取的那个字符的错误状态。读取RHR后这些错误状态会更新为FIFO中下一个字符的状态。错误清除读取LSR寄存器会清除Bit 1 (RXOE)。而Bit 2,3,4的错误状态在读取对应的错误字符通过RHR后更新。Bit 7 (RXFIFOSTS) 在FIFO中所有错误字符被读走后清零。发送完成判断如果需要确保所有数据包括在移位寄存器中的都已发出应查询TXSRE位Bit 6而不是TXFIFOE位Bit 5。5.3 调制解调器状态寄存器MSRMSRModem Status Register用于监控和响应UART与外部设备如传统调制解调器之间的硬件控制信号DCD, RI, DSR, CTS。在现代嵌入式系统中这些引脚常被复用为硬件流控制RTS/CTS或通用IO。Bit 0 - CTS_STSCTS状态变化。1表示CTS输入引脚的状态发生了变化从高到低或从低到高。读MSR后清零。Bit 1 - DSR_STSDSR状态变化。Bit 2 - RI_STSRI状态变化从低到高即上升沿。Bit 3 - DCD_STSDCD状态变化。Bit 4 - NCTS_STSCTS输入信号的反相值。即NCTS_STS !CTS。Bit 5 - NDSR_STSDSR输入信号的反相值。Bit 6 - NRI_STSRI输入信号的反相值。Bit 7 - NCD_STSDCD输入信号的反相值。Bit 4-7提供了信号的瞬时电平而Bit 0-3提供了信号的变化事件。在硬件流控制中我们通常更关心CTS的瞬时电平Bit 4来判断是否允许发送同时也可以通过使能IER中的CTSIT中断在CTS变化时得到通知。在环回测试模式MCR[4]1下这些位反映的是MCR[3:0]循环回来的值用于自检。6. 模式配置与高级功能MDR1、MDR2及其他寄存器6.1 模式定义寄存器MDR1与MDR2MDR1Mode Definition Register 1是决定UART工作模式的核心寄存器。其最低3位MODESELECTBit 2-0必须在初始化时配置且在正常操作中不应更改。0: UART 16x模式标准模式使用16倍波特率时钟采样。1: SIR模式IrDA最高115.2kbps。2h: UART 16x自动波特率检测模式。3h: UART 13x模式某些老式设备兼容。4h: MIR模式IrDA0.576-1.152Mbps。5h: FIR模式IrDA最高4Mbps。6h: CIR模式消费电子红外遥控。7h: 禁用模块默认状态。注意手册提到即使模块被禁用如果IER中使能了中断UART模式的中断仍然可能产生。这需要在软件设计中考虑。MDR1的其他位用于IrDA/CIR模式下的特定功能如帧结束模式、SIP串行红外脉冲模式、红外睡眠模式等。MDR2Mode Definition Register 2提供了一些额外的配置Bit 0 - IRTXUNDERRUNIrDA发送欠载状态位。当发生TX状态中断IIR[5]时读取此位可判断是正常发送完成0还是发生了欠载错误1。Bit 2-1 - STSFIFOTRIG仅IrDA模式有效设置帧状态FIFO的触发阈值。Bit 6 - IRRXINVERT红外接收引脚反相控制。因为大多数红外收发器会对信号反相此位默认0执行反相以确保模块级逻辑正确。6.2 其他关键寄存器SCRScratchpad Register这是一个通用的8位读/写寄存器不控制任何硬件功能。驱动程序可以用它来存储临时变量或作为软件标志在需要与UART硬件紧密耦合的代码中提供便利。MCRModem Control Register用于控制输出到调制解调器的信号DTR, RTS以及启用环回测试模式LOOPBACKEN。环回模式对于驱动自检和硬件调试极其有用它将TX输出内部连接到RX输入并将MCR的输出信号循环到MSR的输入状态位。DLL/DLHDivisor Latch波特率分频器。波特率 输入时钟频率 / (16 * 分频值)。分频值 DLH 8 | DLL。设置它们前必须将LCR的DIV_EN位置1。7. 寄存器编程实战与避坑指南7.1 UART初始化标准流程一个健壮的UART初始化应遵循以下步骤特别是对于支持FIFO和多种模式的复杂UART关闭中断向IER寄存器写入0禁用所有中断源。复位并清空FIFO向FCR寄存器写入0x07Bit2,1,0为1这将清空TX和RX FIFO并暂时禁用FIFO如果之前使能了。注意FIFO_EN的最终设置可能要在后面。设置波特率 a. 写LCR将DIV_EN位置1解锁DLL/DLH。 b. 根据输入时钟和期望波特率计算分频值写入DLL和DLH。 c. 写LCR清除DIV_EN位恢复对数据/控制寄存器的访问。设置通信格式写LCR配置数据位、停止位、校验位。配置FIFO和触发水平 a. 如果需要使用高级功能如可编程触发水平、DMA模式可能需要先写EFR解锁如果芯片支持。 b. 根据SCR、TLR、FCR的联动关系配置所需的RX/TX FIFO触发水平。 c. 向FCR写入最终值使能FIFOBit 0 1并设置好触发水平位。设置工作模式向MDR1写入目标模式值如0x00 for UART 16x。配置调制解调器控制向MCR写入所需值如使能RTS如果用于硬件流控。使能中断最后向IER写入需要的中断使能位。这确保了在硬件完全初始化好之前不会产生意外中断。7.2 常见问题排查与调试技巧收不到数据中断方式检查IER确认RHRITBit 0是否已使能。检查IIR在中断服务程序中首先读取IIR确认IT_PENDING位为0且有中断挂起并检查IT_TYPE字段是否为2RHR中断或6超时中断。检查LSR读取LSR确认RXFIFOE位为0有数据并检查RXOE、RXPE、RXFE、RXBI等错误位。检查FIFO触发水平如果一直不中断可能是触发水平设置过高例如设置为56而发送方每次只发几个字节。可以尝试降低RX_FIFO_TRIG水平或使用接收超时中断。发送数据卡住或丢失检查LSR发送前检查TXFIFOE位确保FIFO未满。发送完成后检查TXSRE位确认所有数据已移出。检查硬件流控如果使用了CTS/RTS检查MSR的NCTS_STS位确认CTS信号是否有效低电平允许发送。检查MCR的RTS位输出是否正确。检查THR写入时机在中断驱动发送中确保只在THR中断THRIT触发或明确查询到TXFIFOE为空时才写入THR。盲目写入会导致数据覆盖。通信数据错误乱码核对LCR确保通信双方的数据位、停止位、校验位设置完全一致。这是最常见的原因。检查波特率计算分频值是否正确输入时钟频率是否准确。可以使用示波器测量TX引脚上一个位的实际时长来反推实际波特率。检查LSR错误位定期读取LSR检查RXPE、RXFE、RXBI位。奇偶校验错或帧错误直接指向物理层问题干扰、电平不匹配、波特率偏差。启用环回测试将MCR的LOOPBACKEN位置1然后自发自收。如果环回模式下数据正确则问题很可能在外部线路或对端设备上。中断无法触发或触发过于频繁确认IIR和IER的匹配记住IIR只反映IER中已使能的中断源。如果一个中断在IER中未使能即使硬件事件发生IIR也不会显示CPU也不会收到中断请求。理解中断清除机制RHR中断读取RHR数据当FIFO数据量低于触发水平时中断条件消失。THR中断向THR写入数据当FIFO数据量超过触发水平时中断条件消失。线路状态中断读取LSR寄存器会自动清除OE错误位但PE、FE、BI错误位在对应的错误字符被从RHR读出后才更新。Modem状态中断读取MSR寄存器会清除Bit 0-3的变化标志位。中断风暴如果接收FIFO触发水平设置为1且数据持续高速涌入可能会造成频繁中断。可以考虑提高触发水平或使用DMA进行数据搬运。寄存器操作原子性在对多位寄存器如LCR、IER进行部分位修改时应采用“读-修改-写”操作避免影响其他位。例如要使能RHR中断而不影响其他位uint8_t ier_value *(uart_base IER_OFFSET); ier_value | (1 0); // 设置Bit 0 (RHRIT) 为1 *(uart_base IER_OFFSET) ier_value;深入理解UART寄存器意味着你掌握了与这个硬件模块直接对话的能力。从配置通信格式、管理数据缓冲到处理各种异步事件和错误每一个细节都体现在对这些寄存器的精准操控上。这份手册提供的位域描述是通用的蓝图具体到不同的芯片平台寄存器的内存映射地址、某些特殊功能位的支持情况可能会有所不同但核心想和处理流程是相通的。在实际项目中结合具体的芯片参考手册灵活运用这些寄存器知识是构建稳定、高效串口通信底层驱动的基石。