UART寄存器深度解析:中断、流控与FIFO配置实战指南

📅 2026/7/20 17:21:52
UART寄存器深度解析:中断、流控与FIFO配置实战指南
1. 项目概述与核心价值如果你在嵌入式开发中用过UART大概率是从某个现成的驱动库或者HAL库开始的比如STM32的HAL_UART_Transmit()。这很方便但当你需要实现一个高可靠、高效率的串口通信或者遇到一些奇怪的通信丢帧、中断不触发问题时仅仅调用库函数就显得力不从心了。这时候你必须深入到寄存器层面理解UART这个“黑盒”内部到底是如何工作的。寄存器配置是串口通信的“底层语言”它直接决定了硬件的每一个行为。本文将以德州仪器TI某款典型UART外设的寄存器手册为蓝本深入解析中断、流控与FIFO配置这三个最核心也最易出错的环节。我不会只翻译手册而是结合我十多年在工业控制和通信模块开发中踩过的坑告诉你每个寄存器位背后的设计逻辑、配置时的“潜规则”以及如何通过组合配置实现稳定可靠的通信。无论你是正在调试一个115200bps的传感器数据采集还是设计一个需要硬件流控的可靠数传链路理解这些寄存器细节都能让你从“会用”进阶到“精通”。2. UART寄存器全景与访问模式解析在深入具体寄存器之前我们必须建立一个全局视图。UART的寄存器组是一个地址映射的集合CPU通过读写这些特定地址来控制UART外设的所有行为。手册中反复出现的“Refer to Section 21.3.7.1 to determine the modes...”这句话是关键前提它指明了寄存器访问存在模式依赖。2.1 寄存器访问模式与“钥匙”机制许多增强型UART如本文所述的型号支持多种工作模式例如标准UART模式、IrDA红外模式、CIR消费红外模式等。不同模式下同一物理地址可能映射到功能完全不同的寄存器。Section 21.3.7.1通常定义了模式选择寄存器如UART_MDR在配置任何功能前必须先确认并设置正确的工作模式。更关键的一点是增强功能写使能锁。细心的你会发现在IER中断使能寄存器、EFR增强功能寄存器、FCRFIFO控制寄存器和MCR调制解调器控制寄存器的描述中频繁出现“Can be written only when EFR[4] 1”。EFR[4]这个位名为ENHANCEDEN它就是一把“钥匙”。设计逻辑解析为什么需要这样一把“钥匙”这主要是出于系统安全性和可靠性的考虑。像中断使能的高位CTS、RTS、XOFF中断等、FIFO触发阈值、以及MCR中的一些高级控制位一旦误写可能导致通信异常甚至死锁。将这些关键配置位“锁”起来要求程序员必须先显式地“解锁”设置EFR[4]1才能修改相当于增加了一道保险。这要求我们的初始化序列必须是配置基本参数如波特率、数据格式。使能增强功能访问EFR[4] 1。配置高级功能流控、高级中断、FIFO阈值。可选关闭增强功能访问锁防止后续代码误操作。2.2 核心寄存器功能分类根据功能我们可以将UART寄存器分为以下几大类这有助于我们理解配置时的先后依赖关系寄存器类别主要寄存器核心功能配置依赖控制与状态LCR(线路控制寄存器)设置数据格式字长、停止位、奇偶校验、访问波特率分频器。无MCR(调制解调器控制寄存器)控制RTS、DTR等输出信号启用环回测试模式。EFR[4]用于写MCR[7:5]LSR(线路状态寄存器)只读。反映TX/RX状态、错误帧错误、奇偶错误、溢出等。无MSR(调制解调器状态寄存器)只读。反映CTS、DSR、RI、DCD等输入信号的状态及变化。无通信参数DLL/DLH(分频器锁存器)共同组成波特率发生器分频值。计算公式DLL/DLH 时钟频率 / (16 * 波特率)。需先设置LCR[7]1DIV_EN中断管理IER(中断使能寄存器)使能或禁用各类中断源接收、发送、错误、Modem状态等。EFR[4]用于写IER[7:4]IIR(中断标识寄存器)只读。当多个中断发生时指示当前最高优先级的中断源并可通过读取该寄存器清除中断挂起状态。无流量控制EFR(增强功能寄存器)总开关启用自动硬件流控Auto CTS/RTS、软件流控、特殊字符检测。其ENHANCEDEN位是其他高级功能的钥匙TCR(传输控制寄存器)定义硬件流控的“HALT”和“RESTORE”触发阈值。需EFR[4]1且MCR[6]1XON1/XON2/XOFF1/XOFF2存储软件流控的启/停字符。无数据缓冲FCR(FIFO控制寄存器)启用/禁用FIFO设置TX/RX FIFO触发阈值清除FIFO。EFR[4]用于写FCR[5:4]TX触发阈值杂项SPR(便签寄存器)一个通用的8位读/写寄存器用于临时存储数据不影响UART功能。无这个分类表是你进行UART驱动开发的“地图”。在初始化时你必须遵循一个合理的顺序先设置通信基本参数LCR,DLL/DLH再打开“钥匙”EFR[4]接着配置高级功能和中断IER,FCR,EFR其他位TCR最后才使能中断并开始数据传输。3. 中断系统深度配置与实战策略中断是UART高效工作的核心机制它让CPU从轮询LSR状态的苦力中解放出来。TI这款UART的中断系统设计得相当精细但也因此容易配置不当。3.1 IER中断使能寄存器的位级解读IER寄存器是中断系统的总开关。手册列出了7种中断类型但实际位分布需要仔细对照位名称功能描述使能条件与注意事项0RHRIT接收器保持寄存器中断。当RX FIFO中的数据量达到触发阈值由FCR[7:6]或TLR设定时产生。这是最常用、最高效的接收数据方式。通常必须使能。注意它同时使能了“超时中断”Timeout Interrupt。1THRIT发送器保持寄存器中断。当TX FIFO中的数据量低于触发阈值由FCR[5:4]设定时产生。用于在发送缓冲区有空闲时通知CPU填入新数据。在需要连续发送大量数据时使能以实现“填鸭式”发送。2LINESTSIT接收线路状态中断。当发生帧错误(FE)、奇偶错误(PE)、溢出错误(OE)或间隔中断(BI)时触发。这是一个错误中断集合。强烈建议使能。这是你发现物理层通信问题如波特率不匹配、线路干扰的主要途径。3MODEMSTSIT调制解调器状态中断。当CTS、DSR、RI或DCD信号状态发生变化时触发。在需要监控Modem信号如检测对方设备上线、挂断时使能。4SLEEPMODE睡眠模式。置1时当UART模块空闲无活动时停止波特率时钟以省电。注意此模式下无法写入DLL/DLH。修改波特率前需先禁用睡眠模式。5XOFFITXOFF中断。当接收到软件流控停止字符XOFF时触发。仅在启用软件流控通过EFR[3:0]配置后有意义。6RTSITRTS中断。当RTS引脚状态从低变高有效变无效时触发。用于监控硬件流控中对方是否准备好接收。需EFR[4]1才能写。7CTSITCTS中断。当CTS引脚状态从低变高有效变无效时触发。用于监控硬件流控中对方是否允许发送。需EFR[4]1才能写。配置心得对于大多数应用我的基础配置是IER 0x07即RHRIT、THRIT、LINESTSIT使能。这覆盖了数据收发和错误处理。只有在明确需要硬件流控状态监控或软件流控时才会在解锁后配置IER[7:4]。3.2 IIR中断标识与优先级处理实战IIR是一个只读寄存器它是中断服务程序ISR的“导航仪”。它的核心作用是当多个中断条件同时满足时告诉你当前哪个是最高优先级的待处理中断。读取IIR本身会清除中断挂起标志IT_PENDING位变为1但不会清除导致中断的硬件状态例如读IIR不会清空RX FIFO。IIR[5:1]的IT_TYPE字段定义了中断类型和优先级IT_TYPE值中断源优先级中断服务程序ISR中需要执行的操作0x06接收超时2读取RHR直到RX FIFO为空。超时中断与RHRIT共享使能位(IER[0])当FIFO中有数据但未达到触发阈值且一段时间无新数据时触发用于处理“零碎”数据。0x04RHR中断(数据就绪)2读取RHR直到读取的数据量达到或超过FIFO触发阈值或FIFO为空。0x02THR中断(发送寄存器空)3向THR写入新的待发送数据直到TX FIFO填满或数据发送完毕。0x00Modem状态中断4读取MSR寄存器该操作会自动清除MSR[3:0]的状态变化标志。0x01接收线路状态中断(错误)1 (最高)立即读取LSR寄存器。根据LSR[4:2]判断具体错误类型BI, FE, PE并执行错误处理如丢弃错误数据、记录日志、重置接收状态。这是一个关键步骤不读LSR错误标志可能无法清除。0x07XOFF/特殊字符中断5读取IIR和LSR确认并根据软件流控逻辑暂停发送。0x10CTS/RTS/DSR变化中断6读取MSR寄存器获取具体哪个信号发生了变化。中断服务程序ISR的标准处理流程 这是一个经过大量项目验证的稳健处理流程void UART_ISR(void) { uint16_t iir_value; do { iir_value READ_REG(UART_IIR); // 检查是否有中断挂起 (bit 0 0 表示有中断) if (iir_value 0x01) { break; // 无中断挂起退出循环 } switch ((iir_value 1) 0x0F) { // 提取IT_TYPE字段 case 0x06: // 接收超时中断 (优先级2) case 0x04: // RHR数据就绪中断 (优先级2) handle_rx_data(); break; case 0x02: // THR发送空中断 (优先级3) handle_tx_empty(); break; case 0x00: // Modem状态变化中断 (优先级4) handle_modem_status(); break; case 0x01: // 接收线路错误中断 (优先级1 - 最高) handle_line_error(); break; case 0x07: // XOFF/特殊字符中断 (优先级5) handle_xoff(); break; case 0x10: // CTS/RTS/DSR变化中断 (优先级6) handle_cts_rts_change(); break; default: // 未知中断类型可能是保留值读取LSR/MSR进行清理 READ_REG(UART_LSR); READ_REG(UART_MSR); break; } } while (1); // 循环处理直到IIR显示无中断挂起 }关键技巧使用do...while循环处理IIR是必须的。因为在高数据速率下可能在处理一个中断的过程中又产生了新的中断例如正在读取RX FIFO时又收到了新数据。循环能确保在一次ISR调用中处理完所有累积的中断事件避免频繁进出ISR带来的性能开销。4. 流量控制机制详解与配置指南流量控制是保证数据可靠传输防止缓冲区溢出的关键。TI UART支持硬件流控RTS/CTS和软件流控XON/XOFF两者可以独立或组合使用。4.1 硬件流控Auto CTS与Auto RTS硬件流控通过额外的两根信号线RTS, CTS实现实时握手。RTS (Request To Send)输出信号本设备通知对方“我准备好接收了”。CTS (Clear To Send)输入信号本设备检测对方是否“允许我发送”。自动流控意味着UART硬件会自动根据FIFO状态管理这些引脚无需CPU干预。4.1.1 Auto CTS自动清除发送功能使能后EFR[7] 1UART在发送数据前会检查CTS引脚的电平。逻辑只有当CTS引脚为低电平有效时UART才会从TX FIFO中取出数据发送。如果CTS变为高电平无效UART会立即停止发送当前字节完成当前字节后停止直到CTS再次变低。应用场景控制本设备的发送。当对方设备接收缓冲区快满时拉高CTS本设备自动暂停发送防止对方溢出。配置步骤确保EFR[4]1解锁。设置EFR[7]1使能Auto CTS。可选使能IER[7]CTSIT以便在CTS状态变化时产生中断用于监控链路状态。4.1.2 Auto RTS自动请求发送功能使能后EFR[6] 1UART会根据自身RX FIFO的填充情况自动控制RTS引脚的输出电平。逻辑依赖于TCR寄存器传输控制寄存器的两个阈值TCR[3:0](RXFIFOTRIGHALT)HALT阈值。当本设备RX FIFO中的数据量达到或超过此值时UART自动将RTS引脚拉高无效通知对方“暂停发送”。TCR[7:4](RXFIFOTRIGSTART)RESTORE阈值。当本设备RX FIFO中的数据量低于或等于此值时因为被CPU读走UART自动将RTS引脚拉低有效通知对方“可以继续发送”。关键约束手册明确警告必须确保TCR[3:0] TCR[7:4]。即HALT阈值必须大于RESTORE阈值形成一个“滞回区间”防止RTS引脚在临界点附近频繁跳变造成系统振荡。应用场景控制对方设备的发送。保护本设备的接收缓冲区不被冲垮。配置步骤确保EFR[4]1且MCR[6]1解锁TCR。配置TCR寄存器设定合理的HALT和RESTORE阈值。例如对于64字节的RX FIFO可设置TCR[3:0] 0x8(HALT at 32 bytes)TCR[7:4] 0x4(RESTORE at 16 bytes)。设置EFR[6]1使能Auto RTS。可选使能IER[6]RTSIT用于监控。硬件流控配置示例 假设我们使用64字节FIFO希望在本机接收缓冲区达到48字节时让对方暂停降到16字节时再恢复。// 1. 解锁增强功能 WRITE_REG(UART_EFR, READ_REG(UART_EFR) | (1 4)); // Set ENHANCEDEN // 2. 配置TCR寄存器 (需同时设置MCR[6]) WRITE_REG(UART_MCR, READ_REG(UART_MCR) | (1 6)); // Set TCRTLR to access TCR // HALT Level 48 bytes - 48/4 12 0xC // RESTORE Level 16 bytes - 16/4 4 0x4 // TCR (RESTORE 4) | HALT (0x4 4) | 0xC 0x4C WRITE_REG(UART_TCR, 0x4C); // 3. 使能Auto RTS和Auto CTS uint16_t efr_value READ_REG(UART_EFR); efr_value | (1 7); // Enable AUTOCTSEN efr_value | (1 6); // Enable AUTORTSEN WRITE_REG(UART_EFR, efr_value); // 4. 可选使能CTS和RTS状态变化中断 WRITE_REG(UART_IER, READ_REG(UART_IER) | (1 7) | (1 6));4.2 软件流控XON/XOFF配置软件流控通过在线路上插入特殊的控制字符XON, XOFF来实现流量控制无需额外的硬件连线。TI UART的软件流控功能通过EFR[3:0](SWFLOWCTRL) 位进行精细配置。4.2.1 控制字符XON(Transmit On)通常为0x11 (DC1)通知对方开始发送。XOFF(Transmit Off)通常为0x13 (DC3)通知对方停止发送。XON1/XON2, XOFF1/XOFF2该UART支持两组字符提供更强的协议兼容性或冗余。4.2.2 发送流控与接收流控SWFLOWCTRL的4个位独立控制发送和接收行为位[3:2] 控制发送流控本设备发送XON/XOFF00: 不发送流控字符。01: 发送XON1/XOFF1对。10: 发送XON2/XOFF2对。11: 发送XON1/XON2或XOFF1/XOFF2对需成对顺序发送。位[1:0] 控制接收流控本设备识别并响应XON/XOFF00: 不识别流控字符。01: 识别并响应XON1/XOFF1。10: 识别并响应XON2/XOFF2。11: 识别并响应XON1/XON2或XOFF1/XOFF2对。4.2.3 特殊字符检测EFR[5](SPECIALCHARDETECT) 位启用特殊字符检测功能。当使能时接收到的数据会与XOFF2寄存器中的值进行比较。如果匹配数据会被正常存入RX FIFO同时IIR[4]位会被置1并产生一个“XOFF/特殊字符中断”IIR类型为0x07。这可以用于实现自定义的带内协议控制命令。软件流控配置示例 配置UART使用XON1/XOFF10x11/0x13进行双向软件流控。// 1. 解锁增强功能 WRITE_REG(UART_EFR, READ_REG(UART_EFR) | (1 4)); // ENHANCEDEN // 2. 设置XON1和XOFF1字符 WRITE_REG(UART_XON1_ADDR1, 0x11); // XON1 0x11 WRITE_REG(UART_XOFF1, 0x13); // XOFF1 0x13 // 注意手册建议如果使能软件流控XON1和XOFF1应设为不同值。 // 3. 配置软件流控模式 // 目标EFR[3:0] 0b1111即发送和接收都使用XON1/XOFF1对。 // 发送控制(EFR[3:2]) 0b01 (发送XON1/XOFF1) // 接收控制(EFR[1:0]) 0b01 (识别XON1/XOFF1) uint16_t efr_value READ_REG(UART_EFR); efr_value ~(0xF); // 清零低4位 efr_value | (1 3) | (1 2) | (1 1) | (1 0); // 设置为0b1111但根据手册描述组合逻辑并非简单相加。 // 更安全的做法是根据手册Table 21-37的位定义单独设置 efr_value | (1 3); // 使能发送XON1/XOFF1 // efr_value | (1 2); // 如果设为1则变为发送XON2/XOFF2这里我们不需要。 efr_value | (1 1); // 使能接收XON1/XOFF1 // efr_value | (1 0); // 如果设为1则变为接收XON2/XOFF2这里我们不需要。 // 根据表格要使用XON1/XOFF1对应设置EFR[3]1, EFR[2]0, EFR[1]1, EFR[0]0。 efr_value (efr_value ~0xF) | (13) | (11); // 即0b1010 0xA WRITE_REG(UART_EFR, efr_value); // 4. 可选使能XOFF中断以便及时响应停止请求 WRITE_REG(UART_IER, READ_REG(UART_IER) | (1 5)); // Enable XOFFIT5. FIFO配置与性能优化实战FIFO先进先出缓冲区是提升UART吞吐率、降低CPU中断负载的核心。TI UART提供64字节的TX/RX FIFO但其触发阈值的配置颇有讲究。5.1 FCRFIFO控制寄存器详解FCR是一个只写寄存器Write-only用于控制FIFO的使能、清除和触发阈值。位名称功能描述配置要点与陷阱0FIFO_ENFIFO使能位。0禁用使用1字节缓冲1启用64字节FIFO。关键限制只能在波特率时钟停止时即DLL和DLH都为0修改。这意味着必须在初始化UART、设置波特率之前就配置好FIFO。1RX_FIFO_CLR接收FIFO清除位。写1清除RX FIFO和其计数器该位会自动清零。在通信开始前或发生错误需要清空缓冲区时使用。写入后应延时几个时钟周期再操作FIFO。2TX_FIFO_CLR发送FIFO清除位。写1清除TX FIFO和其计数器该位会自动清零。同上。注意清除TX FIFO会丢弃其中所有未发送的数据。3DMA_MODEDMA模式选择。0无DMA1模式1TX和RX使用独立的DMA请求。同样需在波特率时钟停止时修改。选择DMA模式后FIFO触发阈值将用于产生DMA请求。[5:4]TX_FIFO_TRIGTX FIFO触发阈值。决定TX FIFO空到什么程度时产生THRIT中断或DMA请求。依赖EFR[4]。阈值选择见下表。[7:6]RX_FIFO_TRIGRX FIFO触发阈值。决定RX FIFO收到多少数据时产生RHRIT中断或DMA请求。阈值选择见下表。注意与TCR中硬件流控阈值的协调。5.2 FIFO触发阈值的选择策略FCR[7:6]和FCR[5:4]的阈值选择逻辑受SCR附加控制寄存器和TLR触发水平寄存器影响但最常见的情况是SCR[7]0且TLR相关位为0此时使用固定的几档阈值。RX FIFO触发阈值 (FCR[7:6])00: 8 字符01: 16 字符10: 56 字符11: 60 字符TX FIFO触发阈值 (FCR[5:4])00: 8 字符01: 16 字符10: 32 字符11: 56 字符选择策略与性能权衡高吞吐、低延迟场景如高速数据日志设置较低的触发阈值如RX8TX8。这会让中断更频繁但能确保数据被及时处理减少端到端延迟。适合CPU负载不重或使用DMA的情况。低功耗、减少中断场景如电池供电设备设置较高的触发阈值如RX56TX32。这减少了中断次数让CPU有更多时间进入睡眠模式但代价是单次中断处理的数据量变大可能增加软件复杂度并引入更大的传输延迟。与硬件流控的协同RX_FIFO_TRIG中断触发和TCR中的RXFIFOTRIGHALT硬件流控RTS触发是两个独立的阈值。通常为了让流控能提前动作防止FIFO溢出应设置RXFIFOTRIGHALTRX_FIFO_TRIG。例如RX FIFO深度64你可以设置TCR HALT 48字节对方在收到48字节时暂停FCR RX Trigger 56字节本机在收到56字节时产生中断这样在FIFO达到48字节时RTS变高通知对方暂停为本机CPU争取了时间在FIFO达到56字节产生中断前进行处理提供了安全裕量。DMA模式下的配置在DMA模式下触发阈值决定了DMA请求的产生时机。通常将TX/RX FIFO触发阈值设置为DMA突发传输长度的一半或四分之一以实现DMA和FIFO的流水线操作最大化总线效率。FIFO初始化配置示例// UART初始化序列的一部分在设置波特率之前 void UART_FIFO_Init(void) { // 1. 确保波特率分频器为0停止波特率时钟 // 通常通过设置LCR[7]1来访问DLL/DLH然后将其清零 uint16_t lcr_backup READ_REG(UART_LCR); WRITE_REG(UART_LCR, lcr_backup | (1 7)); // 设置DIV_EN访问分频器 WRITE_REG(UART_DLL, 0x00); WRITE_REG(UART_DLH, 0x00); WRITE_REG(UART_LCR, lcr_backup); // 恢复LCR退出分频器访问模式 // 2. 配置FCR使能FIFO设置触发阈值并清除FIFO uint16_t fcr_value 0; fcr_value | (1 0); // FIFO_EN 1 fcr_value | (1 1); // RX_FIFO_CLR 1 (清除RX) fcr_value | (1 2); // TX_FIFO_CLR 1 (清除TX) fcr_value | (0x01 6); // RX_FIFO_TRIG 01 (16字节触发) // TX_FIFO_TRIG 需要EFR[4]1才能写我们稍后配置 WRITE_REG(UART_FCR, fcr_value); // 3. 后续解锁增强功能后配置TX触发阈值 // WRITE_REG(UART_EFR, READ_REG(UART_EFR) | (1 4)); // ENHANCEDEN // fcr_value READ_REG(UART_FCR); // 注意FCR是只写的不能回读。需要重新构建值或使用变量保存。 // fcr_value | (0x01 4); // TX_FIFO_TRIG 01 (16字节触发) // WRITE_REG(UART_FCR, fcr_value); // 4. 重新配置正确的波特率设DLL/DLH // ... 波特率计算与设置代码 ... }严重警告FIFO_EN、DMA_MODE等位的修改必须在波特率时钟停止时进行。一个常见的错误流程是先设置好波特率然后尝试使能FIFO结果导致FIFO无法正常工作或通信乱码。正确的顺序永远是停止时钟 - 配置FIFO/DMA - 设置波特率 - 开始通信。6. 典型问题排查与调试技巧即使按照手册配置在实际项目中仍会遇到各种问题。以下是我总结的几个典型场景和排查思路。6.1 中断不触发或触发异常症状数据已收到用示波器或逻辑分析仪确认但RHRIT中断始终不产生。排查步骤检查IER配置确认IER[0](RHRIT) 已置1。别忘了IER[7:4]需要EFR[4]1才能写入。检查FIFO使能与触发阈值确认FCR[0]1FIFO使能。检查FCR[7:6]的RX触发阈值是否设置合理。如果阈值设为56而你只发送了10个字节中断自然不会产生。检查IIR状态在ISR中或主循环里读取IIR寄存器。如果IIR[0]0且IT_TYPE字段是0x04或0x06说明中断已产生但可能被更高优先级中断抢占或标志位处理不当。检查全局中断使能确认CPU内核的全局中断以及UART外设的中断通道已在NVIC中使能。检查LSR错误如果发生了帧错误、奇偶错误等可能会触发更高优先级的LINESTSITIIR类型0x01。必须在该中断的ISR中读取LSR来清除错误状态否则可能会阻塞其他中断。6.2 硬件流控失效数据仍然丢失症状使能了Auto RTS/Auto CTS但对方设备仍在RX FIFO满时发送数据导致溢出。排查步骤确认物理连接用万用表或示波器检查RTS/CTS线是否正确连接且电平有效低电平有效。验证EFR配置读取EFR寄存器确认AUTORTSEN和AUTOCTSEN位确实已置1。检查TCR配置确认已正确设置MCR[6]1并写入了TCR寄存器。重中之重验证TCR[3:0](HALT) TCR[7:4](RESTORE)。如果两者相等或颠倒流控行为将不可预测。检查FIFO深度与阈值匹配确保TCR中设置的阈值乘以4后的字节数不超过实际的RX FIFO大小64字节。监控MSR寄存器在调试时定期读取MSR寄存器观察CTS_STS和RTS相关位的变化看流控信号是否按预期翻转。6.3 软件流控字符被当作数据接收症状使能了软件流控但发送的XON/XOFF字符出现在了应用层接收的数据流中。排查步骤检查EFR[3:0]配置确认SWFLOWCTRL位设置正确。例如如果你希望识别XON1/XOFF1需要设置EFR[3]1且EFR[1]1根据手册表格组合。检查XON/XOFF寄存器值确认XON1_ADDR1和XOFF1寄存器中写入的值与你协议中定义的流控字符一致通常是0x11和0x13。理解流控字符处理当UART识别出流控字符时默认情况下该字符不会存入RX FIFO。如果你需要同时处理流控和保留该字符可能需要使用“特殊字符检测”功能EFR[5]并配置XOFF2寄存器然后在中断中处理。6.4 FIFO使能后通信乱码症状使能FIFO后收发的数据出现错位、乱码或完全不对。排查步骤确认初始化顺序这是最常见的原因。回顾你的代码是否在设置波特率DLL/DLH之后才使能FIFOFCR[0]1正确的顺序必须是停止时钟DLL/DLH0 - 配置FCR - 设置波特率。检查LCR配置确保数据格式字长、停止位、奇偶校验在通信双方完全一致。FIFO不影响帧格式。检查FIFO清除位在初始化时或通信异常后尝试写FCR[1]和FCR[2]来清除RX/TX FIFO。注意写入清除位后硬件需要几个时钟周期完成清除操作建议添加短暂延时。使用环回测试将MCR[4](LOOPBACKEN) 置1进入内部环回模式。在此模式下发送的数据会直接环回到接收端可以排除外部线路问题专注验证UART内核和FIFO的配置是否正确。调试UART尤其是涉及流控和FIFO等高级功能时逻辑分析仪是你的最佳伙伴。用它同时抓取TX、RX、RTS、CTS信号线以及中断引脚可以直观地看到数据流、流控信号的变化与中断触发时刻的对应关系很多软件上难以捉摸的问题在波形图前会一目了然。