news 2026/6/13 13:34:58

MC9328MX1 UART寄存器深度解析:从配置到中断与流控实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MC9328MX1 UART寄存器深度解析:从配置到中断与流控实战

1. 项目概述与核心价值

在嵌入式开发的日常里,串口(UART)调试和通信几乎是每个工程师都绕不开的“老朋友”。从最简单的打印日志,到复杂的设备间协议通信,UART的稳定性和效率直接关系到整个系统的可靠性和响应速度。然而,很多开发者对UART的认知可能还停留在“配置波特率、数据位、停止位”的层面,一旦遇到数据丢失、中断响应不及时或者流控制失效等问题,往往只能靠“玄学调试”或者降低波特率来妥协。

今天,我们就以Freescale(现NXP)的经典ARM9芯片MC9328MX1为例,彻底拆解其UART模块的控制寄存器。这份手册节选虽然看起来是冰冷的寄存器位描述,但背后隐藏的是一套完整的、工业级的串口通信解决方案。理解它,你就能从“会用串口”进阶到“精通串口”,知道每一个配置位背后的设计意图,能在出现问题时精准定位是硬件流控的阈值设错了,还是FIFO中断的触发条件没配好,亦或是某个错误标志位没有及时清除导致中断卡死。

MC9328MX1的UART外设功能相当丰富,远不止基础收发。它支持硬件流控(RTS/CTS)、可编程的发送/接收FIFO及其触发中断、多种错误检测与中断(奇偶校验错、帧错误、溢出)、甚至包括红外编码(IrDA)和自动波特率检测等高级功能。这些功能全都通过一系列控制寄存器(UCR2, UCR3, UCR4, UFCR)和状态寄存器(USR1, USR2)来配置和监控。本文将聚焦于这些控制与状态寄存器的配置逻辑和中断管理机制,为你呈现一份可以直接用于驱动开发的“寄存器级”指南。无论你是正在为这款老芯片维护遗产代码,还是想通过它来深入理解UART外设的设计哲学,这篇文章都将提供十足的干货。

2. UART控制寄存器深度解析与配置逻辑

要驾驭MC9328MX1的UART,不能孤立地看某个寄存器,必须建立起寄存器组之间协同工作的整体视图。其配置流程通常遵循一个清晰的层次:先进行全局和通道使能,再设置通信参数,接着配置FIFO与中断,最后处理高级功能(如流控、红外)。下面我们以最核心的UART控制寄存器2(UCR2)为起点,层层深入。

2.1 UART控制寄存器2(UCR2):通信基础与核心使能

UCR2是UART的“总开关”和“格式设定器”。它的复位值是0x0001,唯一一个置1的位是SRST(软件复位),这暗示着硬件上电后,UART模块默认处于复位状态,需要软件将其清零后才能开始工作。

关键位域详解与配置策略:

  1. SRST (Bit 0): 软件复位

    • 功能:写入0会复位发射器、接收器的状态机、所有FIFO和状态寄存器。持续4个IPG_CLK周期后,硬件会自动将其置1。
    • 实操要点:这是配置UART的第一步。在修改任何关键参数(如波特率分频器、字长、FIFO模式)之前,强烈建议先拉低SRST(写0),完成配置后再将其置1(实际上硬件会自动完成,软件只需写0触发)。这可以确保状态机从一个干净的状态启动,避免因残留状态导致的数据错乱。手册明确警告,在传输或接收过程中改变字长(WS位)会导致当前字符长度不可预测,因此在动态调整参数前使用SRST复位是稳妥的做法。
  2. RXEN (Bit 1) / TXEN (Bit 2): 接收/发送使能

    • 功能:分别控制接收器和发射器的开启。这两个位需要和更高层的UART使能位(通常在UCR1中,手册未在此节给出)配合使用。
    • 配置顺序:典型的启动顺序是:使能UART时钟 -> 配置UCR1(全局使能等)-> 配置UCR2(格式、使能)-> 清除SRST -> 使能RXEN/TXEN。关闭时,则建议先禁用RXEN/TXEN,再进行其他配置。特别注意,如果在中途禁用TXEN,发射器会立即停止并开始发送“1”(Mark位),这可能导致一个不完整的帧被发送出去。
  3. WS (Bit 5): 字长选择

    • 功能:0 = 7位数据;1 = 8位数据。这里的数据位不包括起始位、停止位和校验位。
    • 注意事项:如前述,绝对不要在数据传输或接收过程中更改此位。必须在通信空闲时,结合SRST复位操作进行更改。
  4. STPB (Bit 6): 停止位

    • 功能:0 = 1个停止位;1 = 2个停止位。此位仅影响发送方。接收方总是期望至少1个停止位。在大多数标准通信中(如115200-8-N-1),此处应配置为0。
  5. PREN (Bit 8) / PROE (Bit 7): 校验使能与奇偶选择

    • 功能:PREN使能校验功能,PROE决定是奇校验(1)还是偶校验(0)。
    • 配置逻辑:通常PREN和PROE需要配对设置。例如,偶校验:PREN=1, PROE=0;奇校验:PREN=1, PROE=1;无校验:PREN=0, PROE值忽略。
  6. RTSEN (Bit 4) / IRTS (Bit 14) / CTSC (Bit 13) / CTS (Bit 12): 硬件流控制

    • 这是最容易出错的地方之一。MC9328MX1的硬件流控非常灵活。
    • RTS (Request to Send) 输出控制
      • RTSEN=1:使能RTS引脚的中断功能(边沿检测)。RTEC位(Bit 10-9)选择触发边沿。
      • IRTS=1忽略外部输入的RTS信号。此时UART会认为RTS始终有效(低电平),可以一直发送。UARTx_RTS引脚变成一个普通输入引脚。IRTS=0时,发送器会侦听外部RTS引脚,只有其为低电平(有效)时才发送数据。
    • CTS (Clear to Send) 输出控制
      • CTSC=1:CTS引脚由接收器自动控制。当RxFIFO中的数据达到CTSTL(在UCR4中设置)设定的触发水平时,CTS引脚会自动变高(无效),通知对端停止发送。这是最常用的自动流控模式。
      • CTSC=0:CTS引脚由软件通过CTS位(Bit 12)手动控制。软件写1使CTS有效(低电平,允许对端发送),写0使其无效。
    • 典型自动流控配置IRTS=0(侦听外部RTS),CTSC=1(CTS自动控制)。同时,需要正确配置UCR4中的CTSTL,设定接收FIFO的“警戒水位”。
  7. ESCEN (Bit 11) / ESCI (Bit 15): 转义序列检测

    • 功能:用于在数据流中检测特定的“转义字符”(在UESC寄存器中定义),常用于实现带内协议控制。ESCEN使能检测逻辑,ESCI使能检测到转义序列时产生中断。
    • 应用场景:在某些自定义协议中,可以用转义序列来打断正常数据流,插入命令。需要配合UTIM(转义定时器)寄存器设置字符间超时时间。

配置示例:假设我们需要配置UART1为115200波特率(需另外计算并设置波特率寄存器UBMR和UBIR)、8位数据、无校验、1停止位、使能自动CTS流控(RTS由外部控制)。UCR2的配置值计算如下:

  • SRST=1 (操作顺序上,我们先配其他位,最后处理SRST)
  • RXEN=1, TXEN=1
  • RTSEN=0 (我们不使用RTS边沿中断)
  • WS=1 (8位)
  • STPB=0 (1停止位)
  • PREN=0, PROE=0 (无校验)
  • CTSC=1 (CTS自动控制)
  • CTS=0 (CTSC=1时此位无效)
  • IRTS=0 (侦听外部RTS)
  • ESCEN=0, ESCI=0 (禁用转义序列)
  • 其他保留位为0。 假设我们通过软件先将SRST写0复位,再写1退出复位。那么最终写入UCR2寄存器的值可能是:0x4025(二进制 0100 0000 0010 0101)。注意,这个值是在SRST已为1的情况下。实际编程中,我们通常会先读取当前值,修改目标位,再写回。

2.2 UART控制寄存器3(UCR3):中断使能与特殊功能

UCR3主要管理各种中断的使能,并且UART1和UART2/3的UCR3有细微差别(UART2/3多了DTR/DSR/DCD/RI等调制解调器接口控制位)。我们以共有的部分进行说明。

核心中断使能位:

  1. PARERREN (Bit 12) / FRAERREN (Bit 11): 奇偶校验错与帧错误中断使能

    • 当接收到的字符出现奇偶校验错误或帧错误(如缺少有效的停止位)时,对应的状态位(USR1中的PARITYERR和FRAMERR)会被置位。如果这里使能了相应中断,就会产生UART_MINT_PFERR中断。
    • 调试经验:在开发初期,强烈建议使能这两个中断。一旦通信出现错乱,它们能帮你快速定位是噪声干扰(可能引发帧错误)还是双方校验配置不一致。在稳定运行的系统中,如果通信环境良好且协议有上层校验,可以考虑关闭以减轻中断负载。
  2. RXDSEN (Bit 6): 接收器空闲中断使能

    • 当接收器空闲(RXD线持续为高电平)超过一个字符帧的时间时,USR1中的RXDS位会置1。使能此中断后,可用于检测通信链路断开或数据传输结束。这在半双工通信或需要判断对方是否发送完毕的场景下很有用。
  3. REF25/REF30/REF16(在UCR4中): 参考时钟频率指示

    • 这些位(UCR3的Bit3, Bit2和UCR4的Bit6)用于指示UART模块的输入参考时钟频率是16MHz、25MHz还是30MHz。这个配置必须与实际的IPG_CLK分频后供给UART的时钟频率严格一致,否则波特率计算将完全错误。这是很多初学者容易忽略的硬件关联配置。

UART2/3特有的调制解调器控制位(Bit13-8): 对于需要连接调制解调器或模拟 modem 控制的场景,DTREN、DPEC、DSR、DCD、RI 这些位提供了完整的硬件握手信号控制。例如,DTRENDPEC可以配置DTR引脚上的边沿中断,用于响应远端设备的状态变化。

2.3 UART控制寄存器4(UCR4)与FIFO控制寄存器(UFCR):流控与中断触发核心

这两个寄存器是实现高效、可靠数据吞吐的关键,它们共同决定了何时产生中断,如何控制流控。

UCR4 关键位解析:

  1. CTSTL (Bits 15-10): CTS触发水平

    • 功能:当CTSC=1(CTS自动控制)时,此字段定义接收FIFO(RxFIFO)的“警戒水位”。当RxFIFO中的数据量达到或超过这个阈值时,CTS引脚会自动变为高电平(无效),通知对端“暂停发送”。
    • 配置策略:这个值需要权衡。设得太小(如1或2),流控会过于频繁,影响吞吐效率。设得太大,则可能导致FIFO溢出前来不及阻止对端,造成数据丢失。一个经验值是设置为RxFIFO深度(32)的一半或三分之二,例如16或20。公式为:CTSTL = 期望的字符数。例如,设置为16(二进制010000),则当RxFIFO中有16个字符时,CTS变高。
  2. DREN (Bit 0) / OREN (Bit 1) / BKEN (Bit 2) / TCEN (Bit 3): 接收/发送中断使能

    • DREN:接收数据就绪中断使能。当RxFIFO中有数据(RDR=1)时触发。
    • OREN:接收溢出错误中断使能。当RxFIFO已满但还收到新数据时触发。
    • BKEN:Break条件中断使能。当检测到Break信号(RXD线持续低电平超过一个帧时间)时触发。
    • TCEN:发送完成中断使能。当发送FIFO和移位寄存器完全空(TXDC=1)时触发。
    • 中断管理逻辑:这些中断最终会汇聚到少数几个中断向量上(如UART_MINT_RX,UART_MINT_TX,UART_MINT_UARTC)。你需要查阅芯片的中断控制器章节,了解如何映射和区分这些中断源。例如,DRENOREN都可能触发UART_MINT_RX相关中断,需要在中断服务程序(ISR)中读取USR1/USR2来判别具体原因。

UFCR 关键位解析:

  1. RXTL (Bits 5-0): 接收FIFO触发水平

    • 功能:定义产生接收中断的阈值。当RxFIFO中的数据量达到此阈值时,RRDY位(USR1 Bit 9)置位,如果DREN使能,则产生中断。
    • 与CTSTL的区别RXTL何时通知CPU来取数据CTSTL何时通知对端停止发数据。通常RXTL会设置得比CTSTL小。例如,RXTL=8(收到8个字节就中断),CTSTL=24(收到24个字节才让对端暂停)。这样给CPU留出了处理中断、读取数据的时间窗口,避免FIFO被填满。
  2. TXTL (Bits 15-10): 发送FIFO触发水平

    • 功能:定义产生发送中断的阈值。当TxFIFO中的数据量低于此阈值时,TRDY位(USR1 Bit 13)置位,如果发送中断使能(通常通过UCR1),则产生中断,通知CPU可以填充更多数据。
    • 配置策略:为了提高发送效率,避免发送器空转,通常将TXTL设为一个较小的值,比如4。这意味着当TxFIFO中剩余数据少于4个时,就请求CPU补充数据。结合DMA(直接内存访问)使用效果更佳,可以设置DMA请求与TRDY信号联动。
  3. RFDIV (Bits 9-7): 参考时钟分频器

    • 功能:对输入时钟IPG_CLK进行分频,产生UART内部参考时钟。这是计算波特率的第一步
    • 计算公式UART_REF_CLK = IPG_CLK / (RFDIV值对应的除数)。除数选择:000=/6, 001=/5, 010=/4, 011=/3, 100=/2, 101=/1, 110=/7。
    • 与REF[16|25|30]的关系REF[16|25|30]位指示的是UART_REF_CLK的频率,用于波特率计算模块。因此,你需要根据系统主频和期望的波特率,先选择RFDIV得到一个合适的UART_REF_CLK,然后设置对应的REFx位,最后再计算波特率分频值写入UBMR/UBIR。

配置流程总结: 一个完整的UART初始化配置,特别是涉及FIFO和中断的,应遵循以下顺序:

  1. 禁用UART(通过UCR1等全局控制位)。
  2. 设置SRST=0进行软件复位。
  3. 配置波特率寄存器(UBMR, UBIR),这需要先确定RFDIVREFx
  4. 配置UCR2(数据格式、基本使能)。
  5. 配置UFCR(FIFO触发水平、参考时钟分频)。
  6. 配置UCR4(CTS触发水平、各类错误中断使能)。
  7. 配置UCR3(其他特定中断使能)。
  8. 清除所有状态寄存器(USR1, USR2)中的标志位(写1清除)。
  9. SRST位写0再自动变1,退出复位状态。
  10. 使能UART全局开关(UCR1)和接收/发送使能(UCR2的RXEN/TXEN)。
  11. 使能所需的中断(在UCR3/UCR4中,以及芯片的中断控制器中)。

3. 状态寄存器解析与中断服务程序设计要点

配置好控制寄存器只是开始,在中断驱动模式下,服务程序(ISR)如何高效、正确地处理状态寄存器中的标志位,才是稳定性的关键。MC9328MX1的UART状态信息分布在USR1和USR2两个寄存器中。

3.1 状态寄存器USR1:实时通信状态

USR1反映了通信过程中的即时状态和错误。

  • RRDY (Bit 9): 接收就绪

    • 这是最常用的中断源。当RxFIFO中的数据量达到RXTL设定的阈值时,此位置1。在ISR中,应循环读取数据寄存器(URXD),直到RRDY自动清除(表示FIFO数据已低于阈值)。注意:读取数据寄存器时,要同时读取其中的CHARRDY位(在数据寄存器中),以确保读取的数据是有效的。
  • TRDY (Bit 13): 发送就绪

    • 当TxFIFO中的数据量低于TXTL设定的阈值时,此位置1。在ISR中,应继续向数据寄存器(UTXD)写入数据,直到填满FIFO或待发送数据写完。写入操作会使TRDY在数据量超过阈值后自动清零。
  • FRAMERR (Bit 10) / PARITYERR (Bit 15): 帧错误与奇偶错误

    • 这些是错误标志。必须用���1的方式清除。一个健壮的ISR必须检查并处理这些错误。处理方式可以是丢弃错误帧、记录错误计数、甚至触发系统复位。切勿只读不写,否则中断会持续触发。
  • RTSD (Bit 12): RTS状态变化

    • RTSEN=1RTEC选择的边沿���RTS引脚上被检测到时,此位置1。用于检测对方流控状态的变化。同样需要写1清除。
  • ESCF (Bit 11): 转义序列检测

    • 如果使能了转义序列检测,并在数据流中检测到预设字符,此位置1。用于实现协议解析。

3.2 状态寄存器USR2:扩展状态与错误

USR2包含了一些额外的状态和错误标志。

  • RDR (Bit 0): 接收数据就绪

    • 只要RxFIFO中有至少1个字符,此位就为1。它与RRDY的区别在于,RDR不依赖阈值,有数据就置位。当RxFIFO被读空,此位自动清零。DREN中断使能的是RDR条件。
  • ORE (Bit 1): 溢出错误

    • 严重错误。当RxFIFO已满,但一个新的字符已经接收完成时,此位置1,新字符会丢失。必须写1清除。出现此错误通常意味着CPU处理速度跟不上数据接收速度,或者CTSTL/RXTL设置不合理,流控未能及时生效。
  • BRCD (Bit 2): Break条件检测

    • 当接收端检测到RXD线持续低电平时间超过一个完整字符帧(包括起始位、数据位、校验位、停止位)时,此位置1。常用于某些特殊协议或调试中表示帧间隔。需写1清除。
  • TXDC (Bit 3): 发送完成

    • 当TxFIFO和发送移位寄存器都为空时,此位置1。用于判断一帧数据是否完全发送完毕。在需要严格知道发送结束时间的场景(如切换半双工方向)非常有用。向TxFIFO写数据会清除此位。
  • ADET (Bit 15): 自动波特率检测完成

    • 如果使能了自动波特率检测功能,在接收到字符‘A’或‘a’并成功检测到波特率后,此位置1。需写1清除。

3.3 中断服务程序(ISR)设计模板与避坑指南

一个稳健的UART ISR模板应遵循以下流程:

void UART1_IRQHandler(void) { uint32_t usr1 = READ_REG(UART1_USR1); uint32_t usr2 = READ_REG(UART1_USR2); // 1. 处理接收相关中断 (可能由RDR、RRDY等触发) if (usr2 & USR2_RDR_MASK) { // 或检查接收中断使能标志对应的状态位 // 循环读取,直到FIFO为空或低于阈值 while (READ_REG(UART1_USR2) & USR2_RDR_MASK) { uint32_t data = READ_REG(UART1_URXD); if (data & URXD_CHARRDY_MASK) { // 检查数据有效位 // 处理有效数据 data & 0xFF process_rx_data(data & 0xFF); } } // 注意:读取数据后,RDR/RRDY会自动更新,无需软件清除 } // 2. 处理发送相关中断 (可能由TRDY、TXDC等触发) if (usr1 & USR1_TRDY_MASK) { // 检查是否还有数据要发送 while (tx_buffer_not_empty() && !tx_fifo_full()) { uint8_t data = get_next_tx_byte(); WRITE_REG(UART1_UTXD, data); } // 如果所有数据发送完毕,可以考虑禁用发送中断以避免空中断 if (tx_buffer_empty()) { DISABLE_TX_INTERRUPT(); // 操作UCR1或相关寄存器 } } // 3. 处理错误中断 (必须清除标志位!) if (usr1 & USR1_PARITYERR_MASK) { WRITE_REG(UART1_USR1, USR1_PARITYERR_MASK); // 写1清除 parity_error_count++; // 可能的错误处理:丢弃当前FIFO数据?重置接收状态? } if (usr1 & USR1_FRAMERR_MASK) { WRITE_REG(UART1_USR1, USR1_FRAMERR_MASK); // 写1清除 frame_error_count++; } if (usr2 & USR2_ORE_MASK) { WRITE_REG(UART1_USR2, USR2_ORE_MASK); // 写1清除 overrun_error_count++; // 溢出是严重错误,可能需要更激进的处理,如清空FIFO FLUSH_RX_FIFO(); } if (usr2 & USR2_BRCD_MASK) { WRITE_REG(UART1_USR2, USR2_BRCD_MASK); // 写1清除 // Break信号处理 } // 4. 处理其他特定中断(如RTSD, ESCF, ADET等) if (usr1 & USR1_RTSD_MASK) { WRITE_REG(UART1_USR1, USR1_RTSD_MASK); // 处理RTS边沿变化 } // ... 其他状态位处理 }

避坑指南:

  • 清除标志位顺序:先读取状态寄存器值进行判断,再针对需要清除的位写1清除。避免先清除再判断,可能丢失在判断期间新产生的标志。
  • FIFO读取循环:在RDR中断中,使用while循环读取,但必须设置超时或最大读取次数限制,防止在异常情况下(如对方持续高速发送)ISR执行时间过长,影响其他中断响应。
  • 中断使能管理:在发送完所有数据后,及时禁用发送就绪中断(TRDY)。在需要发送时再开启。这可以避免无数据可发时,TRDY中断不断空跑消耗CPU资源。
  • 错误处理:对于ORE(溢出)错误,除了清除标志,强烈建议在ISR中清空接收FIFO(可以通过连续读数据寄存器实现),因为溢出时FIFO中的数据序列可能已经错乱,继续使用这些数据可能导致协议解析错误。
  • 状态位粘滞:有些错误状态位(如FRAMERR)可能在一次接收错误中只对应一个错误帧。但在连续接收中,ISR可能来不及处理,下一个错误又来了。确保你的ISR执行速度足够快,或者考虑在错误处理段暂时提升中断优先级。

4. 高级功能配置与实战场景分析

掌握了基础配置和中断处理,我们来看看MC9328MX1 UART的一些高级功能如何在实战中应用。

4.1 硬件流控(RTS/CTS)配置实战

场景:两个设备通过UART高速(如921600 bps)传输大量数据。为防止因处理速度不匹配导致数据丢失,需启用硬件流控。

配置步骤:

  1. 硬件连接:确保设备A的RTS引脚连接设备B的CTS引脚,设备A的CTS引脚连接设备B的RTS引脚。
  2. 设备A配置(作为数据接收方,控制CTS)
    • UCR2:IRTS = 0(侦听对方RTS),CTSC = 1(CTS自动控制)。
    • UCR4:CTSTL = 16(根据RxFIFO大小32,设为一半)。假设RXTL = 8
    • UFCR:RXTL = 8(收到8字节就中断)。
  3. 设备B配置(作为数据发送方,控制RTS)
    • UCR2:IRTS = 0,CTSC = 0(CTS手动控制,但通常接收方自动控制CTS,发送方只需侦听CTS,所以CTSC配置不影响,主要靠IRTS)。
    • 实际上,对于发送方,关键是将IRTS设为0,这样它的发送器就会受自己的CTS引脚(即对方RTS)控制。它不需要设置CTSTL
  4. 工作流程
    • 设备B想发送数据,但首先会检查自己的CTS引脚(即设备A的RTS)。如果设备A未准备好(RTS为高),设备B会等待。
    • 设备A上电后,其CTS(由接收FIFO控制)初始为低(有效),允许设备B发送。
    • 设备B开始发送数据到设备A。
    • 当设备A的RxFIFO数据量达到CTSTL=16时,其CTS引脚自动变高(无效)。
    • 设备B检测到自己的CTS变高,立即停止发送当前正在传输的字符(完成后)。
    • 设备A的ISR因RXTL=8早已触发,开始读取数据。当RxFIFO数据被读到低于CTSTL阈值时,CTS自动恢复为低。
    • 设备B检测到CTS变低,恢复发送。
    • 如此循环,实现自动调速。

常见问题:流控不生效,对方一直发数据导致溢出。

  • 检查1:确认CTSC是否设置为1。如果设为0,CTS将由软件控制,不会自动响应FIFO。
  • 检查2:确认CTSTL值是否合理且已正确写入。该字段在UCR4的高位,注意位偏移。
  • 检查3:用逻辑分析仪或示波器观察CTS/RTS引脚波形。看CTS是否在FIFO数据多时变高,数据被读取后变低。
  • 检查4:确认对方设备(发送方)的IRTS位是否为0。如果为1,它会忽略CTS信号,一直发送。

4.2 FIFO与DMA协同工作配置

对于高速或大数据量传输,使用CPU在ISR中逐个字节搬运数据效率低下。利用TRDYRRDY信号触发DMA传输是更好的选择。

发送DMA配置思路:

  1. 配置DMA通道的源地址为内存中的发送缓冲区,目标地址为UART的发送数据寄存器(UTXD)。
  2. 将DMA请求源设置为UART的TRDY信号(或与之关联的特定DMA请求线)。
  3. 在UART端,设置TXTL(例如=4)。当TxFIFO数据量低于4时,TRDY置位,触发DMA请求。
  4. DMA控制器自动将数据从内存搬移到UTXD,直到设定的传输长度完成。
  5. 传输完成后,DMA产生完成中断,此时可以检查TXDC位确认所有数据已发出,或准备下一包数据。

接收DMA配置思路:

  1. 配置DMA通道的源地址为UART的接收数据寄存器(URXD),目标地址为内存中的接收缓冲区。
  2. 将DMA请求源设置为UART的RRDY信号(当RxFIFO数据达到RXTL阈值时触发)。
  3. 设置RXTL(例如=8)。当收到8个字节时,触发DMA请求。
  4. DMA控制器自动将数据从URXD搬移到内存。注意,需要配置DMA为每次传输读取URXD(32位),但实际数据在低8位,并且要处理CHARRDY位(通常DMA会忽略,但软件后期处理需要知道哪些数据有效)。
  5. 挑战:如何知道一帧数据接收完毕?DMA可以设定固定长度,或者结合IDLE中断(RXDS)。当检测到接收空闲(RXDS=1)时,认为一帧结束,停止DMA或进行帧处理。

关键点:使用DMA时,要特别注意TXTL/RXTL的设置与DMA突发传输大小的匹配。如果TXTL设得太大,DMA触发不够及时,发送器会空闲;设得太小,DMA请求过于频繁,增加总线负担。通常需要结合测试调整。

4.3 自动波特率检测与红外模式

自动波特率检测

  1. 使能相关功能(通常涉及UCR3的BPEN位和UART的特定模式寄存器)。
  2. 发送方首先发送一个字符‘A’或‘a’(0x41或0x61,其位模式包含从高到低的跳变)。
  3. 接收方检测这个字符的位时长,从而计算出波特率,并设置内部的波特率分频器。
  4. 检测成功后,状态寄存器USR2中的ADET位会置1。
  5. 注意事项:自动波特率检测对起始位的识别要求较高,在噪声大的环境中可能不可靠。通常用于初始连接或调试。

红外模式(IrDA)

  1. 使能红外模式(通常通过UCR1等寄存器,手册未在此节显示)。
  2. 配置INVT(UCR3 Bit1)和INVR(UCR4 Bit9)来设置红外发射和接收的极性。
  3. 配置IRSC(UCR4 Bit5)选择投票逻辑的时钟源。
  4. 红外模式会将正常的UART数字脉冲编码成占空比为3/16的光脉冲。需要外接红外收发器。
  5. 注意通信距离和角度,红外通信易受遮挡和强光干扰。

5. 调试技巧与常见问题排查实录

即使配置看起来完全正确,UART通信仍可能出问题。以下是一些基于寄存器状态的排查经验。

问题1:能发送,不能接收;或能接收,不能发送。

  • 检查1UCR2中的RXENTXEN是否都已置1。
  • 检查2SRST位是否为1。如果为0,模块处于复位状态。
  • 检查3:检查波特率寄存器(UBMR, UBIR)计算和配置是否正确。最常用方法:用示波器测量TXD引脚,看发送的波形波特率是否与预期一致。一个简单的办法是让程序持续发送0x55(二进制01010101),示波器上应该看到标准的方波,测量一个位的时间即可算出实际波特率。
  • 检查4:检查引脚复用配置。MC9328MX1的UART引脚可能与其他功能复用,需要确保IOMUX(输入输出复用控制器)已正确配置为UART功能。

问题2:通信数据错乱,出现大量帧错误或奇偶错误。

  • 检查1:双方的数据格式(数据位、停止位、校验位)是否完全一致。重点检查WSSTPBPRENPROE
  • 检查2:地线连接是否良好。串口通信需要共地,地线不稳会引入巨大噪声。
  • 检查3:波特率容差。计算出的波特率分频值可能不是整数,存在误差。高速率下(如115200以上),误差累积可能导致采样点偏移。尽量选择时钟源和分频数能使波特率误差最小的配置。
  • 检查4:电气电平是否匹配。MC9328MX1是3.3V TTL电平,如果连接RS-232设备需要电平转换芯片。

问题3:中断能进入,但似乎只进入一次,之后不再触发。

  • 检查1这是最常见的原因:状态寄存器中的中断标志位没有清除。例如,发生了帧错误(FRAMERR=1)并使能了中断,但ISR中没有写1清除这个标志位。该标志位会一直保持,阻止后续相同类型的中断产生。务必在ISR中清除所有检测到的状态标志(通过写1)。
  • 检查2:中断使能位是否被意外清除。检查UCR3、UCR4中的PARERRENFRAERRENDREN等位。
  • 检查3:芯片级的中断控制器(如NVIC)配置,中断是否被屏蔽或优先级设置有问题。

问题4:使用FIFO和中断,但偶尔还是会丢失数据。

  • 检查1RXTLCTSTL设置是否合理。如果RXTL设得太大(如28),而数据涌入速度很快,可能在CPU响应中断并开始读取数据前,FIFO就已经满了(导致ORE)。尝试减小RXTL(如4或8),让中断更早触发。
  • 检查2CTSTL是否小于FIFO深度(32)。确保流控能及时生效。CTSTL应设置为小于32且留有一定余量给CPU处理。例如设为20。
  • 检查3:CPU总中断是否被长时间关闭?在ISR中处理任务是否过重?优化ISR,只做最必要的操作(如搬运数据),将复杂处理放到主循环中。
  • 检查4:是否使能了ORE中断并在其中清空了FIFO?如果没有,溢出后FIFO可能处于异常状态。

问题5:如何判断通信是否真的在工作?

  • 软件环回测试:将UCR2中的IRTSCTSC都设为1(忽略RTS,CTS自控),然后将TXD和RXD在PCB上短接。程序发送一个数据,然后接收。如果能在接收端读到发送的数据,说明UART内核、数据通路基本正常。
  • 寄存器诊断:在通信过程中,定期读取USR1USR2寄存器,观察RRDYTRDYTXDC以及各种错误标志的变化,这能最直接地反映硬件状态。
  • 使用调试器:在调试器中设置对UART数据寄存器的读写断点,或者监控关键状态寄存器的值,可以动态跟踪通信流程。

通过对MC9328MX1 UART控制与状态寄存器的逐位剖析,并结合实际的配置策略、中断处理模板和调试技巧,你应该已经对如何“驾驭”而不仅仅是“使用”一个UART外设有了更深的理解。寄存器编程的魅力就在于,你直接与硬件对话,掌控每一个细节。这份掌控力,正是解决那些最棘手的嵌入式通信问题的关键。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/13 13:33:54

告别下载等待:如何让115云盘视频在Kodi中直接流畅播放

告别下载等待:如何让115云盘视频在Kodi中直接流畅播放 【免费下载链接】115proxy-for-kodi 115原码播放服务Kodi插件 项目地址: https://gitcode.com/gh_mirrors/11/115proxy-for-kodi 你是否曾遇到过这样的困扰:想在电视上观看115云盘里的高清电…

作者头像 李华
网站建设 2026/6/13 13:31:11

Source Han Serif CN:7种粗细免费商用字体终极使用指南

Source Han Serif CN:7种粗细免费商用字体终极使用指南 【免费下载链接】source-han-serif-ttf Source Han Serif TTF 项目地址: https://gitcode.com/gh_mirrors/so/source-han-serif-ttf 还在为中文设计找不到合适的免费字体而烦恼吗?Source Ha…

作者头像 李华
网站建设 2026/6/13 13:31:10

为什么你的浏览器需要uBlock Origin:5个必须安装的理由

为什么你的浏览器需要uBlock Origin:5个必须安装的理由 【免费下载链接】uBlock uBlock Origin - An efficient blocker for Chromium and Firefox. Fast and lean. 项目地址: https://gitcode.com/GitHub_Trending/ub/uBlock 你是否经常在浏览网页时被各种弹…

作者头像 李华
网站建设 2026/6/13 13:23:53

思源宋体CN终极指南:7种粗细字体一键配置完整解决方案

思源宋体CN终极指南:7种粗细字体一键配置完整解决方案 【免费下载链接】source-han-serif-ttf Source Han Serif TTF 项目地址: https://gitcode.com/gh_mirrors/so/source-han-serif-ttf 还在为中文排版找不到合适的免费商用字体而烦恼吗?思源宋…

作者头像 李华