1. 项目概述与核心价值
在嵌入式开发,尤其是基于MCU的实时控制系统中,定时和通信是两个最基础、也最考验工程师功底的模块。飞思卡尔(现恩智浦)的MC9S08JE128系列微控制器,以其高性价比和丰富的外设,在消费电子、工业控制和汽车辅助系统中应用广泛。其内置的可编程延迟块(PDB)和串行通信接口(SCI)模块,是许多项目成败的关键。手册上的寄存器描述虽然详尽,但往往分散且偏重理论,新手直接上手配置,很容易在“预分频器该设多少”、“中断标志怎么清不掉”、“通信死活不通”这类问题上卡住半天。
我接手过不少从其他平台迁移到S08JE128的项目,也调试过许多同事留下的“祖传代码”,发现大部分问题都源于对这两个模块的寄存器理解不够透彻,只是照搬例程,一旦应用场景稍有变化就束手无策。因此,我决定结合手册和多年踩坑经验,写一份“说人话”的配置指南。本文不会重复手册的每一句话,而是聚焦于PDB和SCI最核心的寄存器,拆解每个关键配置位背后的设计意图、实操中的陷阱,以及如何将它们组合起来解决实际问题。目标是让你读完就能动手,调通还能知其所以然。
2. 可编程延迟块(PDB)深度配置解析
PDB本质上是一个高度可配置的定时器/触发器。它的核心思想很简单:一个计数器(PDBCNTH:L)在总线时钟驱动下不断累加,我们可以设定一个模值(PDBMODH:L)作为计数上限,还可以设定一个或多个延迟值(PDBDLYH:L)。当计数器达到这些预设值时,PDB可以产生中断、触发ADC转换或DAC更新。听起来简单,但几个控制寄存器的配合使用,却藏着不少门道。
2.1 PDB控制寄存器1(PDBC1):时钟与触发之源
PDBC1寄存器是PDB的总开关和节拍器,它决定了计数器“怎么跑”以及“什么时候开始跑”。
PRESCALER[2:0](位7-5):时钟预分频选择这是第一个容易出错的地方。预分频器决定了计数器累加的基本时间单位。公式是:计数器时钟 = 总线时钟 / 分频系数。选项从1分频(直接使用总线时钟)到128分频。
- 实操要点:选择预分频值不是越小越好。如果你的PDB模值(PDBMOD)设置得很大,比如需要产生一个几秒的周期,而总线时钟是8MHz,直接分频(PRESCALER=000)会导致PDBMOD值需要设得极大(可能超过16位寄存器范围)。此时就需要增大预分频,用更慢的计数时钟来匹配你的长周期需求。核心原则是:在满足定时分辨率的前提下,使用尽可能大的预分频值,让PDBMOD的值处于一个合理的范围(例如几千以内),便于计算和调试。
- 避坑指南:手册中特别提到了“使用大于1的预分频器会限制以总线时钟周期为单位的计数/延迟精度”。例如,如果你选择4分频,那么你所能设置的最小时间间隔就是4个总线时钟周期,任何不能被4整除的周期数都无法精确实现。因此,对于需要高精度定时(例如精确的PWM死区控制)的场景,应优先考虑使用不分频或低分频,通过调整PDBMOD来满足周期要求。
TRIGSEL[2:0](位4-2):输入触发源选择这个字段决定了什么事件能让PDB计数器复位并重新开始计数。000对应ADC转换完成(ADCSC1_COCO),001对应比较器输出(ACMPO),111对应软件触发(SWTRIG)。
- 场景分析:选择ADC触发是最常见的用法之一,用于实现精确的周期性ADC采样。例如,你可以设置PDB每1ms触发一次ADC,确保采样间隔绝对均匀,不受软件执行时间抖动的影响。选择软件触发则给了你最大的灵活性,可以在任何需要的时候通过写
PDBC2寄存器的SWTRIG位来启动一次PDB计数周期。 - 配置顺序:务必注意,要使能硬件触发(非111的情况),除了设置
TRIGSEL,还必须将PDBC2寄存器中对应的通道使能位(对于ADC触发,通常是通道0)置1。这是一个常见的遗漏点。
CONT(位1):连续模式使能此位控制PDB计数器在达到模值(PDBMOD)后的行为。
CONT=0(单次模式):计数器达到PDBMOD后停止,等待下一次触发事件才会重新从0开始计数。CONT=1(连续模式):计数器达到PDBMOD后自动复位到0,并继续计数,形成连续的周期性计时。- 选择策略:需要产生固定频率的周期性触发(如定时中断、DAC更新)时,使用连续模式。仅在需要由外部事件(如按键、传感器信号)来启动一次定时序列时,使用单次模式。
MULT(位0):预分频器倍乘位这是一个容易被忽略但功能强大的位。当MULT=1时,实际的预分频系数将是PRESCALER选择系数的20倍。例如,PRESCALER选择8分频(011),如果MULT=1,则实际分频系数是8*20=160。
- 应用价值:这让你能用较小的
PRESCALER值(保持较好的时间分辨率)和较小的PDBMOD值(便于设置),实现极长的定时周期。计算总定时周期时,公式为:周期 = (PDBMOD值 + 1) * (预分频系数) * (MULT?20:1) / 总线时钟频率。 - 计算示例:总线时钟8MHz,需要1秒定时。若
PRESCALER=111(128分频),MULT=0,则PDBMOD需设置为1秒 * 8MHz / 128 - 1 = 62499,刚好在16位寄存器范围内。若想用更小的PDBMOD,可设PRESCALER=011(8分频),MULT=1,则实际分频为160,PDBMOD需设为1秒 * 8MHz / 160 - 1 = 49999,同样可行。
2.2 PDB控制寄存器2(PDBC2)与通道使能寄存器(PDBCHEN)
PDBC2目前主要用到位0:SWTRIG(软件触发位)。当PDBC1.TRIGSEL设置为111(软件触发)且PDB模块使能后,向SWTRIG位写1,会立即复位并重启PDB计数器。这是一个“只写”触发动作,读该位始终为0。在单次模式下,这是启动计数的唯一方法;在连续模式下,你也可以用它来手动同步计数器的起始点。
PDBCHEN寄存器用于使能各个通道的触发输出。手册用加粗的“NOTE”警告我们:位1到位7复位后默认为1!这是一个巨大的陷阱。
- 严重警告:如果你使用PDB来触发ADC(通常使用通道0),必须手动将
PDBCHEN寄存器的位1-7清零,只保留CHEN0=1。如果这些位为1,可能会引发不可预知的ADC行为。我曾在调试一个ADC采样乱码的问题时,花了整整一天才发现是这个寄存器没正确初始化。安全的做法是在PDB初始化代码中,明确写入PDBCHEN = 0x01。
2.3 PDB模值寄存器(PDBMODH:L)与计数器寄存器(PDBCNTH:L)
PDBMODH:L组成一个16位模值。在连续模式下,这就是PDB的计数周期。计数器从0开始递增,当计数值等于PDBMOD时,在下一个时钟沿复位为0,并置位相关标志(如果使能了中断)。因此,实际的定时周期对应的计数值是PDBMOD + 1。例如,需要计数器计1000个时钟周期后溢出,那么PDBMOD应设置为999。
PDBCNTH:L是只读的当前计数器值。这里有一个重要的硬件特性:读取高字节(PDBCNTH)或低字节(PDBCNTL)时,硬件会将当前16位计数器的值锁存到一个缓冲器中。后续再读取另一个字节时,读到的将是之前锁存的缓冲器值,而非实时计数器值。这意味着,为了获取一个准确的、一致的16位计数器快照,你必须连续读取这两个字节,且顺序不能错。通常的做法是先读高字节,再读低字节。
2.4 PDB中断延迟寄存器(PDBIDLYH:L)与通道延迟寄存器(PDBDLYH:L)
这是PDB的精华所在,实现了“在一个大周期内,产生多个不同时刻的触发事件”。
PDBIDLYH:L:用于设定一个产生PDB自身中断的延迟点。计数器从0开始计数,当计数值等于PDBIDLY时,如果中断使能(PDBSC_IE置位),则会产生PDB中断。注意:即使中断未使能,当计数值等于PDBIDLY时,PDBSC_IF标志位也会被置位,你可以通过轮询这个标志来判断时间点。PDBDLYH:L:每个触发通道(如触发ADC的通道0)都有自己的一对延迟寄存器。它定义了从触发输入有效(或计数器开始计数)到该通道触发输出有效之间的延迟。例如,你可以设置PDB每1ms(由PDBMOD决定)循环一次,但让ADC在每次循环开始后的第200个时钟周期才被触发。这常用于需要多个动作按严格时序执行的场景。
配置流程与心得:
- 确定时钟源:根据所需定时周期和分辨率,计算并设置
PDBC1中的PRESCALER和MULT。 - 设置工作模式:根据应用选择单次(
CONT=0)或连续(CONT=1)模式,并选择触发源(TRIGSEL)。 - 计算并设置模值:根据定时周期公式,计算
PDBMOD值并写入。 - 配置延迟:如果需要非零时刻的触发或中断,计算
PDBIDLY和/或PDBDLY值并写入。 - 使能通道与中断:正确配置
PDBCHEN(切记清除高位!),并根据需要使能PDB中断。 - 启动:如果使用软件触发,向
PDBC2的SWTRIG位写1;如果使用硬件触发,确保触发信号有效。
关键提醒:所有PDB的延时/模值寄存器(PDBMOD, PDBIDLY, PDBDLY)都有“双缓冲”机制。你写入的值并不会立即生效,而是要等到当前PDB计数周期结束后,在新的周期开始时才会加载。这样做是为了避免在计数器运行时更改周期值导致不可预测的行为。在初始化时这没问题,但如果在运行中需要动态修改这些值,你必须意识到这个延迟生效的特性。
3. 串行通信接口(SCI)寄存器精讲与配置实战
SCI是异步串口,协议简单,但配置寄存器繁多,且标志位清除有特定顺序,一不留神就会导致数据卡死或错误。
3.1 波特率寄存器(SCIxBDH, SCIxBDL):通信的节拍
这两个寄存器共同构成13位的波特率分频数SBR[12:0](常记为BR)。波特率计算公式为:SCI Baud Rate = BUSCLK / (16 × BR)。
- 计算示例:总线时钟
BUSCLK = 8MHz,目标波特率= 9600。则BR = 8,000,000 / (16 * 9600) ≈ 52.083。取整为52。代入验证:实际波特率 = 8,000,000 / (16 * 52) ≈ 9615.38,误差约为0.16%,在可接受范围内(通常要求<2%)。 - 写入顺序:由于
BR是13位,而SCIxBDH只存放高5位。必须先写SCIxBDH,再写SCIxBDL。写SCIxBDL的动作才会将缓冲的新值真正更新到波特率发生器。 - 特殊值:当
BR=0时,波特率发生器被禁用以省电。复位后SCIxBDL非零,所以波特率发生器默认是关闭的,直到首次使能接收器或发送器(RE或TE置1)才会启动。这意味着,如果你先配置波特率再使能SCI,是安全的;但如果顺序反了,可能会以默认的、错误的波特率发送乱码。
3.2 控制寄存器1(SCIxC1):工作模式定调
SCIxC1决定了通信的基本框架。
LOOPS和RSRC:这两个位配合,用于配置回环测试和单线半双工模式。LOOPS=1启用回环模式,发送端输出内部连接到接收端输入,断开外部引脚。此时RSRC决定连接方式:RSRC=0为纯内部回环,用于自测试;RSRC=1为单线模式,TxD引脚同时用于发送输出和接收输入,此时TXDIR位控制数据方向。- 调试利器:在硬件连接前,务必先配置为内部回环模式(
LOOPS=1, RSRC=0)测试发送和接收代码。如果能自发自收,说明你的SCI驱动代码和波特率设置基本正确,可以排除软件问题,聚焦硬件线路检查。
M:选择数据帧长度。M=0为8位数据位;M=1为9位数据位。9位模式常用于多机通信,第9位作为地址/数据标识位。PE和PT:奇偶校验控制。PE=1使能校验,PT选择奇校验(PT=1)或偶校验(PT=0)。注意:当使能校验时,数据位的最高位(第8或第9位)会被硬件用作校验位,你发送/接收的数据实际上是7位或8位有效数据加上1位校验位。ILT:空闲线类型选择。它影响“空闲线检测”何时开始计时。ILT=0时,在起始位之后开始计空闲时间;ILT=1时,在停止位之后开始计。在多点通信(唤醒功能)中,ILT=1是更可靠的选择,因为它能确保停止位不会误判为空闲位的一部分。
3.3 控制寄存器2(SCIxC2):核心功能开关
SCIxC2包含了最重要的发送和接收使能位,以及中断控制。
TE(发送使能)和RE(接收使能):这是SCI工作的总开关。一个常见错误是只打开了其中一个。即使你只做单向通信,也建议在初始化时同时使能,因为某些状态标志(如TC)的运作与两者都有关。特别要注意TE的副作用:当TE从0变为1时,会强制在TxD线上发送一个空闲字符(全1),用于初始化线路状态。如果你的接收方对此敏感,需要规划好使能时序。TIE,TCIE,RIE,ILIE:分别是发送数据寄存器空、发送完成、接收数据寄存器满、空闲线中断使能。中断服务程序(ISR)的编写必须严格遵循标志清除顺序,否则会导致中断持续触发或丢失。通常,查询方式(轮询)对于简单应用更可靠。SBK:发送中止符。写1再写0,会排队发送一个中止字符(连续的低电平)。注意:根据BRK13位的设置,中止符长度可能为10/11或13/14个位时间。在LIN总线通信中会用到。
3.4 状态寄存器1(SCIxS1)与错误处理
SCIxS1是诊断通信问题的“仪表盘”。所有标志位都是只读的,通过特定的“读状态寄存器-访问数据寄存器”序列来清除。
TDRE(发送数据寄存器空):当发送数据缓冲器(SCIxD)可写入新数据时置1。清除方法:先读SCIxS1(此时TDRE=1),然后向SCIxD写入要发送的数据。TC(发送完成):当发送移位寄存器也空(即所有数据,包括中止符,都已发出)时置1。清除方法:先读SCIxS1(此时TC=1),然后执行以下三者之一:写SCIxD、将TE位先清0再置1、或写SBK位为1。RDRF(接收数据寄存器满):当接收数据已从移位器转移到SCIxD缓冲器时置1。清除方法:先读SCIxS1(此时RDRF=1),然后读SCIxD获取数据。IDLE(空闲线检测):当RxD线空闲超过一个完整字符时间后置1。清除方法与RDRF类似。OR,NF,FE,PF(溢出、噪声、帧错误、校验错误):这些错误标志在接收字符时检测到相应问题后,与RDRF同时置1。它们的清除序列与RDRF完全相同:先读SCIxS1,再读SCIxD。务必在读取数据前检查这些错误位,否则你可能在处理错误的数据而不知情。
致命陷阱:标志位清除序列是刚性的。例如,如果你在
RDRF=1时,先读了数据(SCIxD),再读状态寄存器(SCIxS1),���么RDRF和相关的错误标志将无法被清除,导致后续数据无法接收,通信彻底挂死。正确的顺序必须牢记:先读状态,后访问数据。
3.5 控制寄存器3(SCIxC3)与数据寄存器(SCIxD)
SCIxC3包含一些高级控制和9位模式下的数���位。
T8/R8:当M=1(9位模式)时,T8是发送数据的第9位,R8是接收数据的第9位。操作顺序至关重要:发送时,应先写T8,再写SCIxD;接收时,应先读R8,再读SCIxD。因为读写SCIxD会触发内部的数据转移和标志清除逻辑。ORIE,NEIE,FEIE,PEIE:各种接收错误的中断使能。在要求高可靠性的通信中,建议使能这些中断,以便及时处理线路故障。TXINV/RXINV:数据极性反转。有些硬件链路(如某些RS-485收发器)或协议(如DMX512)使用反向逻辑。设置这些位可以免去外部反相器。
SCIxD寄存器是数据通道。读它访问接收缓冲器,写它访问发送缓冲器。它是双缓冲的,意味着你可以提前写入下一个要发送的数据(当TDRE=1时),也可以在读取当前数据的同时,硬件正在接收下一帧数据(当RDRF=1时)。
4. 完整配置流程与代码框架
理解了每个寄存器后,将它们串联起来才能工作。下面以配置一个9600波特率、8N1(8数据位、无校验、1停止位)、使能接收中断的SCI为例,并配置PDB以1ms周期触发ADC为例,展示一个可靠的初始化流程。
4.1 SCI初始化代码框架(以SCI1为例)
// 假设 BUSCLK = 8MHz #define BUS_CLK_HZ 8000000UL #define SCI_BAUD 9600UL void SCI1_Init(void) { // 1. 暂时禁用SCI,配置波特率 SCI1C2 = 0x00; // 关闭TE和RE,避免在配置期间误操作 // 计算并设置波特率 uint16_t sbr = (uint16_t)(BUS_CLK_HZ / (16 * SCI_BAUD)); SCI1BDH = (uint8_t)((sbr >> 8) & 0x1F); // 先写高5位 SCI1BDL = (uint8_t)(sbr & 0xFF); // 后写低8位,更新生效 // 2. 配置工作模式:8位数据,无校验,正常双工模式 SCI1C1 = 0x00; // LOOPS=0, M=0, PE=0 // 3. 配置控制寄存器2:使能接收中断,使能收发器 // TIE=0(轮询发送), RIE=1(接收中断), TE=1, RE=1 SCI1C2 = 0x2C; // 二进制 0010 1100 // 4. 配置控制寄存器3:默认值,无极性反转,使能错误中断(可选) SCI1C3 = 0x0F; // 使能所有错误中断(ORIE, NEIE, FEIE, PEIE) // 5. 清除任何可能存在的初始状态标志(通过读S1,读/写D寄存器) (void)SCI1S1; // 读状态寄存器 (void)SCI1D; // 读数据寄存器(如果RDRF意外置位) } // SCI1接收中断服务例程 interrupt void SCI1_RX_ISR(void) { uint8_t status = SCI1S1; // 必须首先读取状态寄存器! if (status & SCI1S1_RDRF_MASK) { // 检查错误标志 if (status & (SCI1S1_FE_MASK | SCI1S1_NF_MASK | SCI1S1_PF_MASK)) { // 处理帧错误、噪声错误或校验错误 // 通常需要读取错误数据并丢弃 uint8_t bad_data = SCI1D; // 读数据以清除标志 // ... 错误处理逻辑 ... } else if (status & SCI1S1_OR_MASK) { // 处理溢出错误 uint8_t bad_data = SCI1D; // 读数据以清除标志 // ... 溢出处理逻辑 ... } else { // 数据接收正确 uint8_t received_data = SCI1D; // 读数据,同时清除RDRF标志 // ... 处理 received_data ... } } if (status & SCI1S1_IDLE_MASK) { // 处理空闲线检测,同样需要读S1再读D来清除IDLE标志 (void)SCI1D; // ... 空闲线处理逻辑 ... } }4.2 PDB初始化代码框架(用于触发ADC)
// 假设 BUSCLK = 8MHz, 需要1ms的ADC触发周期 #define BUS_CLK_HZ 8000000UL #define PDB_PERIOD_MS 1UL void PDB0_Init_For_ADC(void) { // 1. 停止PDB,进行配置 // 假设PDB_SC寄存器(手册中可能为PDBSC)的PDBEN位用于总使能,先关闭 // 这里以PDBSC为例,具体寄存器名请参考手册 PDBSC = 0x00; // 2. 配置PDBC1:选择预分频、触发源、模式 // 目标:1ms周期。先尝试不分频。 // 所需计数器时钟周期数 = 1ms * 8MHz = 8000 // PDBMOD = 8000 - 1 = 7999 (0x1F3F),在16位范围内,可行。 // 因此,PRESCALER=000(不分频), CONT=1(连续模式), TRIGSEL=111(软件触发启动) PDBC1 = 0x07; // 二进制 0000 0111 (CONT=1, TRIGSEL=111) // 3. 设置模值寄存器 (1ms周期) PDBMODH = 0x1F; // 7999 的高字节 PDBMODL = 0x3F; // 7999 的低字节 // 4. 设置通道0延迟寄存器 (假设我们希望触发发生在周期开始时,即延迟为0) PDBDLY0H = 0x00; PDBDLY0L = 0x00; // 5. 配置PDBCHEN:仅使能通道0,并必须清除位1-7! PDBCHEN = 0x01; // 只设置CHEN0=1 // 6. 使能PDB(如果存在独立使能位),或通过触发启动 // 若使用软件触发启动连续模式,只需使能模块后写一次SWTRIG // 假设PDBSC的PDBEN位是总使能 PDBSC |= PDB_SC_PDBEN_MASK; // 7. 发送软件触发,启动PDB连续计数 PDBC2 |= PDBC2_SWTRIG_MASK; } // 在ADC初始化中,需要配置ADC使用PDB触发 void ADC_Init_With_PDB_Trigger(void) { // ... 其他ADC配置(通道、分辨率等)... // 设置ADC为硬件触发模式,并选择PDB作为触发源 // 这通常涉及配置ADCSC2寄存器的ADTRG位和ADACT位 // 具体请参考ADC章节 }4.3 常见问题排查速查表
| 现象 | 可能原因 | 排查步骤 |
|---|---|---|
| SCI无法发送数据 | 1.TE位未使能。2. 波特率设置错误。 3. TDRE标志未有效清除(清除序列错误)。4. TxD引脚未正确配置为输出功能。 | 1. 检查SCIxC2的TE位是否为1。2. 用示波器测量TxD引脚,看是否有任何波形。计算 BR值并核对写入顺序(先BDH,后BDL)。3. 确认发送代码遵循“读S1->写D”的清除序列。 4. 检查引脚控制寄存器,将TxD引脚功能设置为SCI输出。 |
| SCI能发送但不能接收 | 1.RE位未使能。2. RxD引脚输入功能未开启或硬件连接问题。 3. 接收中断未使能或中断服务程序(ISR)未正确清除 RDRF。4. 发送与接收方波特率、数据格式不匹配。 | 1. 检查SCIxC2的RE位。2. 检查RxD引脚配置,并用示波器交叉对比发送方TxD和接收方RxD信号。 3. 检查 RIE位,并在ISR中严格按“读S1->读D”顺序操作。4. 双重检查双方波特率、数据位、停止位、校验位设置。 |
| PDB无法触发ADC | 1. PDB通道未使能(PDBCHEN配置错误)。2. PDB模值 PDBMOD设置为0或过小。3. ADC未配置为硬件触发模式,或未选择PDB作为触发源。 4. PDB计数器未启动( CONT=0且无触发,或软件触发未执行)。 | 1.重点检查PDBCHEN,确保只有需要的通道(如CHEN0)为1,其余位必须为0。2. 计算并验证 PDBMOD值是否合理。3. 检查ADC控制寄存器中触发源选择位。 4. 检查 PDBC1.CONT,若为0,确认触发信号(硬件或软件SWTRIG)是否产生。 |
| PDB中断不产生或频繁产生 | 1. PDB中断未使能(PDBSC_IE位)。2. PDBIDLY值设置等于或大于PDBMOD,在连续模式下,等于PDBMOD时会在计数器溢出时触发,可能符合预期。3. 中断标志 PDBSC_IF未清除。 | 1. 检查PDB中断使能寄存器。 2. 核对 PDBIDLY与PDBMOD的关系。如果需要周期中断,通常设PDBIDLY=PDBMOD。3. 在中断服务程序中,必须写1清除 PDBSC_IF标志。 |
| 通信数据错误或乱码 | 1. 波特率误差过大(>2%)。 2. 电气干扰(噪声)。 3. 发送/接收缓冲器溢出( OR标志置位)。4. 帧错误( FE置位),可能是波特率不匹配或停止位被干扰。 | 1. 精确计算波特率分频比,尽量使用误差小的时钟源(如外部晶振)。 2. 检查硬件线路,必要时增加串联电阻或并联电容��使用双绞线。 3. 提高接收数据处理速度,或使用流控。检查并处理 OR标志。4. 用示波器观察数据帧格式,确认起始位、停止位电平正确。 |
5. 高级应用与优化技巧
掌握了基础配置后,可以探索一些高级用法来优化系统性能。
PDB的精准定时与多通道触发:PDB的强大之处在于可以同时为多个外设提供精准的、相位可调的触发信号。例如,在一个电机控制应用中,你可以用同一个PDB模块,设置PDBMOD为PWM周期,然后用PDBDLY0触发ADC在PWM波形的特定点采样电流,用PDBDLY1触发另一个定时器产生互补PWM的死区时间。所有触发都在硬件层面同步,消除了软件延迟带来的抖动。
SCI的DMA支持:虽然S08JE128的DMA功能相对简单,但结合SCI可以大幅减轻CPU负担。对于高速或连续的数据流,可以配置DMA在RDRF标志置位时自动将SCIxD的数据搬运到内存缓冲区,或在TDRE标志置位时从内存缓冲区搬运数据到SCIxD。关键在于配置好DMA的触发源和传输量。
低功耗模式下的SCI唤醒:利用SCI的接收器唤醒功能(RWU位),可以让MCU在等待串口指令时进入低功耗的等待模式。当检测到空闲线(WAKE=0)或地址匹配(WAKE=1,第9位为1)时,硬件自动清除RWU并产生中断唤醒MCU。配置时需注意ILT位的设置,以确保唤醒条件判断准确。
寄存器访问的原子性:在对16位寄存器(如PDBMOD,PDBIDLY)进行写操作时,虽然手册要求先写高字节再写低字节,但在中断可能发生的环境中,这组写操作应该被保护起来,防止被中断打断导致高低字节写入不同步。通常的做法是在操作前关闭全局中断,操作后再开启。
调试这些模块,最有力的工具不是仿真器,而是示波器和逻辑分析仪。用它们直接测量PDB的触发输出引脚波形,测量SCI的TxD/RXD信号,对比实际波形与预期时序,任何配置错误都会无所遁形。把寄存器位域图打印出来放在手边,调试时逐位核对,是效率最高的方法。