UART模块高级应用:软件流控制、IrDA与CIR红外通信实战解析

发布时间:2026/7/21 12:49:03
UART模块高级应用:软件流控制、IrDA与CIR红外通信实战解析 1. 项目概述从UART到无线一个模块的三种面孔搞嵌入式开发串口UART绝对是绕不开的老朋友。从最基础的调试信息打印到设备间的命令交互它无处不在。但很多人对UART的认知可能还停留在“配置波特率、数据位、停止位、奇偶校验”这老四样上顶多再知道个RTS/CTS硬件流控制。实际上现代SoC系统级芯片里的UART模块能力远超我们的想象。它不仅能干好串口通信的本职工作还能通过内部状态机的切换摇身一变成为红外数据通信IrDA的收发器甚至化身为一套可编程的万能红外遥控CIR编码解码引擎。我最近在调一个基于TI某款ARM Cortex-A8处理器的项目正好用到了其UART3模块需要同时实现与上位机的可靠串口通信、与另一设备的IrDA数据交换以及学习并发射家电的红外遥控信号。翻看芯片的技术参考手册TRM时发现其UART模块将这三种功能集成在了一起通过配置不同的寄存器模式来切换。这比外挂一堆专用芯片如IrDA编解码芯片、红外遥控编码芯片要优雅和节省成本得多。但手册内容庞杂寄存器位描述分散直接上手容易踩坑。本文将结合我的实际调试经验深入剖析UART模块的软件流控制XON/XOFF、IrDA模式SIR/MIR/FIR以及CIR遥控模式的实现原理、配置要点和避坑指南。无论你是正在调试类似功能的工程师还是对串口通信深层应用感兴趣的开发者相信都能从中找到有用的干货。我们会从最核心的流控制机制讲起这是保证一切数据交换可靠性的基石。2. 软件流控制XON/XOFF深度解析与实战硬件流控制RTS/CTS需要额外的物理连线在引脚紧张或者布线简单的场景下并不总是可用。此时软件流控制就成了维持通信稳定的关键手段。它的核心思想非常简单接收方通过向发送方回传特定的控制字符来动态命令对方“暂停发送”或“恢复发送”。2.1 工作原理XOFF与XON的握手在UART模块中软件流控制功能通常由增强功能寄存器EFR等使能。一旦启用模块的接收逻辑就会对流入的每一个数据字节进行“审查”。暂停发送XOFF当接收方的缓冲区RX FIFO快满时它需要告诉对方“慢点我处理不过来了”。此时接收方会向发送方发送一个或多个预先定义好的XOFF字符通常是0x13即DC3字符。发送方的UART模块在收到并识别出有效的XOFF字符序列后会在发送完当前正在传输的这个字符后立即暂停从发送缓冲区TX FIFO中取出数据发送。同时它会设置一个中断标志位例如IIR[4]如果中断使能了IER[5]1就会产生一个中断通知CPU“对方要求暂停发送了”。恢复发送XON当接收方处理完积压的数据缓冲区有空余时就需要解除暂停。它会向发送方发送XON字符通常是0x11即DC1字符。发送方UART模块识别到有效的XON字符序列后会清除之前的中断标志并自动恢复从TX FIFO中取数据发送。这里有几个关键细节手册里提了但容易忽略字符序列XON/XOFF不一定是一个字符。模块可以配置为需要匹配单个字符XON1/XOFF1或者需要按顺序匹配一对字符XON1XON2 / XOFF1XOFF2。这通过EFR[1:0]来配置。使用字符对可以提高流控制指令的可靠性避免因数据中的巧合字符而误触发。FIFO写入规则这是一个重要的“坑点”。当软件流控制使能且“XON任意字符检测”和“特殊字符检测”功能关闭时被识别为XON/XOFF的字符是不会被写入接收FIFO的。它们被模块内部“消费”掉了不会递交给上层软件。这意味着如果你的应用数据流中恰好包含了与XON/XOFF相同的字符它们会在传输过程中被“吃掉”导致数据错误。因此务必选择应用中绝不会出现的字符作为XON/XOFF或者启用特殊处理机制。错误处理如果接收XON/XOFF字符时发生了奇偶校验、帧错误或Break错误该字符不会被当作流控制字符处理而是会被当作普通数据写入RX FIFO。这算是一种容错机制防止线路干扰导致流控制信号误判。2.2 发送方的自动流控制除了响应对方的XON/XOFF模块自身也可以根据接收FIFO的填充水平自动向对方发送XON/XOFF信号实现双向流控制。这通过触发水平寄存器TCR来配置。TCR[3:0] (RX FIFO Halt Trigger)设置一个阈值例如FIFO深度的3/4。当接收FIFO中的数据量超过此阈值时模块会自动向对方发送XOFF字符通常是两个请求对方暂停发送。TCR[7:4] (RX FIFO Resume Trigger)设置一个恢复阈值例如FIFO深度的1/4。当接收FIFO中的数据量低于此阈值时模块会自动向对方发送XON字符通常是两个通知对方可以恢复发送。这个功能非常实用实现了硬件流控制类似的自动化但完全在软件协议层完成。需要注意的是自动发送的XON/XOFF字符其传输协议和普通数据字节完全一样受数据位长度5/6/7位设置的影响——只有低5/6/7位会被发送。虽然实际中几乎不会用5/6/7位模式做流控制但模块保留了这种兼容性。避坑指南软件流控制的“死锁”风险软件流控制最大的风险是“死锁”。假设A发送XOFF给B后B的回复可能是XON也可能是其他数据因为线路问题丢失A将永远等待通信中断。因此在实际应用中必须实现超时机制发送方在暂停后如果超过一定时间如500ms未收到XON应尝试恢复发送一小段数据或触发错误处理流程。谨慎选择控制字符绝对避免使用0x00, 0xFF, 0x0A, 0x0D等常见于数据帧头、帧尾或文本协议的字符。硬件流控制优先在高速或可靠性要求极高的场合硬件流控制RTS/CTS仍是首选因为它响应更快且不占用数据带宽。2.3 配置示例与代码思路手册里给出了一个通用的配置流程但比较抽象。我结合实践梳理出一个更清晰的步骤。假设我们要配置UART为115200波特率8N1使能FIFO和软件流控制使用XON10x11, XOFF10x13。第一步模块软复位与基础设置目标是清空所有状态将模块置于一个已知的初始状态。// 1. 解锁增强功能寄存器(EFR)的访问权限 UART_LCR 0xBF; // 写入0xBF到LCR使能访问EFR、IER、MCR等 UART_EFR | (1 4); // 设置EFR[4]1允许写入IER和MCR // 2. 关闭所有中断将MODEM控制信号设为无效状态 UART_IER 0x00; // 禁用所有中断 UART_MCR 0x00; // 强制DTR、RTS等信号为无效高电平 // 3. 确保不在发送Break信号 UART_LCR ~(1 6); // 清除LCR[6]解除Break条件 // 4. 将模块置于复位/禁用状态可选但推荐 UART_MDR1 0x07; // MDR1[2:0]111bUART复位模式或者你也可以直接使用芯片级的硬件复位信号如SYSC[1]复位完成后同样需要执行上述寄存器配置以确保状态一致。第二步FIFO与流控制参数配置接下来配置FIFO和流控制的触发阈值。// 1. 确保仍能访问EFR并设置MCR[6]以允许配置TCR/TLR UART_LCR 0xBF; // 再次写入确保访问权限 UART_EFR | (1 4); // EFR[4]1 UART_MCR | (1 6); // MCR[6]1使能TCR/TLR寄存器访问 // 2. 配置流控制触发水平假设64字节FIFO UART_TCR 0x37; // 举例TCR[7:4]0011b (恢复水平12字节) TCR[3:0]0111b (暂停水平28字节) // 3. 配置FIFO触发水平用于中断 UART_TLR 0x10; // 举例TLR[7:4]0001b (TX FIFO触发水平4字节) TLR[3:0]0000b (RX FIFO触发水平1字节) // 4. 使能FIFO并设置其模式 UART_FCR 0xC1; // FCR[0]1 使能FIFO FCR[1]1 复位RX FIFO FCR[2]1 复位TX FIFO FCR[7:6]11b (64字节模式) // 5. 配置XON/XOFF字符 UART_XON1 0x11; // XON字符 UART_XOFF1 0x13; // XOFF字符 // 如果需要字符对还需配置XON2/XOFF2 // 6. 配置流控制模式并锁定寄存器 UART_EFR | (1 7) | (1 6); // 假设EFR[7:6]控制流控制使能和模式具体看手册 // 完成配置后关闭特殊寄存器访问权限防止误写 UART_LCR 0xBF; UART_EFR ~(1 4); // EFR[4]0 UART_LCR 0x00; // 回到正常LCR模式 UART_MCR ~(1 6); // MCR[6]0第三步波特率、数据格式与模块使能最后配置通信参数并启动模块。// 1. 配置数据格式8位数据1位停止位无奇偶校验 UART_LCR 0x03; // LCR[1:0]11 (8位) LCR[2]0 (1停止位) LCR[3]0 (无校验) // 2. 访问波特率分频器锁存器 UART_LCR | (1 7); // 设置LCR[7]1以访问DLL和DLH // 3. 设置波特率 (假设系统时钟48MHz目标115200) // 计算公式DLLDLH 时钟频率 / (16 * 波特率) // 48000000 / (16 * 115200) 26.042 ≈ 26 UART_DLL 26; // 写入低8位 UART_DLH 0; // 写入高8位 // 4. 退出波特率设置模式 UART_LCR ~(1 7); // 清除LCR[7] // 5. 使能所需中断例如接收数据可用中断 UART_IER 0x01; // 使能接收数据可用中断(RHR) // 6. 最后将模块从复位模式切换到操作模式 UART_MDR1 0x00; // MDR1[2:0]000b UART操作模式非自动波特率至此一个支持软件流控制的UART就配置完成了。在中断服务程序ISR中除了处理数据还需要检查IIR[4]标志以响应对方发送的流控制请求。3. IrDA红外通信模式全解从SIR到FIRIrDAInfrared Data Association是一套用于短距离点对点无线数据通信的标准。它利用红外光脉冲传输数据方向性强保密性好曾是手机、笔记本、打印机间数据传输的主流方式。UART模块通过内部集成IrDA编解码器SIR/MIR/FIR可以直接驱动外部的红外收发器如TFDU4101省去了外置编解码芯片。3.1 SIR模式最经典的115.2kbpsSIRSlow Infrared是IrDA最基础的模式最高速率115.2kbps与标准串口波特率兼容因此应用最广。3.1.1 帧格式与透明传输SIR的帧不是在UART的“起始位数据位停止位”上简单调光而是有一套完整的帧结构[Start Flags] [Address] [Control] [Information] [CRC-16] [Stop Flag]Start Flags开始标志至少一个0xC0字节用于帧同步。Address/Ctrl/Info就是你的数据载荷。CRC-16对整个地址、控制和信息字段计算的校验和。Stop Flag停止标志一个0xC1字节标志帧结束。这里有个核心机制叫异步透明传输Asynchronous Transparency。因为0xC0和0xC1被用作帧标志0x7D被用作转义字符如果数据载荷中恰好包含这些字节怎么办直接发送会破坏帧结构。IrDA的解决方案是在发送前如果遇到0xC0、0xC1或0x7D就在其前面插入一个转义字符0x7D并将原字节的第5位bit 5从0开始计数取反与0x20异或。接收方看到0x7D就知道下一个字节是转义过的将其第5位取反恢复后得到原始数据。CRC计算使用的是原始数据而非转义后的数据这一点在编程时要特别注意。3.1.2 编码与解码3/16与1.6μsSIR采用归零RZI编码逻辑“0”对应一个红外光脉冲逻辑“1”对应无光。3/16编码一个比特周期被分为16份。对于要发送的“0”在第7个时钟周期开始发射红外脉冲持续3个时钟周期宽度即3/16个比特周期然后关闭。这是最常用的编码方式。1.6μs编码脉冲宽度固定为1.6微秒与波特率无关。在115.2kbps下一个比特周期约8.68μs1.6μs脉冲约占18.4%。这种方式兼容性更好。通过配置辅助控制寄存器ACREG[7]的PULSETYPE位来选择脉冲类型。3.1.3 SIR自由格式模式有时我们想完全控制红外帧的每一个字节比如实现自定义协议。SIR自由格式模式就是为此而生。在此模式下UART模块不再自动添加/移除开始标志、CRC和停止标志也不进行透明传输处理。它仅仅将TX FIFO中的数据以SIR的脉冲编码方式3/16发送出去接收端也原样将解码后的数据放入RX FIFO。所有帧结构的组装、CRC校验都需要软件来完成。这给了开发者最大的灵活性。配置SIR自由格式模式的关键是将MDR1[2:0]设置为000bUART模式。将MDR2[3]设置为1以允许脉冲整形。将UART数据格式固定为8位数据位、1位停止位、无校验LCR0x03。设置ACREG[7]0选择3/16脉冲。3.1.4 地址检查与SIP地址检查在多设备红外环境中为了避免收到发给其他设备的帧可以启用地址检查功能。通过XON1/ADDR1和XON2/ADDR2寄存器设置本机地址并通过EFR[1:0]使能检查。只有地址匹配的帧才会被存入RX FIFO。SIP串行红外交互脉冲在MIR和FIR模式下发送方必须每500ms至少发送一次SIP一个长脉冲以告知低速SIR设备信道正忙。在SIR模式下通常不需要。3.2 MIR与FIR模式高速红外MIRMedium Infrared速率0.576Mbps或1.152Mbps。帧格式与SIR类似但采用了比特填充Bit Stuffing技术在数据中每连续出现5个‘1’就自动插入一个‘0’以保证足够的电平跳变用于时钟恢复。接收端则进行相反的去填充操作。MIR模式还需要复杂的42-41-42循环模式的波特率调整机制以在48MHz系统时钟下满足严格的波特率容差±0.1%。FIRFast Infrared速率4Mbps。它采用了完全不同的4PPM4-Pulse Position Modulation编码将两个比特编码为一个符号位并通过符号位在四个时隙中的位置来表示数据。帧结构包含前导码、开始标志、CRC-32等。FIR的硬件实现更为复杂通常用于要求更高速度的文件传输。实操心得IrDA调试的关键点硬件连接IrDA收发器有TX、RX和SD关断引脚。UART的TXD接收发器的TXD收发器的RXD接UART的RXD。务必注意很多收发器是3.3V电平需确保与UART引脚电平兼容。SD引脚通常拉低使能。视线与距离红外通信需要直视且距离通常在几厘米到一米之间中间不能有障碍物。调试时最好将两个收发器窗口对准。模式选择通信双方必须工作在相同的IrDA模式SIR/MIR/FIR和相同的波特率/速率下。通常从SIR 115200开始调试最简单。示波器观察最直接的调试方法是使用示波器观察UARTTXD脚和红外收发器IRTX输出引脚的波形。TXD上是标准的UART数字波形而IRTX上应该是被调制的红外脉冲波形逻辑0时有脉冲群。如果IRTX没有输出检查MDR1模式寄存器是否已正确设置为IrDA模式如SIR模式是001b。透明传输如果你发送的数据中包含0xC0,0xC1,0x7D一定要确认接收端是否正确恢复了数据。一个常见的错误是软件自己又做了一遍透明处理导致数据错误。3.3 IrDA配置代码示例手册给出了SIR收发的配置示例但比较零散。我将其整合并加上注释SIR模式接收配置115200bps偶校验FIFO禁用// 1. 设置模式为SIR UART_MDR1 0x01; // MDR1[2:0]001b (SIR模式) // 2. 配置LCR访问DLL/DLH并设置数据格式8位数据偶校验 UART_LCR 0xAB; // LCR[7]1 (访问DLL/DLH) LCR[5:3]101b (偶校验) LCR[1:0]11b (8位) // 注意手册示例中LCR0xA8其LCR[5:3]101是强制校验位为1这里根据需求调整。 // 3. 设置波特率除数 (48MHz / (16 * 115200) 26.04 - 26) UART_DLL 26; UART_DLH 0; // 4. 退出DLL/DLH访问模式并可选设置停止位等 UART_LCR 0x2B; // LCR[7]0 LCR[2]1 (2停止位可选)其他同上 // 5. 使能接收中断可选 UART_IER 0x01; // 使能接收数据可用中断 // 现在模块已准备好接收SIR格式的红外数据帧SIR模式发送配置115200bps无校验发送6字节帧// 1. 设置模式为SIR并启用自动SIP生成可选 UART_MDR1 0x41; // MDR1[2:0]001b (SIR模式) MDR1[6]1 (自动生成SIP) // 2. 访问EFR寄存器以进行增强功能配置 UART_LCR 0xBF; // 写入0xBF访问EFR UART_EFR 0x10; // 使能增强功能写入 (EFR[4]1) // 3. 配置LCR访问DLL/DLH并设置数据格式7位数据2停止位根据需求 UART_LCR 0x86; // LCR[7]1, LCR[2]1 (2停止位), LCR[1:0]10b (7位数据) // 4. 设置波特率除数 UART_DLL 26; UART_DLH 0; // 5. 退出DLL/DLH访问模式 UART_LCR 0x06; // LCR[7]0 // 6. 设置MODEM控制信号如果需要 UART_MCR 0x01; // 强制DTR有效 // 7. 使能发送中断可选 UART_IER 0x02; // 使能THR空中断 // 8. 设置发送帧长度对于SIR这个寄存器可能用于其他目的需查证。手册示例中用了TXFLL UART_TXFLL 0x06; // 发送帧长6字节 // 9. 设置额外的开始标志数量可选 UART_EBLR 0x08; // 发送8个开始标志实际至少2个即可 // 10. 选择脉冲类型可选默认3/16 // UART_ACREG | (1 7); // 选择1.6us脉冲 // 11. 向发送保持寄存器(THR)写入数据启动发送 UART_THR data_byte0; // ... 写入后续字节或由中断服务程序填充MIR和FIR模式的配置流程类似主要区别在于MDR1中的模式选择位、波特率除数DLL/DLH的值因为速率不同以及可能需要配置SIP相关寄存器。4. CIR模式打造万能红外遥控CIRConsumer Infrared模式让UART模块变身成了一个可编程的红外遥控信号发生器/接收器。与IrDA用于数据传输不同CIR专为控制命令设计其编码强调抗干扰和距离而非高速度。4.1 编码原理脉宽调制与双相编码市面上红外遥控协议五花八门但编码原理主要分两大类脉宽调制PWM也叫脉冲距离调制逻辑‘0’和逻辑‘1’用脉冲高电平的持续时间不同来区分。例如在NEC协议中‘0’是560μs脉冲560μs低电平‘1’是560μs脉冲1690μs低电平。索尼的SIRC协议是此类的典型代表。双相编码曼彻斯特编码等逻辑‘0’和‘1’用在一个位周期内电平跳变的方向来区分。例如在RC-5协议中每一位中间都有一次跳变。逻辑‘1’是前半位高电平后半位低电平逻辑‘0’则相反。飞利浦的RC-5协议是此类的典型代表。UART的CIR模式采用了一种灵活的自由格式。它不固定任何协议而是定义了一个基本时间单位T。开发者可以编程T的时长通过配置寄存器实现。然后UART模块就按照一个简单的规则工作从TX FIFO读到一个比特‘1’就在IRTX引脚上输出一个持续时间为T的红外载波脉冲调制后读到一个比特‘0’就输出持续时间为T的空闲无载波。4.2 如何用CIR模式模拟主流协议关键在于软件如何组织要发送的比特流。模拟RC-5双相编码RC-5的每一位占用1.778ms中间有跳变。我们可以将CIR的周期T设置为RC-5的半个位周期即889μs。那么一个RC-5的逻辑‘1’先高后低就可以用两个连续的CIR比特“10”来表示一个逻辑‘0’先低后高就用“01”来表示。因此要发送一串RC-5码你需要先将每一位扩展成两个CIR比特然后按顺序写入UART的TX FIFO。例如发送RC-5位序列1, 0, 1, 0你需要构造CIR比特序列1,0, 0,1, 1,0, 0,1。每8个比特组成一个字节写入FIFO所以这个序列对应两个字节0b10011001(0x99) 和0b10011001(0x99)。实际上一个完整的RC-5帧是14位需要28个CIR比特即4个字节最后一个字节高4位补0。模拟SIRC脉宽调制SIRC的‘0’和‘1’脉宽不同。假设‘0’的脉冲宽度是T低电平宽度是T‘1’的脉冲宽度是T但低电平宽度是2T或更长。我们可以通过控制连续‘0’和‘1’的数量来组合出不同的高低电平持续时间。但这通常需要更精细的时序控制有时CIR模式的灵活度可能不够需要结合定时器或PWM。4.3 载波调制让红外线“闪起来”红外遥控不是用稳定的红外光表示‘1’而是用高频载波通常是38kHz调制过的脉冲。这样做的好处是1. 提高发射功率2. 便于接收端滤波抗干扰能力强。 在CIR模式下每个代表‘1’的T时长脉冲内部实际上是一串38kHz的方波。如图23-16所示一个比特脉冲由多个载波周期组成。模块要求每个比特脉冲至少包含4个载波周期。载波频率配置这是配置的关键一步。需要通过CFPS寄存器设置分频值。 公式为分频值 (F_CLK / 12) / F_MOD其中F_CLK是系统时钟频率例如48MHz。12是UART模块内部的一个固定分频系数与波特率生成有关。F_MOD是你期望的红外载波频率例如38kHz 0.038MHz。计算分频值 (48 / 12) / 0.038 ≈ 105.26取整为105写入CFPS寄存器。实际的载波频率会有微小误差F_MOD_actual (48/12) / 105 ≈ 38.095 kHz这在允许误差范围内。4.4 CIR模式配置与发射流程模式设置将MDR1[2:0]设置为CIR模式具体值需查手册例如101b。载波配置根据上述公式计算并设置CFPS寄存器确定比特周期T和载波频率。数据格式将UART设置为与CIR兼容的模式通常是8位数据位、1位停止位、无校验LCR0x03。注意此时UART的波特率发生器不用于通信波特率而是用于生成CIR的时基T但LCR[7]和DLL/DLH可能用于设置T的倍数关系具体需查阅寄存器描述。有些模块有专门的CTPRCIR周期寄存器来设置T。构造数据根据目标协议如RC-5将命令码、地址码等按照协议规定的帧格式起始位、校验位等和编码规则如曼彻斯特编码转换成一系列的‘0’和‘1’并打包成字节写入TX FIFO。发送写入数据后模块会自动按照CIR编码规则调制并发送。通常需要发送整个帧的数据帧与帧之间需要软件插入足够的延时几十到上百毫秒这是红外遥控协议的要求。避坑指南CIR接收与学习手册主要描述了发射但CIR模式同样可以接收。接收原理是红外接收头如VS1838B会将38kHz的载波解调输出解调后的数字信号给UART的IRRX引脚。UART模块测量高电平和低电平的持续时间并将其量化为‘1’和‘0’存入RX FIFO。 实现“学习遥控器”功能的大致步骤将UART配置为CIR接收模式。设置一个合适的载波检测阈值和比特周期T。使能接收中断。当用户按下原装遥控器按键时UART会收到一串脉冲信号并转换为一串‘0’和‘1’数据。软件分析这串数据识别出协议类型通过引导码宽度、逻辑‘0’和‘1’的脉宽比例等并提取出地址码和命令码。将这些参数协议类型、地址、命令、T周期存储起来。当需要发射时再按照对应的协议规则生成比特流配置模块并发射。难点不同协议的差异很大需要软件实现一个简单的协议分析器。此外环境光干扰和接收头本身的特性可能引入噪声需要做一定的数字滤波。5. 常见问题排查与调试实录在实际调试这三种模式时我遇到了不少问题这里总结一下问题1软件流控制不起作用对方一直发导致我这边数据丢失。排查检查流控制是否真正使能。确认EFR中相关的流控制使能位已设置。检查XON1/XOFF1字符是否配置正确且双方约定一致。检查TCR寄存器中的触发水平是否设置合理。如果RX FIFO深度是64字节触发水平设为60和4可能太激进可以尝试设为48和16。最重要的一点用逻辑分析仪或示波器抓取TXD和RXD线路上的数据。看当你的RX FIFO超过触发水平时你的UART模块是否真的在TXD线上发出了XOFF字符0x13。同时检查对方的RXD线是否收到了这个字符。解决确保流控制功能已正确使能并通过抓包确认控制字符的发送与接收。在软件层面增加接收缓冲区并提高处理数据的速度。问题2IrDA通信不稳定时通时断或者传输数据错误。排查物理对准确保两个红外收发器的窗口正对且距离在有效范围内通常5-30厘米。电源噪声红外发射需要较大电流确保电源去耦良好。可以在VCC和GND之间加一个100uF的电解电容并联一个0.1uF的陶瓷电容。模式与速率双方必须配置为相同的IrDA模式SIR/MIR/FIR和相同的速率。用示波器测量IRTX引脚看脉冲波形是否正常逻辑0时有密集脉冲群。透明传输如果传输的数据中包含0xC0,0xC1,0x7D接收端数据错误请确认透明传输机制是否正常工作。可以尝试发送一组不包含这些字符的测试数据。中断处理检查IrDA接收中断是否及时响应。如果FIFO溢出也会丢数据。解决从最简单的SIR 9600bps开始测试发送固定的0x55或0xAA0101或1010交替波形规整用示波器观察发送和接收端的波形。逐步提高速率并加入复杂数据测试。问题3CIR模式发射的红外信号设备不响应。排查载波频率这是最常见的问题。用示波器测量IRTX引脚输出的波形。你应该看到周期性的脉冲群。测量脉冲群的频率它应该是你设定的载波频率如38kHz。误差太大超过±1kHz设备可能无法识别。比特周期T测量一个完整比特一个脉冲群一段空闲的周期。它应该等于你根据协议计算出的T。例如对于NEC协议一个T是560μs。如果周期不对协议解码会失败。编码逻辑确认你为协议构造的比特流是正确的。将你要发送的字节数组按照协议文档手工绘制出预期的红外波形图高低电平时序然后与示波器抓取的实际波形对比。重点检查引导码、地址码反码、命令码反码等部分。发射功率红外发射管的驱动电流是否足够可以尝试减小限流电阻但注意不要超过管子的最大电流。接收设备确认你要控制的设备支持你模拟的协议如NEC。用手机摄像头普通模式非人像模式对准你的红外发射管按下发射键在手机屏幕上应该能看到发射管发出微弱的白紫色光点。这是一个快速的定性检查方法。解决使用一个成品红外遥控器和一个红外接收模块如VS1838B连接到逻辑分析仪抓取标准遥控器的波形。然后严格按照此时序调整你的CIR配置CFPS、CTPR等使你的发射波形与之尽可能一致。从模仿一个已知可用的信号开始是最可靠的。问题4UART模式切换后配置似乎不生效或行为异常。排查顺序问题切换模式通过MDR1必须在进行其他具体配置如波特率、数据格式之前进行。因为模式寄存器可能重置或影响其他寄存器的含义。复位状态在切换模式前最好对UART模块进行一次软复位写MDR10x07确保从一个干净的状态开始配置。寄存器访问锁像EFR、TCR、TLR等寄存器需要先通过写LCR0xBF等特殊操作解锁才能写入。配置完成后应将其锁定EFR[4]0防止后续操作误修改。时钟使能确保UART模块的上级时钟例如Peripheral时钟已经使能。有些SoC的模块时钟默认是关闭的。解决严格按照手册推荐的初始化顺序进行配置复位 - 设置模式 - 解锁增强功能 - 配置FIFO/流控制等 - 配置波特率/数据格式 - 使能中断 - 启动操作。并将配置过程封装成清晰的函数如UART_Init()、UART_SetIrdaMode()、UART_SetCirMode()。