行业资讯
深入解析TI UART/IrDA/CIR FIFO与中断机制:从寄存器配置到实战调试
1. 项目概述与核心价值在嵌入式开发尤其是涉及串行通信的领域UART、IrDA和CIR这些接口是我们与外部世界对话的“嘴巴”和“耳朵”。但通信从来不是简单的“你发我收”当高速的处理器遇上慢吞吞的串行总线或者需要处理突发的大量数据时如果没有一个高效的缓冲机制系统要么被频繁的中断拖垮要么眼睁睁看着数据丢失。这就是FIFOFirst In First Out先进先出队列登场的原因。它就像一个快递驿站数据包先在这里排队暂存处理器或DMA控制器可以一次性来取走或放入一批而不是每来一个包裹就敲一次门。你提供的TI UART/IrDA/CIR模块技术手册片段正是深入这个“驿站”内部管理机制的钥匙。它详细描述了FIFO如何与中断、DMA协同工作实现数据流的平滑控制。对于嵌入式软件工程师、驱动开发者或任何需要优化串行通信性能的开发者而言理解这些机制至关重要。它不仅能帮你写出更稳定、高效的驱动程序还能在调试通信超时、数据丢失等棘手问题时提供清晰的排查思路。本文将基于这份手册拆解FIFO管理的三种核心模式中断、轮询、DMA并深入探讨中断机制在不同模式UART、IrDA、CIR下的差异最后分享一些从寄存器配置到实际调试的实战心得。2. FIFO核心机制与寄存器详解在深入工作模式之前我们必须先搞清楚控制这个“数据驿站”的几个关键“开关”和“仪表盘”也就是相关的寄存器。手册中提到的FCR、TLR、IER、IIR等每一个位都直接决定了FIFO的行为。2.1 核心控制寄存器FCR与TLRFIFO控制寄存器FCR是总开关。其中FCR[0]FIFO_EN位是核心置1则启用64字节的收发FIFO置0则禁用FIFO模块退回到单字节缓冲的“传统”模式。启用FIFO是使用中断或DMA模式的前提。FCR[5:4]TX FIFO Trigger Level和FCR[7:6]RX FIFO Trigger Level这两个字段用于设置FIFO的触发阈值但它们是比较基础的设置。更灵活、更强大的阈值配置来自于触发等级寄存器TLR。TLR[3:0]用于设置发送FIFO的空闲空间Space阈值而TLR[7:4]用于设置接收FIFO的数据量Level阈值。这个阈值是中断和DMA请求的“发令枪”。注意手册明确指出TLR寄存器仅在增强功能启用通过EFR和MCR相关位配置时才可访问。在实际编程中你需要先解锁对这些扩展寄存器的访问权限才能配置TLR。2.2 状态感知寄存器LSR与SSR光有控制不行还得知道驿站里现在是什么情况。线路状态寄存器LSR提供了最基础的状态信息例如接收数据就绪DR、发送保持寄存器空THRE等。在轮询模式下我们需要持续查询这个寄存器。而在FIFO启用后补充状态寄存器SSR提供了更直接的信息。例如SSR[0]TXFIFOFULL位当它被读为1时就明确告诉你发送FIFO已经满了此时再写入数据会导致溢出。这是一个非常直观的状态检查点。2.3 中断管理寄存器IER与IIR中断使能寄存器IER决定了哪些事件可以触发中断线给处理器。比如使能IER[0]ERBFI允许接收数据就绪产生中断使能IER[1]ETBEI允许发送保持寄存器空中断。当中断真的发生时我们需要快速知道是“谁”引起了中断。这就是中断标识寄存器IIR的作用。IIR[0]位指示是否有中断挂起0表示有。IIR[3:1]在有些版本中是IIR[2:1]或IIR[3:0]则指明了具体的中断类型如接收线路状态错误、接收数据就绪、发送保持寄存器空等。处理器通过读取IIR来识别中断源并跳转到相应的服务例程。一个关键细节手册的UART中断表Table 23-4展示了中断的优先级。接收线路状态中断如溢出OE、帧错误FE等拥有最高优先级1级而发送空中断THRE是3级。这意味着当多个中断条件同时发生时高优先级的会先被响应。在编写中断服务程序ISR时即使你只使能了接收中断也最好先读取IIR判断类型因为线路错误也可能触发中断。3. FIFO三种工作模式深度解析理解了寄存器我们就可以像搭积木一样组合出三种不同的工作模式。每种模式适用于不同的场景和性能需求。3.1 中断模式效率与实时性的平衡中断模式是最高效的通用模式。通过设置FCR[0]1启用FIFO并在IER中使能相应的中断如ERBFI和ETBEI模块就可以在达到TLR设定的阈值时自动通知CPU。接收中断流程数据持续进入接收FIFO。当FIFO中的数据量达到或超过TLR[7:4]设定的阈值例如8字节时模块拉低中断请求线。CPU响应中断进入ISR。ISR读取IIR确认为接收数据就绪中断后开始从接收保持寄存器RHR读取数据。这里有个关键点手册强调中断信号只有在CPU读取了足够多的数据使FIFO中的数据量低于触发阈值后才会被取消断言De-assert。这意味着如果你的ISR只读了一个字节就退出了而FIFO里还剩7个字节假设阈值是8那么中断线会一直保持有效导致CPU不断被重复中断陷入“中断风暴”。正确的做法是在ISR中用一个循环一直读到FIFO为空通过检查LSR的DR位或SSR状态或读到低于阈值为止。发送中断流程发送FIFO初始为空中断立即被触发。CPU在ISR中向发送保持寄存器THR写入数据直到填满FIFO或达到你计划发送的数据量。当数据被硬件不断发送出去FIFO中的数据量减少一旦其空闲空间达到或超过TLR[3:0]设定的阈值例如56字节空间中断信号被取消。当FIFO再次被完全发空中断会再次触发请求CPU填充下一批数据。实操心得设置阈值是一场权衡。接收阈值设得太小如1字节中断会非常频繁CPU开销大设得太大如60字节数据响应延迟会变长且在高速数据流下可能因处理不及时导致溢出。对于发送阈值决定了你一次填充的数据量。通常接收阈值设为FIFO深度的1/4或1/2如16或32字节发送阈值设为1/2或3/4如32或48字节空间是一个不错的起点需要根据实际波特率和CPU负载调整。3.2 轮询模式简单直接的控制当系统对实时性要求不高或者CPU资源充裕到可以定期检查时轮询模式是最简单的选择。设置FCR[0]0禁用FIFO或者启用FIFO但通过IER禁用所有中断然后通过定期读取LSR寄存器来检查状态。检查是否可以发送查询LSR[5]THRE位为1表示发送保持寄存器空可以写入下一个字节。检查是否收到数据查询LSR[0]DR位为1表示有数据可读。轮询模式的优缺点优点实现简单没有中断上下文切换的开销对简单任务或裸机系统友好。缺点CPU必须不断主动查询占用CPU周期。如果查询频率不够可能错过数据或造成发送延迟查询太频繁又浪费资源。在FIFO启用的情况下轮询你可以通过检查FIFO状态位如通过SSR或自定义的FIFO计数来批量读写效率比单字节模式高。3.3 DMA模式解放CPU的终极武器对于大数据量、高波特率的传输DMA模式是必选项。它允许数据在FIFO和外设内存之间直接搬运无需CPU介入每个字节。DMA模式配置手册提到了DMA模式0/1/2/3通过SCR和FCR寄存器组合选择。例如设置SCR[0]1且SCR[2:1]01选择DMA模式1。更常见的配置是使用模式1或2。DMA发送流程CPU配置好DMA控制器源地址内存中的数据缓冲区目标地址UART的THR寄存器传输数据量。当发送FIFO为空时模块向DMA控制器发出请求DMA Request。DMA控制器响应请求将设定好数量的数据例如TLR设定的“空间阈值”个字节一次性搬运到发送FIFO中。数据被硬件自动发送。当FIFO再次被发空DMA请求再次产生直到完成全部数据的传输。传输结束时可能会产生一个传输完成中断通知CPU。DMA接收流程CPU配置DMA源地址UART的RHR寄存器目标地址内存中的接收缓冲区传输数据量。当接收FIFO中的数据量达到TLR[7:4]设定的阈值时模块向DMA控制器发出请求。DMA控制器将阈值数量的数据一次性从FIFO搬运到内存缓冲区。重复此过程。通常DMA会配置成循环模式或由CPU在缓冲区满后重新配置。一个至关重要的对齐问题手册图23-22及其描述强调UART模块内设置的DMA请求大小由TLR定义例如56个空间必须与系统DMA控制器的传输量设置相匹配。如果DMA控制器一次只搬32字节而UART期望56字节就会导致行为异常。务必确保两边的配置一致。4. 不同通信模式下的中断机制差异UART、IrDA和CIR虽然共享硬件模块但协议不同中断源和含义也有显著区别。混淆它们是调试中常见的错误来源。4.1 UART模式中断UART模式的中断最为经典和复杂拥有明确的优先级见表23-4。除了常见的收发中断RHR, THR需要特别关注接收线路状态中断最高优先级由LSR[7]RX_FIFO_STS位错误溢出OE、帧错误FE、奇偶错误PE、线路间断BI触发。清除方法因错误类型而异对于FE/PE/BI读取RHR寄存器即可清除对于OE溢出必须读取LSR寄存器才能清除。在ISR中必须妥善处理否则中断会持续挂起。XOFF/特殊字符中断用于硬件流控。当接收到XOFF字符或预设的特殊字符时触发。如果是XOFF引起则接收到XON字符后清除如果是特殊字符引起则读取IIR寄存器清除。4.2 IrDA模式中断IrDA是面向帧的协议因此其中断更侧重于“帧”事件。状态FIFO中断IIR[4]这是IrDA的特色。当接收完一个完整帧后帧长度和错误状态CRC错误、中止、帧长错误会被写入一个独立的8入口状态FIFO。当状态FIFO中的数据达到其触发水平时产生此中断。CPU通过读取SFLSR和SFREGL/H寄存器来获取帧信息从而在内存中定位帧边界并筛选错误帧。这允许DMA连续搬运数据而CPU只需在积累了一批帧状态后才被中断处理极大提高了效率。TX状态中断IIR[5]指示发送完成。但需注意它可能表示两种结果成功发送完成或发送过程中发生欠载Underrun错误。需要通过检查MDR2[0]IRTX_UNDERRUN位来区分。欠载错误需要按手册描述进行复位FIFO和读取RESUME寄存器的恢复操作。接收EOF中断IIR[7]收到帧结束符。这对于帧同步很有用。4.3 CIR模式中断CIR消费电子红外模式使用了IrDA中断的一个子集并做了简化。RXSTOPIT中断IIR[2]这是CIR特有的表示接收停止中断其触发条件取决于BOF长度寄存器EBLR的设置。通常用于检测红外遥控信号中的引导码BOF结束。TX状态中断IIR[5]在CIR模式下它仅表示最后一比特红外数据已成功发送到IR TX引脚功能比IrDA模式下单纯。配置陷阱在切换模块工作模式通过MDR1[2:0]时中断使能位IER和中断标识位IIR的映射关系会改变。如果你在UART模式下配置了IER然后切换到IrDA模式之前的中断使能设置可能无效甚至指向错误的中断源。最佳实践是在切换模式后重新初始化IER等中断相关寄存器。5. 高级功能与故障处理实战5.1 流控与阈值协同当使能硬件流控如RTS/CTS时手册给出了一个关键约束流控FIFO阈值由TCR[3:0]寄存器控制必须大于或等于接收FIFO中断/DMA阈值TLR[7:4]。这是为了防止死锁。假设接收FIFO阈值是8流控阈值是4。当FIFO收到4个字节时模块就会因为达到流控阈值而拉高RTS假设高电平禁止发送通知对方停止发送。但此时接收中断还未触发需要8字节本地CPU不知道有数据到来不会去读取。FIFO数据无法被清空RTS一直为高通信就此卡死。因此务必确保流控阈值 接收触发阈值。5.2 欠载与溢出的恢复手册明确描述了传输欠载TX Underrun和接收溢出RX Overrun的硬件处理流程及软件恢复步骤。这不是简单的错误标志而是会触发内部标志并禁用后续传输或接收。TX欠载恢复当发送FIFO在帧结束前变空硬件会设置内部标志并停止发送。软件必须复位发送FIFO通过FCR寄存器。读取RESUME寄存器这是一个“魔法”操作用于清除内部锁定标志。 之后才能开始新的传输。RX溢出恢复当接收FIFO已满但RX状态机仍试图写入时发生。恢复步骤类似复位接收FIFO。读取RESUME寄存器。踩坑记录我曾遇到一个偶发的串口收不到后续数据的问题查了很久才发现是发生了接收溢出但程序只清除了LSR中的OE错误标志没有执行“复位FIFO读RESUME”的完整恢复流程导致接收电路被锁死。这个教训很深刻对于这类会禁用硬件的错误必须严格按照手册的恢复序列操作。5.3 睡眠与空闲模式下的考量为了节能模块支持睡眠和空闲模式。在UART模式下通过IER[4]需EFR[4]1进入睡眠在IrDA/CIR模式下通过MDR1[3]进入。进入睡眠的条件包括收发FIFO为空、RX线空闲等。一个重要警告手册用NOTE特别强调在睡眠模式下绝对不能去写DLL和DLH寄存器来修改波特率。因为此时模块内部时钟可能已停止写操作会导致不可预测的行为。正确的做法是在修改波特率前先禁用睡眠模式清除IER[4]或MDR1[3]配置好波特率后再重新使能睡眠。5.4 波特率生成计算与误差手册表23-7和23-8提供了48MHz系统时钟下的常用波特率配置值。其核心公式是分频值 (FCLK / 16) / 目标波特率其中FCLK是48MHz16是UART 16倍过采样模式下的倍数。对于13倍模式或其他模式如IrDA的SIR/MIR除数需要相应调整。例如要配置115200波特率16倍模式 分频值 (48,000,000 / 16) / 115200 3,000,000 / 115200 ≈ 26.0417 取整后为26。代入公式反算实际波特率48,000,000 / (16 * 26) ≈ 115384.6 bps误差约为0.16%。这在大多应用中是可接受的。如果对误差有严格要求可能需要选择更精确的晶振或使用小数分频器如果模块支持。6. 寄存器访问映射与配置流程手册最后的表23-9是配置时的“地图”它揭示了寄存器地址偏移与LCR[7]和LCR[7:0]值的复杂关系。例如当LCR[7]0时偏移0x0地址对应的是RHR读和THR写。但当LCR[7]1时该地址就变成了DLL波特率除数锁存器低字节的访问地址。标准配置流程示例以启用115200波特率、8N1、FIFO中断模式为例解锁扩展功能如需访问EFR、TLR等通常需要写一个特定值到LCR如0xBF然后才能设置EFR[4]等位。设置波特率写LCR使其LCR[7]1以访问DLL/DLH。根据计算或查表写入DLL0x1ADLH0x00对应十进制26。写LCR使其LCR[7]0回到正常寄存器映射。设置线路控制写LCR 0x038位数据无校验1位停止位。启用并配置FIFO写FCR 0xC7启用FIFO清除收发FIFO设置TX/RX触发阈值为默认值或根据TLR设置。如果需要自定义阈值解锁并配置TLR寄存器。使能中断写IER 0x07使能接收数据就绪、发送保持寄存器空、接收线路状态中断。可选启用自动流控如果需要配置MCR和TCR寄存器。在整个过程中对寄存器的每一次读写都必须严格遵循表23-9的地址映射规则否则你写入的可能是完全不同的控制位导致模块行为异常。理解TI UART/IrDA/CIR模块的FIFO与中断机制就像是掌握了管理一个高效物流中心的所有细则。从阈值设定这个“库存预警线”到中断/DMA这个“自动叫车系统”再到不同协议下的“特色服务”如IrDA的状态FIFO每一个细节都影响着通信的稳定性和效率。调试时不妨多用逻辑分析仪抓取中断信号线和数据线结合寄存器的状态亲眼看看数据是如何在FIFO中流动中断又是如何被触发和清除的这种直观的感受远比读文档来得深刻。最后牢记手册里的那些“NOTE”和“CAUTION”它们往往是前人踩过的坑能帮你省下大量的调试时间。
郑州网站建设
网页设计
企业官网