飞思卡尔MC68HC908RC24 CMT模块:嵌入式无线信号生成的硬件利器
1. 项目概述与CMT模块核心价值在嵌入式系统开发特别是涉及无线通信或红外遥控的领域如何高效、精确地生成调制信号一直是个核心挑战。很多开发者会选择外置的专用编码芯片或复杂的软件模拟但这往往增加了系统成本、功耗和代码复杂度。今天要深入剖析的是飞思卡尔现恩智浦MC68HC908RC24这颗8位微控制器内部一个极具特色的硬件模块——载波调制发射器Carrier Modulator Transmitter, CMT。这个模块堪称是嵌入式无线信号生成的“瑞士军刀”它把信号调制的大部分硬件逻辑都集成在了芯片内部让开发者能用极简的软件控制就输出高精度的红外或无线载波信号。简单来说CMT模块就是一个高度可编程的“智能信号发生器”。它的核心价值在于将传统上需要CPU频繁干预的脉宽调制PWM、载波生成和协议时序控制全部交给了硬件自动完成。你只需要预先配置好几个寄存器设定好“高电平持续多久”标记周期和“低电平持续多久”空间周期以及载波的频率CMT模块就能自动、连续、无差错地输出符合要求的调制波形。这对于实现诸如红外遥控NEC、RC-5、SIRC等协议、简单的FSK频移键控无线数据传输、甚至是自定义的串行通信协议都提供了极大的便利。它解放了CPU让MCU在发射信号的同时还能处理其他任务并且由于是硬件生成信号的时序精度和稳定性远非软件循环翻转IO口所能比拟。2. CMT模块架构与核心工作原理拆解要玩转CMT首先得理解它的内部架构。你可以把它想象成一个由三个核心部分协同工作的精密时钟系统载波发生器Carrier Generator、调制器Modulator和发射器输出块Transmitter Output Block。2.1 核心组件功能解析载波发生器顾名思义负责产生那个被调制的“基础波”——载波。在红外通信中这个载波通常是38kHz、36kHz或40kHz的方波。CMT的载波发生器非常灵活它通过两组寄存器主寄存器CCH1/CCL1和次寄存器CCH2/CCL2来分别定义载波高电平和低电平的持续时间。这个持续时间是以系统时钟CMTCLK的周期为单位的。例如当总线时钟为2MHz时通过设置CCH1和CCL1的值你可以精确地合成出你想要的载波频率。在FSK模式下模块会自动在主、次两组寄存器间切换从而产生两个不同的频率实现频移键控。调制器是整个模块的“指挥中心”。它决定了载波信号何时输出标记期Mark以及何时静默空间期Space。调制器内部有两个核心的12位缓冲寄存器MBUFF标记缓冲和SBUFF空间缓冲。MBUFF的值决定了输出载波的持续时间而SBUFF则决定了静默期的长度。调制器按照设定的模式时间、基带或FSK以CMTCLK/8或载波频率为时间基准自动递减内部计数器控制着载波发生器的门控信号。发射器输出块是最后的“执行单元”。它负责将调制器与载波发生器协同产生的信号最终输出到指定的IRO红外输出引脚上。这里有一个关键的控制点输出极性CMTPOL。这个位决定了有效输出是高电平还是低电平。在红外发射电路中红外发射二极管IRED通常是阴极接IRO脚阳极接VCC。当CMTPOL0默认时IRO输出高电平对应IRED熄灭低电平对应IRED导通发光。因此通常我们需要将CMTPOL设置为1反向这样当模块输出有效载波标记期时IRO引脚为低IRED导通发光符合常规电路设计。2.2 时钟系统与精度基石CMT模块的时序精度完全依赖于其输入时钟CMTCLK。CMTCLK来源于内部总线时钟Bus Clock并且可以通过CMCS寄存器中的DIV2位进行2分频。这是理解所有时间计算的基础。当DIV2 0时CMTCLK 总线时钟频率。例如使用2MHz晶振总线时钟为2MHz则CMTCLK 2MHz。当DIV2 1时CMTCLK 总线时钟频率 / 2。在时间模式和基带模式下调制器的最小时间单位是CMTCLK ÷ 8。这个“÷8”是硬件固定的预分频器。所以时间分辨率 8 / CMTCLK。还是以2MHz总线时钟、DIV20为例CMTCLK2MHz时间分辨率 8 / 2MHz 4μs。这意味着你所能设置的最短标记或空间时间以及所有时间的增量步长都是4μs的整数倍。实操心得时钟配置是第一步在初始化任何CMT参数之前务必先确认你的系统时钟配置。错误的时钟频率会导致计算出的所有时间参数完全错乱。例如你以为设置了一个560μs的引导码实际可能因为时钟分频比算错而变成了1120μs导致接收端完全无法解码。3. CMT三大工作模式深度剖析与配置实战CMT模块提供了三种工作模式通过CMCS寄存器中的MODE和BASE位进行选择。理解每种模式的差异和适用场景是正确应用的关键。3.1 时间模式Time Mode通用脉冲宽度调制这是最基础也是最常用的模式。在此模式下MODE0 BASE0调制器以CMTCLK÷8为时间基准独立控制载波输出标记和静默空间的时间长度。标记时间 (t_mark):(MBUFF 1) * (8 / CMTCLK)秒空间时间 (t_space):SBUFF * (8 / CMTCLK)秒注意标记时间公式中的“1”。这意味着当你将MBUFF设置为0时实际的标记时间是一个时间单位例如4μs而不是0。这个设计避免了零宽度脉冲。配置示例生成一个标准的38kHz红外载波调制信号假设我们需要生成一个频率为38kHz周期约26.3μs占空比通常为1/3的载波并用它来调制一个560μs的脉冲后跟一个560μs的空间。计算载波参数总线时钟2MHzDIV20CMTCLK2MHz。载波周期 1/38kHz ≈ 26.316μs。CMT载波发生器通过设置高电平时间CCH和低电平时间CCL来合成周期。我们需要将26.316μs分配到CCH和CCL上且每个单位是1/CMTCLK 0.5μs。总计数 26.316μs / 0.5μs ≈ 52.63取整为53个时钟周期。按1/3占空比高电平时间 ≈ 26.316/3 ≈ 8.77μs对应计数 ≈ 17.54取整。我们可以设置CCH63μsCCL4723.5μs这样周期为26.5μs频率约37.74kHz在误差允许范围内。实际应用中需根据接收头灵敏度微调。写入寄存器CCH1 0x86假设CMTPOL1IROLN0CCL1 0x2F二进制0010 1111注意高两位为0。计算调制时间参数时间分辨率4μs。560μs的标记期需要MBUFF 560 / 4 - 1 139。因为 t_mark (MBUFF1)*4μs。560μs的空间期需要SBUFF 560 / 4 140。MBUFF和SBUFF都是12位寄存器0-4095通过CMD1、CMD2、CMD3三个8位寄存器访问。我们将MBUFF1390x008BSBUFF1400x008C写入。配置控制寄存器设置CMCS寄存器。假设我们启用结束中断EOCIE1选择时间模式MODE0 BASE0禁用扩展空间EXSPC0不分频DIV20。则CMCS初始值可设为0x42二进制0100 0010EOCF位只读默认为0。启动发射最后将MCGEN位CMCS bit 0置1模块开始工作。当第一个560μs的载波脉冲发射完毕进入560μs空间期时EOCF标志位会置1如果中断已开启则触发中断。在中断服务程序中我们可以更新MBUFF和SBUFF的值以产生下一个脉冲例如发送一个560μs脉冲后跟1680μs空间代表逻辑‘1’从而实现完整的红外协议编码。3.2 基带模式Baseband Mode直接数字信号输出基带模式MODE0 BASE1是时间模式的一个变体。它与时间模式的计算公式完全一样唯一的区别是载波发生器被强制关闭输出固定为逻辑高电平。在这种模式下IRO引脚直接输出由MBUFF和SBUFF控制的数字脉冲波形没有载波调制。这有什么用呢它适用于那些不需要载波调制的通信场景例如驱动红外接收头如HS0038B的输出信号本身就是解调后的数字信号在某些调试或直连应用中可能需要模拟这种信号。生成精确的PWM信号用于控制舵机、LED调光等。实现自定义的、低速的串行数字通信协议。注意事项基带模式的输出电平在基带模式下输出逻辑高电平的实际电压是MCU的VDD。如果你的后端电路需要不同的电平如驱动一个NPN三极管可能需要加上拉电阻或电平转换电路。同时由于没有载波信号的抗干扰能力会变差通常只用于短距离或屏蔽良好的环境。3.3 FSK模式FSK Mode生成相位相干频移键控信号FSK模式MODE1是CMT模块的高级功能用于生成相位相干的频移键控信号。在这种模式下调制器的工作方式与时间模式类似但有一个根本区别时间基准从CMTCLK÷8切换为了当前的载波频率f_CG本身。标记时间 (t_mark):(MBUFF 1) / f_CG秒空间时间 (t_space):SBUFF / f_CG秒更重要的是每当一个空间期结束时载波发生器会自动在主CCH1/CCL1和次CCH2/CCL2两组频率寄存器之间切换。这就意味着你可以用一组寄存器定义频率F1代表逻辑0用另一组定义频率F2代表逻辑1。调制器会控制每个频率的发射持续时间标记期和静默间隔空间期从而生成一个纯净的、相位连续的FSK信号。配置示例生成一个简单的1200Hz/2200Hz的FSK信号假设我们需要用FSK表示数据逻辑‘0’用1200Hz的1个周期表示逻辑‘1’用2200Hz的1个周期表示每个符号后跟一个短暂的静默空间。计算载波频率参数总线时钟2MHzCMTCLK2MHz。我们需要计算产生1200Hz和2200Hz方波的CCH/CCL值。对于1200Hz周期T0 1/1200 ≈ 833.33μs。每个CMTCLK周期0.5μs总计数 833.33 / 0.5 ≈ 1666.67。我们需要将1667个时钟周期分配到高电平和低电平。为了产生50%占空比的方波可以设置高电平计数 低电平计数 总计数/2。但CCH/CCL是6位寄存器0-63最大只能表示63这显然不够。这里是一个关键点CMT的载波发生器高/低时间寄存器只有6-7位这意味着它直接能生成的载波频率是相对较高的。对于几百Hz到几KHz的低频FSK直接计算出的计数值会溢出寄存器范围。因此CMT的FSK模式通常用于生成几十KHz以上的射频或超声载波的FSK调制而不是直接生成音频FSK基带信号。对于音频FSK更常见的做法是用CMT生成一个中心频率较高的载波如32kHz然后通过外部电路或软件进行混频/分频得到音频信号。或者使用MCU的其他定时器如PWM来生成低频FSK。假设我们生成一个32kHz/40kHz的FSK适用于超声波通信或某些无线模块32kHz周期31.25μs计数62.5取整63。设CCH116 CCL147主频。40kHz周期25μs计数50。设CCH213 CCL237次频。计算调制时间我们希望每个频率持续1ms。对于32kHz段f_CG 32kHz。t_mark 1ms 0.001s。MBUFF t_mark * f_CG - 1 0.001 * 32000 - 1 31。空间期设为一个载波周期方便相位连续SBUFF 1。工作流程设置MODE1写入主/次频率寄存器写入MBUFF31 SBUFF1。启动后模块会先以32kHz频率输出1ms静默约31.25μs1个40kHz周期然后自动切换到40kHz频率输出1ms如此循环。通过动态更新MBUFF/SBUFF可以形成FSK数据流。避坑指南FSK模式下的空间期与相位连续FSK模式设计的一个精妙之处在于它通过空间期SBUFF实现了频率切换时的“无毛刺”过渡。当SBUFF0时模块会在标记期结束后立即切换频率并开始下一个标记期中间没有任何间隙这保证了信号的相位相干性对于某些通信系统的解调性能至关重要。务必理解SBUFF在FSK模式下的这个特殊作用。4. 扩展空间操作与高级时序控制技巧CMT模块提供了一个强大的“扩展空间EXSPC”功能这个功能在数据手册里可能一笔带过但在实现复杂协议时极其有用。4.1 扩展空间原理与应用场景当CMCS寄存器中的EXSPC位被置1时调制器会进入扩展空间模式。在这个模式下下一个调制周期以及之后的所有周期直到EXSPC被清零将变成一个超长的空间期其长度等于原本的标记期和空间期之和。简单说就是让输出保持静默低电平一段很长的时间。计算公式时间/基带模式t_extended_space [ (SBUFF1) (MBUFF21SBUFF2) ... (MBUFFn1SBUFFn) ] * (8 / CMTCLK)其中下标1,2,...n代表EXSPC位被置位期间经历的各个调制周期。这个功能有什么用模拟零标记事件某些红外协议如NEC的重复码是一个很长的低电平9ms后跟一个短脉冲。你可以通过设置一个很短的“虚拟”标记和很长的空间来模拟但SBUFF有最大值4095。利用EXSPC你可以将多个标准周期的静默时间无缝连接起来形成一个远超SBUFF上限的长空间。实现非周期性的长延迟在发送一帧数据后可能需要等待数十甚至数百毫秒再发送下一帧。使用EXSPC你可以在不占用CPU进行软件延时的情况下由硬件自动生成这段超长的静默间隔CPU可以进入低功耗的等待模式。动态协议切换你可以在发送过程中通过设置EXSPC插入一个确定长度的静默期然后在这段时间内快速更新CMT的配置如切换模式、改变载波频率为发送另一种协议的数据做准备。4.2 扩展空间实战配置假设我们需要在发送一个脉冲后产生一个20ms的静默期。系统时钟2MHzDIV20时间分辨率4μs。20ms需要 20000μs / 4μs 5000 个时间单位。这超过了SBUFF的最大值4095。方案我们可以设置一个正常的脉冲比如MBUFF249产生1ms脉冲SBUFF0。然后在发送这个脉冲之前或之后通过EOC中断将EXSPC位置1。计算我们需要让EXSPC覆盖多个周期来累加出20ms。假设我们让EXSPC持续5个周期。周期1EXSPC刚被设置SBUFF1 0我们设定的空间。周期2-5我们需要设置MBUFF和SBUFF使得它们的和满足要求。20ms 5000个单位。第一个周期贡献了 SBUFF10。我们需要剩余周期贡献5000个单位。我们可以设置后续的MBUFF0 SBUFF1250。这样每个后续周期的贡献是 (011250)1251个单位。4个这样的周期贡献5004个单位略微超过20ms20.016ms在可接受误差内。操作步骤初始化CMT设置MBUFF249 SBUFF0。启动发射MCGEN1。第一个1ms脉冲发出。在EOC中断服务程序中将EXSPC位置1并更新MBUFF0 SBUFF1250。模块进入扩展空间模式开始长达约20ms的静默。静默结束后会触发EOC中断在中断服务程序中清除EXSPC位并重新加载正常的数据模式寄存器值继续后续发射。重要警告EXSPC在FSK模式下的复杂性在FSK模式下使用EXSPC需要格外小心因为扩展空间的计算公式依赖于当前是主频周期还是次频周期。而软件无法直接读取当前是哪个频率周期。因此软件必须自己维护一个状态机来跟踪当前是主频还是次频周期然后根据不同的公式计算总时间。如果跟踪错误会导致产生的静默期长度不符合预期。在非必要情况下FSK模式中尽量避免使用EXSPC或者使用固定的、已知的MBUFF/SBUFF序列来简化计算。5. 寄存器配置详解与编程实战指南理解了原理最终要落到代码上。CMT模块的所有操作都通过一组内存映射寄存器完成。这里我们抛开数据手册的罗列从编程者角度梳理关键点和操作流程。5.1 关键寄存器精讲与操作序列载波发生器数据寄存器 (CCH1, CCL1, CCH2, CCL2)地址$0010 - $0013。核心功能定义载波波形。CCHx定义高电平时间计数CCLx定义低电平时间计数。计数值是写入值的二进制表示。例如写入CCH15表示高电平持续5个CMTCLK周期。坑点1位域复用。CCH1的bit7是IROLNbit6是CMTPOL。这意味着当你写入CCH1设置频率时会同时改变IRO锁存器状态和输出极性务必在初始化时一次性将CMTPOL和IROLN的期望值通常CMTPOL1 IROLN0与频率值组合成一个字节写入。坑点2CCL1只有低7位有效bit7是IROLP。写入时同样要注意组合。初始化顺序先配置好CCH1/CCL1主频和CCH2/CCL2次频FSK模式用确保写入的值非零。为零会导致不可预测的行为。调制器控制与状态寄存器 (CMCS)地址$0014。这是核心控制寄存器。必须理解每一位MCGEN (Bit 0)总开关。必须在所有数据寄存器配置完成后最后置1。清零它会停止当前周期后关闭模块。EOCIE (Bit 1)结束中断使能。如果希望在每个调制周期结束时由硬件自动更新数据用于发送流式数据必须开启此中断。MODE (Bit 2)模式选择。0时间/基带1FSK。BASE (Bit 3)基带使能。1基带模式关闭载波0载波使能。EXSPC (Bit 4)扩展空间使能。动态控制长静默。DIV2 (Bit 6)时钟2分频。此位非双缓冲禁止在发射过程中修改EOCF (Bit 7)结束标志位只读。每个调制周期结束包括初始启动时置1。清除方法特殊必须先读CMCS寄存器再读或写CMD2或CMD3寄存器。通常在中断服务程序中按此序列清除。调制器周期数据寄存器 (CMD1, CMD2, CMD3)地址$0015 - $0017。功能这是MBUFF和SBUFF的映射窗口。CMD2是MBUFF低8位CMD3是SBUFF低8位CMD1的高4位是MBUFF高4位低4位是SBUFF高4位。双缓冲机制写入CMD1/2/3只是写入了缓冲区。真正的MBUFF和SBUFF是在每个调制周期结束时从缓冲区加载到工作寄存器的。这保证了你在发送当前脉冲的同时可以准备下一个脉冲的参数实现无缝流式输出。编程技巧如果你只需要8位精度即MBUFF和SBUFF值都小于256那么可以只写CMD2和CMD3并将CMD1清零。这可以减少一次写操作。5.2 完整初始化与发射流程代码框架C语言示例以下是一个基于时间模式发送NEC协议引导码9ms载波4.5ms空间的示例框架。假设总线时钟2MHz使用38kHz载波。// 寄存器地址定义根据你的编译器头文件调整 #define CCH1 (*(volatile unsigned char*)0x0010) #define CCL1 (*(volatile unsigned char*)0x0011) #define CMCS (*(volatile unsigned char*)0x0014) #define CMD1 (*(volatile unsigned char*)0x0015) #define CMD2 (*(volatile unsigned char*)0x0016) #define CMD3 (*(volatile unsigned char*)0x0017) // 时间计算宏us_to_units 将微秒转换为CMT时间单位4us/单位 #define CMT_CLK_MHZ 2.0 #define TIME_UNIT_US (8.0 / CMT_CLK_MHZ) // 4us #define us_to_units(us) ((unsigned int)((us) / TIME_UNIT_US 0.5)) void CMT_Init(void) { // 1. 配置载波发生器产生~38kHz载波 (以2MHz时钟CCH6, CCL47为例) // 注意CCH1的bit6是CMTPOL(1:低有效)bit7是IROLN(通常0) // 所以写入的值 (IROLN7) | (CMTPOL6) | (CCH_VALUE) // 假设我们需要低电平有效(CMTPOL1)IROLN0CCH值6 CCH1 (07) | (16) | 6; // 写入 0x46 CCL1 47; // 0x2F注意CCL1只有低7位有效bit7是IROLP // 2. 配置调制器数据寄存器发送NEC引导码 9ms Mark, 4.5ms Space unsigned int mark_units us_to_units(9000) - 1; // MBUFF t_mark/4us - 1 unsigned int space_units us_to_units(4500); // SBUFF t_space/4us // 拆分12位的MBUFF和SBUFF到CMD1/2/3 CMD2 (unsigned char)(mark_units 0xFF); // MBUFF低8位 CMD3 (unsigned char)(space_units 0xFF); // SBUFF低8位 CMD1 ((unsigned char)((mark_units 8) 0x0F) 4) | ((unsigned char)((space_units 8) 0x0F)); // 高4位组合 // 3. 配置控制寄存器时间模式使能结束中断不扩展空间不分频 // CMCS [EOCF(RO)][DIV20][0][EXSPC0][BASE0][MODE0][EOCIE1][MCGEN0] // 先不启动所以MCGEN0 CMCS 0x02; // 二进制 0000 0010 } void CMT_StartTransmission(void) { // 4. 最后置位MCGEN启动发射 CMCS | 0x01; // 设置MCGEN位为1 } // CMT中断服务例程假设已正确配置中断向量 void __interrupt CMT_ISR(void) { if (/* 判断是CMT中断 */) { // 5. 清除EOCF标志读CMCS然后访问CMD2或CMD3 unsigned char dummy CMCS; // 读CMCS dummy CMD2; // 访问CMD2读或写皆可 // 6. 在此更新CMD1/2/3为下一个脉冲准备数据 // 例如发送完引导码后接下来发送地址码的脉冲... // update_next_pulse_data(); // 清除MCU的中断标志位具体操作取决于MCU型号 } }6. 低功耗模式、中断处理与实战避坑指南在实际产品中功耗和稳定性是必须考虑的。CMT模块在这两方面都有相应的设计但使用不当也会带来问题。6.1 等待模式与停止模式下的行为等待模式Wait Mode执行WAIT指令后CPU停止运行但外设时钟包括CMT通常继续运行。这意味着CMT可以继续发射信号这是一个非常有用的特性你可以在CPU休眠时让CMT发送一个很长的、由EXSPC功能产生的静默间隔从而极大降低系统平均功耗。当CMT产生EOC中断时可以唤醒CPU。注意事项如果不需要CMT在等待模式下工作务必在进入等待模式前清除MCGEN位以关闭CMT节省功耗。停止模式Stop Mode执行STOP指令后所有时钟停止CMT模块也完全冻结。这是一个潜在的巨坑如果CMT正在发射时进入停止模式IRO引脚会保持在其进入停止模式瞬间的状态可能是高也可能是低。如果此时IRO引脚是低电平正在驱动红外管发光那么红外管会持续导通直到MCU被唤醒这可能导致红外管过热烧毁或电池快速耗尽。致命警告进入STOP模式前的安全操作绝对禁止在MCGEN1CMT正在发射时直接进入STOP模式。安全的做法是清除MCGEN位请求停止CMT。等待最后一个调制周期完成。由于清除MCGEN后当前周期会继续完成你需要等待一段时间或者通过轮询EOCF标志如果未用中断来确认发射已真正停止。确认发射停止后再执行STOP指令。数据手册中明确提到了这个“timeout period”。6.2 中断服务程序编写要点CMT的中断相对简单只有EOC周期结束中断。但编写ISR时有几个细节必须注意标志清除序列必须严格按照“读CMCS - 访问CMD2或CMD3”的顺序来清除EOCF标志。任何其他顺序都可能导致标志无法清除或产生虚假中断。数据更新时机在EOC中断中更新MBUFF/SBUFF即写CMD1/2/3是安全的因为双缓冲机制确保了新值会在下一个周期开始时才被加载。你可以流畅地连续发送不同宽度的脉冲序列。中断响应时间确保你的ISR执行时间包括清除标志、更新数据、其他处理短于当前设置的空间期SBUFF时间。否则当下一个周期开始时你可能还没来得及准备好新数据导致发送错误。对于高速协议ISR必须极度精简。6.3 常见问题排查速查表现象可能原因排查步骤与解决方案无输出1. IRO引脚未正确配置为输出。2. MCGEN位未置1。3. 载波寄存器CCH1/CCL1值为0。4. 输出极性CMTPOL设置错误实际有输出但电平反相。1. 检查端口数据方向寄存器DDR确保IRO对应引脚设为输出。2. 单步调试确认CMCS寄存器的bit0为1。3. 检查CCH1/CCL1确保写入非零值。4. 用示波器测量IRO引脚或设置CMTPOL为相反值试试。输出波形频率不对1. 系统时钟频率计算错误。2. CMTCLK分频DIV2设置错误。3. CCH/CCL计算错误未考虑寄存器位数限制。1. 确认晶振频率、锁相环PLL配置、总线分频比。2. 核对CMCS寄存器的DIV2位。3. 重新计算载波周期 (CCH1 CCL1) / CMTCLK。脉冲宽度不准1. MBUFF/SBUFF计算错误忽略了“MBUFF1”。2. 时间单位算错混淆了CMTCLK和CMTCLK/8。3. 在发射过程中修改了DIV2、MODE、BASE等非双缓冲位。1. 复核公式t_mark (MBUFF1)*8/CMTCLK。2. 时间/基带模式基准是CMTCLK/8FSK模式基准是f_CG。3.仅在MCGEN0时修改这些控制位。FSK模式频率不切换1. MODE位未设置为1。2. 次频率寄存器CCH2/CCL2未正确初始化或值为0。3. SBUFF设置过大导致空间期过长观察时间不够。1. 确认CMCS的MODE位1。2. 检查并写入有效的CCH2/CCL2值。3. 尝试将SBUFF设为0观察频率是否在每个标记期后立即切换。中断不触发或连续触发1. 中断未全局开启或向量未配置。2. EOCIE位未置1。3. EOCF标志清除序列错误。4. ISR执行时间过长错过下一个中断。1. 确认MCU全局中断使能CMT中断向量指向正确ISR。2. 确认CMCS的EOCIE位1。3.严格按“读CMCS-访问CMD2/3”顺序清除。4. 优化ISR代码或增加SBUFF时间。使用EXSPC后静默时间不对1. 在FSK模式下未跟踪主/次周期状态用错公式。2. 在EXSPC被清除后未正确加载下一个正常周期的数据。1. 在FSK模式下使用EXSPC时软件必须维护当前频率状态。2. 在清除EXSPC的那个EOC中断里确保写入了下一个正常脉冲的MBUFF/SBUFF。最后调试CMT最有力的工具是示波器或逻辑分析仪。直接观察IRO引脚上的波形测量脉冲宽度、空间宽度、载波频率是与理论计算对比、发现配置错误的最直接方法。从一个简单的固定脉冲开始调试逐步增加复杂度是驾驭这个强大模块的不二法门。

相关新闻