深度解析UART/IrDA/CIR复合模块:从寄存器配置到流控制实战
2026/7/22 15:53:49 网站建设 项目流程

1. 项目概述与核心价值

在嵌入式系统开发中,串行通信是连接微控制器与传感器、无线模块、调试终端乃至另一颗处理器的“血管”。而通用异步收发器(UART)无疑是这条血管中最经典、最通用的“心脏”。从业十多年,我调试过的UART接口不计其数,从最简单的8位MCU到复杂的多核应用处理器,其核心思想一脉相承,但具体到不同厂商、不同系列的芯片,寄存器配置和高级功能(如IrDA红外、CIR遥控)的细节往往千差万别,这正是新手容易踩坑、老手需要查阅手册的地方。

今天,我们就以德州仪器(TI)某款应用处理器中的UART/IrDA/CIR复合模块为例,进行一次“庖丁解牛”式的深度解析。你手头可能只有一份零散的技术手册片段,里面充斥着寄存器位域描述,看起来枯燥且难以关联。我的目标是带你穿透这些冰冷的表格,理解整个模块的设计哲学、工作流程,并最终能自信地对其进行配置和调试。这不仅关乎“如何配置”,更关乎“为什么这样配置”以及“配置错了会怎样”。我们会重点剖析其模式切换机制、流控制实现,并特别关注一个常被忽视但至关重要的“伴侣”——看门狗定时器(WDT)在通信模块上下文中的角色与相关寄存器。无论你是正在评估芯片选型,还是深陷通信不稳定的调试泥潭,相信这篇近万字的实操笔记都能给你带来启发。

2. 模块架构与模式切换全解析

2.1 模块核心定位与功能总览

这个UART/IrDA/CIR模块并非一个简单的UART外设,而是一个高度集成的串行通信“瑞士军刀”。它的设计目标很明确:用一套硬件逻辑,通过软件配置,适配多种物理层和协议层的串行通信需求,从而节省芯片面积和功耗,提高应用灵活性。

其核心能力可以分解为三个层面:

  1. 基础UART功能:提供全双工、异步、串行通信,支持5-8位数据位、1/1.5/2停止位、奇偶校验,以及高达3.6864 Mbps(在48MHz参考时钟下)的波特率。这是其立身之本。
  2. 硬件流控与高级特性:内置自动RTS/CTS(自动请求发送/清除发送)硬件流控,能有效防止接收FIFO溢出;支持软件流控(XON/XOFF);具备自动波特率检测、线路中断(Break)产生与检测、以及多种中断源管理能力。这些特性使其能稳定可靠地工作在复杂的通信环境中。
  3. 多模式扩展:通过模式选择寄存器,它能变身为:
    • IrDA SIR模式:支持最高115.2 kbps的红外数据通信,兼容IrDA 1.0物理层标准。
    • IrDA MIR/FIR模式:支持0.576 Mbps和4 Mbps的中高速红外通信。
    • CIR模式:专为消费电子红外遥控设计,支持可编程的脉冲宽度调制(PWM)编码,能够模拟各种品牌遥控器的协议。

这种集成化设计的好处是显而易见的。例如,一个智能家居网关芯片,可以用同一个硬件模块,通过UART模式连接 Zigbee 协处理器,通过CIR模式学习和控制客厅电视与空调,又可以通过IrDA模式与老式PDA进行数据同步,极大提升了资源利用率。

2.2 核心寄存器:模式选择的钥匙(MDR1)

模式切换是整个模块功能配置的起点,其控制权集中于模式定义寄存器1(MDR1)的最低3位MDR1[2:0]。这是一个非常经典的设计,用3个比特位定义了7种工作状态(第8种为禁用)。

MDR1[2:0] 值工作模式关键特性与典型应用场景
0hUART 16x 模式标准UART模式,内部采样时钟为波特率的16倍。最常用,稳定性高。
1hSIR 模式慢速红外模式,速率 ≤ 115.2 kbps。用于早期的手机、笔记本红外数据传输。
2hUART 16x 自动波特率模式在标准UART模式下,增加自动检测对方波特率的功能(1200 bps - 115.2 kbps)。常用于需要自适应不同设备的场景,如Bootloader。
3hUART 13x 模式内部采样时钟为波特率的13倍。某些老式或特定标准的设备需要此模式以保证兼容性。
4hMIR 模式中速红外模式,支持 0.576 Mbps 和 1.152 Mbps。
5hFIR 模式高速红外模式,支持 4 Mbps。用于高速IrDA设备间的大文件传输。
6hCIR 模式消费红外遥控模式。支持可编程的载波频率和占空比,用于发射和接收遥控信号。
7h禁用模式模块复位后的默认状态,或需要彻底关闭模块以省电时设置。

实操心得一:模式切换的“静默期”在通过写MDR1寄存器切换模式(尤其是进出禁用模式7h)时,必须确保当前没有正在进行的数据传输。一个稳妥的流程是:1) 等待发送FIFO和移位寄存器完全清空(通过查询LSR[6]和LSR[5]);2) 可选地,禁用收发器或相关中断;3) 写入MDR1切换模式;4) 根据需要重新配置新模式下的参数(如波特率、FIFO等);5) 最后再使能收发。直接粗暴地在通信中途切换模式,极大概率会导致总线挂死或产生错误帧。

2.3 引脚复用与信号管理

模块的物理引脚是复用的,具体输出什么信号完全由当前模式决定。这是理解硬件连接的关键。

  • TX: 仅在UART模式下作为串行数据输出。在其他模式下,该引脚被强制为复位值(高电平),处于无效状态。
  • IRTX: 在IrDA模式(SIR/MIR/FIR)下作为红外数据输出。注意,这是已经过调制的红外发射管驱动信号,而非TTL电平。
  • RCTX: 在CIR模式下作为消费红外遥控编码输出。
  • RX:所有模式的串行数据输入。这意味着,无论处于何种模式,接收通路都会监听RX引脚。但在IrDA模式下,接收到的需是已解调后的数字信号(通常由外部红外接收头完成)。
  • RTS/CTS, DTR/DSR等: 这些硬件流控和调制解调器信号主要在UART模式下使用。

这种设计意味着,在硬件PCB布局时,需要根据最终应用场景,将TX/IRTX/RCTX这三个输出引脚连接到不同的驱动电路:TX可能直接接电平转换芯片(如MAX3232);IRTX需要接红外发射二极管及其驱动三极管;RCTX则接遥控发射电路。

注意事项:外部电路匹配当使用IrDA或CIR模式时,绝对不能简单地将IRTXRCTX引脚直接连接到UART电平的RX引脚上。IrDA模式输出的是经过3/16或1.6us脉冲调制的信号,必须通过标准的IrDA收发器芯片(如TFDU4101)或分立元件电路进行调制解调。CIR模式同理,需要匹配遥控接收头的载波频率。

3. UART模式深度配置与流控制实战

3.1 数据帧格式与波特率生成

UART的通信基础是帧。一帧数据包括起始位、数据位(5-8位)、可选的奇偶校验位和停止位(1, 1.5, 2位)。所有这些都由线路控制寄存器(LCR)配置。

波特率的设置则依赖于除数锁存器(DLL 和 DLH)。计算公式为:波特率 = 参考时钟频率 / (16 * 除数)其中,除数 = DLH << 8 | DLL。例如,在48 MHz参考时钟下,要得到115200 bps的波特率,除数 = 48,000,000 / (16 * 115200) = 26.0417 ≈ 26。因此,需设置DLL = 26 (0x1A)DLH = 0。实际波特率会有微小误差,为 48,000,000 / (16 * 26) ≈ 115384.6 bps,误差约0.07%,在异步通信允许的范围内。

避坑指南:访问DLL/DLH的“钥匙”DLLDLHLCR寄存器共享同一个地址。为了区分,芯片设计了一个“开关”:LCR[7]���,即除数锁存访问位(DLAB)。当DLAB=1时,访问的是DLL/DLH;当DLAB=0时,访问的是RHR/THR(接收/发送保持寄存器)和IER(中断使能寄存器)。因此,设置波特率的正确顺序是:1) 设置LCR[7]=1;2) 写入DLLDLH;3) 清除LCR[7]=0,以恢复正常的数据收发和中断配置访问。忘记切换DLAB是新手配置波特率失败的最常见原因。

3.2 硬件流控制(Auto-RTS/Auto-CTS)精讲

硬件流控制是保证高速或大数据量通信不丢数据的“保险丝”。其核心思想是让接收方通过RTS(请求发送)信号告诉发送方“我快满了,暂停发送”,通过CTS(清除发送)信号告诉发送方“我准备好了,可以发送”。

3.2.1 Auto-RTS(自动请求发送)此功能由接收方控制。模块内部会监控接收FIFO(RX FIFO)的数据量。

  • 启动条件:当RX FIFO中的数据量低于TCR[3:0]寄存器设定的HALT阈值时,RTS引脚自动被拉低(有效),向对方发送“可以发送”的信号。
  • 停止条件:当RX FIFO被填满,达到HALT阈值时,RTS引脚自动拉高(无效),通知对方“暂停发送”。
  • 恢复条件:当程序从RX FIFO中读取数据,使其数据量降至TCR[7:4]设定的RESUME阈值以下时,RTS引脚再次自动拉低,请求对方恢复发送。

这个过程完全由硬件自动完成,无需CPU干预。关键在于合理设置HALTRESUME阈值。通常,HALT应设置为略小于FIFO深度(如60/64),为后续可能到达的数据留出缓冲;RESUME应设置得足够低(如16/64),以确保在恢复发送后,有足够的空间接收一个数据包,避免频繁的启停。

3.2.2 Auto-CTS(自动清除发送)此功能由发送方监听。在发送每个字节之前,发送逻辑会检查CTS引脚的状态。

  • 允许发送:仅当CTS引脚为低电平(有效)时,发送器才会从TX FIFO中取出下一个字节发送。
  • 停止时机:如果对方想让我方停止发送,它必须在当前正在发送字节的停止位中点之前CTS拉高。发送器检测到CTS无效后,会在完成当前字节的发送后停止。

这意味着CTS信号的变化需要满足一定的时序要求。如果对方反应太慢,在我方已经开始发送下一个字节的起始位后才拉高CTS,那么这个字节仍然会被发出,可能导致对方溢出。

实操心得二:硬件流控的布线“陷阱”硬件流控要生效,必须确保RTSCTS交叉连接(本机的RTS接对端的CTS,本机的CTS接对端的RTS)。我见过不止一个项目因为将RTS-CTS直连而导致流控失效。此外,有些简化版的USB转串口线或蓝牙模块可能并未引出真正的硬件流控引脚,即使你配置了寄存器也不会有效果。在调试阶段,可以用示波器或逻辑分析仪同时抓取TXRXRTSCTS四根线,直观地观察流控信号与数据流的互动,这是排查流控问题最直接的方法。

3.3 软件流控制(XON/XOFF)与高级特性

当硬件流控引脚不可用时,软件流控是备选方案。它通过插入特殊的控制字符(XOFF: 0x13, XON: 0x11,通常可编程)到数据流中来控制传输。

  • 发送XOFF:当本机(接收方)的RX FIFO达到TCR[3:0]设定的阈值时,会自动向对方(发送方)发送XOFF1XOFF2字符(如果使能了双字符)。
  • 发送XON:当本机程序从RX FIFO中读取数据,使数据量低于TCR[7:4]设定的恢复阈值时,会自动发送XON1XON2字符。

这里有两个高级特性值得注意:

  1. XON Any功能MCR[5]):使能后,在收到XOFF暂停后,接收到任何字符(而不仅仅是约定的XON)都会恢复传输。这增加了灵活性,但也可能因数据中偶然出现XOFF字符而导致意外暂停。通常建议关闭此功能,除非协议有特殊要求。
  2. 特殊字符检测EFR[5]):使能后,模块会将接收到的数据与XOFF2字符进行比较。如果匹配,它会触发一个中断(IIR[4]),但不会停止传输。这可以用于在数据流中嵌入“带外”的控制信令。

注意事项:软件流控的字符过滤默认情况下,被识别为XON/XOFF的流控字符不会被存入RX FIFO,它们被硬件“吃掉”了。这保证了上层协议看不到这些控制字符。但是,如果使能了“XON Any”或配置为需要连续接收两个字符(如XON1+XON2)而只收到了第一个,那么第一个字符是会被写入FIFO的。理解这一点对解析应用层协议至关重要。

4. IrDA与CIR模式工作原理及配置要点

4.1 IrDA SIR模式:从字节到红外脉冲

IrDA SIR模式可以理解为在标准UART的字节流之上,包裹了一层红外专用的帧封装、透明化处理和物理层调制

4.1.1 帧结构一个完整的SIR帧不是裸数据,它包含:

  • 起始标志(BOF):至少一个0xC0字节,用于帧同步。
  • 地址(A)与控制(C)域:各1字节,用于链路管理(在简单点对点通信中常被忽略)。
  • 信息域(I):可变长度的实际数据。
  • CRC-16校验:2字节,校验A、C、I域。
  • 结束标志(EOF):一个0xC1字节。

硬件会自动为发送的数据添加BOF、CRC和EOF,并在接收时剥离它们,将纯净的A、C、I域数据(以及CRC值)放入RX FIFO。开发者只需关心信息域的数据。

4.1.2 异步透明化(Asynchronous Transparency)由于BOF (0xC0) 和 EOF (0xC1) 被用作帧边界,那么如果数据域中恰好包含0xC00xC1怎么办?此外,还有一个转义字符0x7D。IrDA协议使用了一种称为“异步透明化”的机制:

  • 发送时:如果待发送的字节是0xC0,0xC1, 或0x7D,硬件会先发送一个转义字符0x7D,然后将原字节的第5位取反(与0x20异或),再发送这个修改后的字节。
  • 接收时:如果收到0x7D,则将其丢弃,并将紧随其后的字节的第5位取反,恢复出原始数据。

这个过程完全由硬件完成,对软件透明。但需要注意的是,用于CRC计算的数据是原始数据(转义前)

4.1.3 物理层编码:3/16 vs 1.6μs这是SIR模式最核心的物理差异,由ACREG[7] (PULSETYPE)位选择。

  • 3/16编码(默认/常用):将一个逻辑“0”编码为一个占空比为3/16个位周期的红外脉冲。例如,在115200 bps下,位周期约8.68 μs,脉冲宽度约为1.63 μs。逻辑“1”则不发射脉冲。
  • 1.6 μs编码:无论波特率是多少,逻辑“0”都被编码为一个固定宽度约1.6 μs的红外脉冲。

绝大多数标准IrDA设备都使用3/16编码。1.6 μs编码主要用于一些早期的、非标准的设备。务必确保通信双方的编码方式一致,否则无法解码。

4.2 CIR模式:遥控器信号的“翻译官”

CIR模式的设计目标非常专一:生成和解析消费电子红外遥控信号。这类信号的特点是用特定频率(通常38kHz)的载波对数据位进行脉冲宽度(PWM)或脉冲位置(PPM)调制。

4.2.1 核心原理CIR模式不再发送UART标准的起始位+数据位+停止位格式,而是允许你定义一个完全自定义的帧结构。你可以通过寄存器配置:

  • 载波频率:例如38kHz、36kHz、40kHz等。
  • 载波占空比:1/2, 5/12, 1/3, 或 1/4。这决定了载波脉冲的宽度。
  • 位编码:通过定义逻辑“0”和逻辑“1”分别对应多少个“时间单元”(t周期)的高电平和低电平,来模拟各种遥控协议(如NEC、RC-5、Sony SIRC等)。

4.2.2 配置流程简述

  1. 选择CIR模式:设置MDR1[2:0] = 6h
  2. 配置载波:通过相关寄存器(如CIR_PWCIR_DUTY)设置载波周期和占空比。
  3. 定义帧结构:通常需要配置引导码(Leader)的时长、逻辑“0”和“1”的脉冲/空格时长、以及结束条件。这可能需要组合多个寄存器,具体需参考芯片手册的CIR章节。
  4. 填充数据:将遥控命令码(如地址码、命令码)写入TX FIFO,硬件会按照你定义的帧结构和载波,从RCTX引脚输出调制好的红外波形。

CIR模式的灵活性极高,但配置也相对复杂,通常需要对照目标遥控器的协议说明书,用示波器抓取原始波形,然后反推出各个时间参数进行配置。

5. 看门狗定时器(WDT)在通信模块中的角色与配置

在提供的资料片段中,出现了大量以WDT_开头的寄存器。需要明确的是,看门狗定时器(WDT)是一个独立于UART/IrDA/CIR模块的外设,它们通常在同一芯片的不同章节描述。但为什么在通信模块的文档中会提到它?因为一个稳定的通信系统,尤其是用于控制或长时间运行的设备,必须考虑“死机”或“程序跑飞”的风险。WDT就是最后的“保险丝”。

5.1 WDT核心寄存器精讲

WDT本质上是一个递减计数器,需要软件定期“喂狗”(重置计数器)。如果超时未喂狗,WDT会产生复位信号重启系统。我们来看关键寄存器:

  • WDT_WLDR (Load Register)装载值寄存器。这里存放的是计数器的初始值。系统复位后或喂狗后,计数器会从这个值开始递减。例如,如果输入时钟是32.768 kHz,设置WLDR = 32768,那么超时时间就是 32768 / 32768 Hz = 1秒。
  • WDT_WCRR (Counter Register)计数器当前值寄存器。这是一个只读寄存器(从描述看是R/W,但通常写入用于特定操作,如快速喂狗),实时反映了递减计数器的当前值。调试时读取它可以判断系统“健康”程度。
  • WDT_WTGR (Trigger Register)触发寄存器。这是喂狗的关键。向该寄存器写入一个与当前值不同的值,就会触发计数器重载(从WLDR重新开始计数)。为了防止误操作,通常采用“写入特定序列”的方式,比如先写0xAAAA,再写0x5555,具体序列需查手册。
  • WDT_WWPS (Write Posting Status Register)写提交状态寄存器。这是一个非常重要的安全机制。在某些高性能处理器中,对寄存器的写入可能不会立即生效,而是进入一个写缓冲区。WWPS的各个位(如W_PEND_WLDR,W_PEND_WTGR)指示对应寄存器的写入操作是否还在“提交中”(pending)。在写入关键寄存器(如WLDR、WTGR)后,必须轮询WWPS中对应的位,直到其变为0,才能确保写入生效。忽略这一步是导致喂狗失败、意外复位的常见原因。
  • WDT_WIRQSTATRAW/WIRQSTAT/WIRQENSET/WIRQENCLR中断状态与控制寄存器组。WDT除了产生复位,还可以在计数器溢出(EVENT_OVF)或达到预置的延迟值(EVENT_DLY)时产生中断。RAW是原始状态(无论中断是否使能),STAT是使能后的状态,ENSETENCLR用于使能和禁用中断。这允许软件在系统复位前得到一个“最后警告”,尝试进行紧急日志保存或状态恢复。

5.2 通信场景下的WDT集成策略

在通信系统中,WDT的集成需要精心设计:

  1. 超时时间设定:要远大于最坏情况下的通信周期。例如,如果每100ms发送一次心跳包,那么WDT超时应设为500ms-1s,为网络延迟、处理耗时留出余量。
  2. 喂狗点选择绝对不要在UART发送或接收中断服务程序(ISR)中喂狗。因为如果通信链路故障(如线被拔掉),接收中断可能永远无法触发,导致即使主程序正常,也会因喂狗中断而复位。正确的做法是在主循环或一个独立的、周期性的定时器任务中喂狗,该任务的条件是“通信状态机健康”,而非“收到数据”。
  3. 利用预溢出中断:可以启用EVENT_DLY中断,其触发时间早于最终复位时间。在这个中断里,可以尝试复位通信外设、重新初始化链路、或上报严重错误,给系统一个“自救”的机会。
  4. 调试与禁用:在早期软件调试阶段,尤其是调试UART驱动本身时,可以先禁用WDT(如果支持),或将其超时设得非常长,避免频繁的无关复位干扰调试过程。

踩坑实录:WWDPS的“幽灵”写入我曾调试过一个案子,系统偶尔会莫名其妙地复位。日志显示喂狗逻辑执行了。最后用调试器跟踪寄存器写操作才发现,问题出在WWTGR的写入上。代码是WDT->WTGR = 0xAAAA;然后WDT->WTGR = 0x5555;。但在写入后没有检查WWPS。在高负载或某些特殊指令序列下,第二次写入可能因为CPU流水线或总线调度,在第一次写入尚未提交到WDT模块时就发生了,导致WDT模块识别为“两次写入值相同”,喂狗失败。教训是:任何对WDT关键寄存器的写入,之后必须同步(如插入内存屏障指令DSB)并轮询WWPS确认。

6. 完整配置流程与问题排查指南

6.1 UART初始化标准流程(带FIFO与中断)

结合手册中的“配置示例”,一个稳健的UART初始化流程如下:

// 假设基地址为 UART_BASE void UART_Init(uint32_t baudrate, uint8_t data_bits, uint8_t parity, uint8_t stop_bits) { // 步骤1: 软件复位与模块禁用 // 访问EFR需要先设置LCR为0xBF REG_WRITE(UART_BASE + LCR_OFFSET, 0xBF); // LCR[7]=1, 访问EFR/IER REG_WRITE(UART_BASE + EFR_OFFSET, 0x10); // 设置EFR[4]=1,使能访问IER/MCR REG_WRITE(UART_BASE + LCR_OFFSET, 0x00); // LCR[7]=0,恢复正常访问 REG_WRITE(UART_BASE + IER_OFFSET, 0x00); // 禁用所有中断 REG_WRITE(UART_BASE + MCR_OFFSET, 0x00); // 强制Modem控制信号无效 // 清除可能的线路中断状态 REG_WRITE(UART_BASE + LCR_OFFSET, 0x80); // 设置LCR[6]=0 (Break无效) REG_WRITE(UART_BASE + MDR1_OFFSET, 0x07); // 模块禁用/复位 // 步骤2: FIFO与流控阈值配置 REG_WRITE(UART_BASE + LCR_OFFSET, 0xBF); // 再次进入EFR访问模式 REG_WRITE(UART_BASE + EFR_OFFSET, 0x10); // EFR[4]=1 REG_WRITE(UART_BASE + LCR_OFFSET, 0x00); REG_WRITE(UART_BASE + MCR_OFFSET, 0x20); // 设置MCR[6]=1,使能访问TCR/TLR // 配置FIFO:使能FIFO,设置RX/TX触发级别(例如14字节) REG_WRITE(UART_BASE + FCR_OFFSET, 0xC7); // 0xC7: 使能FIFO,RX FIFO复位,TX FIFO复位,触发级14字节 // 配置硬件流控阈值 (示例:HALT=56, RESUME=16) REG_WRITE(UART_BASE + TCR_OFFSET, 0x1038); // TCR[7:4]=0x10(16), TCR[3:0]=0x38(56) // 配置软件流控阈值 (如果需要) // REG_WRITE(UART_BASE + TLR_OFFSET, ...); // 关闭特殊寄存器访问 REG_WRITE(UART_BASE + LCR_OFFSET, 0xBF); REG_WRITE(UART_BASE + EFR_OFFSET, 0x00); // EFR[4]=0 REG_WRITE(UART_BASE + LCR_OFFSET, 0x00); REG_WRITE(UART_BASE + MCR_OFFSET, 0x00); // MCR[6]=0 // 步骤3: 配置波特率与数据格式 uint32_t divisor = SYSTEM_CLOCK / (16 * baudrate); uint8_t lcr_config = 0x00; // 设置数据位 (假设8位) lcr_config |= 0x03; // 设置停止位 (假设1位) // lcr_config |= 0x00; // 设置奇偶校验 (假设无校验) // lcr_config |= 0x00; // 更复杂的格式配置在此进行... // 先设置DLAB=1以访问波特率分频器 REG_WRITE(UART_BASE + LCR_OFFSET, lcr_config | 0x80); REG_WRITE(UART_BASE + DLL_OFFSET, divisor & 0xFF); REG_WRITE(UART_BASE + DLH_OFFSET, (divisor >> 8) & 0xFF); // 清除DLAB,设置最终数据格式 REG_WRITE(UART_BASE + LCR_OFFSET, lcr_config); // 步骤4: 使能中断(如果需要) // REG_WRITE(UART_BASE + IER_OFFSET, IER_RHR_MASK | IER_THR_MASK ...); // 步骤5: 使能UART模块 REG_WRITE(UART_BASE + MDR1_OFFSET, 0x00); // 进入UART 16x模式 }

6.2 常见问题排查速查表

现象可能原因排查步骤与解决方案
完全无收发1. 模块未使能(MDR1=7)。
2. 波特率严重错误。
3. 引脚复用错误,TX未输出。
4. 硬件线路断开。
1. 确认MDR1[2:0]=0
2. 用示波器测量TX引脚,看是否有任何波形。计算并核对波特率分频值。
3. 检查芯片引脚复用配置,确保该引脚功能已映射到UART。
4. 检查物理连接。
能发不能收,或反之1. 收发引脚接反(TX-RX交叉)。
2. 对方设备故障或未上电。
3. 本机或对方流控信号钳制了总线。
1.这是最常见原因!确认TX接对方RX,RX接对方TX。
2. 测量对方TX引脚是否有输出。
3. 测量RTS/CTS电平,尝试在初始化时禁用硬件流控(EFR[7:6]=0)。
数据错乱(乱码)1. 波特率不匹配(微小误差累积)。
2. 数据格式不匹配(数据位、停止位、校验位)。
3. 电气干扰,电平不标准。
1. 双方使用同一时钟源并精确计算分频值。使用示波器测量位宽度验证波特率。
2. 双方核对LCR配置,必须完全一致。
3. 检查电平转换芯片供电,测量信号幅值,在长距离时考虑使用差分RS-485。
通信一段时间后死机1. 接收FIFO溢出。
2. 中断服务程序(ISR)未及时清除中断标志。
3. 看门狗超时复位。
1. 检查LSR[1](溢出错误位)。优化程序,及时读取RHR,或使能/正确配置硬件流控。
2. 在UART ISR中,读取IIR并处理所有挂起的中断源。
3. 检查WDT配置和喂狗逻辑,确认喂狗周期小于超时时间。
IrDA通信距离极短或不通1. 编码方式不匹配(3/16 vs 1.6us)。
2. 红外发射管驱动电流不足。
3. 接收头载波频率不匹配(CIR模式)。
4. 环境光干扰太强。
1. 确认双方ACREG[7]设置一致,推荐使用3/16。
2. 检查发射管限流电阻,适当减小电阻以增大电流(但勿超规格)。
3. 用示波器观察IRTX和接收头输出波形,确认载波频率。
4. 避免阳光直射,或使用带滤波的接收头。
硬件流控无效1. RTS和CTS未交叉连接。
2. 流控未在双方使能。
3. 阈值(TCR)设置不合理。
4. 使用的串口线/转换器不支持硬件流控。
1. 确认连接:本机RTS接对方CTS,本机CTS接对方RTS。
2. 确认双方EFR[7:6]已正确设置(如0x03使能自动RTS和CTS)。
3. 调整TCR的HALT和RESUME值。
4. 更换真正支持RTS/CTS的串口线或模块。

调试串口通信,示波器或逻辑分析仪是最得力的工具。不要只依赖打印日志。抓取TX/RX的实际波形,可以直观地看到起始位、数据位、停止位是否完整,波特率是否准确,流控信号是否及时响应,很多问题会一目了然。

最后,再分享一个关于FIFO触发级别的经验:对于高速或大数据量传输,将RX FIFO触发级别设得低一些(例如8或16字节),可以更频繁地触发中断或DMA请求,降低单次处理的延迟,避免因处理不及时导致的溢出。而对于低速率或对实时性要求不高的场景,可以设高一些(如56字节),减少中断次数,降低CPU负载。这需要根据具体应用场景做权衡。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询