MC68HC908AZ60A TIMB模块详解:输入捕获、输出比较与PWM实战配置

AI助手已提取文章相关产品:

1. 项目概述:深入理解MC68HC908AZ60A的TIMB模块

在嵌入式开发,尤其是涉及电机驱动、电源管理或通信协议解析的项目里,精准的时序控制往往是决定系统稳定性和性能的关键。很多新手工程师在面对数据手册中复杂的定时器章节时,常常感到无从下手,寄存器配置表看花了眼,功能描述读起来也似懂非懂。如果你正在使用Freescale(现NXP)的MC68HC908AZ60A这款经典的8位微控制器,并且需要用到它的Timer Interface Module B(TIMB),那么这篇文章就是为你准备的。我将结合自己多年在工业控制项目中使用HC08系列MCU的经验,为你彻底拆解TIMB模块的输入捕获、输出比较和PWM功能,把数据手册里那些干巴巴的描述,变成可以直接“抄作业”的配置步骤和避坑指南。

MC68HC908AZ60A的TIMB模块是一个16位的定时器,它最核心的价值在于,能用硬件帮你完成“计时”和“比较”这两件最耗CPU精力的事。想象一下,你需要测量一个传感器脉冲的宽度,如果让CPU不停地去查询引脚状态并记录时间,那CPU就几乎干不了别的了。而输入捕获功能,可以在脉冲边沿到来的瞬间,自动把当前定时器的计数值“冻结”到寄存器里,你只需要在合适的时候去读取这个值即可。同样,输出比较功能可以让你设定一个时间点,时间一到,硬件自动改变引脚电平,生成精准的方波,CPU完全不用干预。PWM(脉冲宽度调制)则是输出比较的一种高级应用,通过周期性改变输出比较值,就能生成占空比可调的波形,这是驱动电机、LED调光、DAC模拟的基础。

这个TIMB模块提供了两个独立的通道(Channel 0和Channel 1),每个通道都可以被灵活配置为输入捕获或输出比较模式。更厉害的是,这两个通道还能“联手”工作,形成 缓冲输出比较 缓冲PWM 模式,这能在不干扰当前输出波形的前提下,提前准备好下一个周期的参数,实现无缝切换,对于生成复杂、稳定的波形至关重要。接下来,我们就从最根本的模块结构和寄存器配置讲起,一步步摸清它的脾气。

2. TIMB模块整体架构与核心寄存器解析

要驾驭TIMB,首先得看懂它的“大脑”和“手脚”——也就是控制寄存器与数据通路。很多朋友一上来就照着例程配置,结果出了问题也不知道寄存器某一位到底起了什么作用,调试起来一头雾水。我们必须先建立起清晰的模块框图。

2.1 模块核心:16位计数器与时钟源

TIMB的核心是一个16位向上计数器(TBCNTH:TBCNTL)。它可以工作在两种模式下: 自由运行模式 模数计数模式 。在自由运行模式下,计数器从0x0000开始,一直累加到0xFFFF,然后溢出回到0x0000重新开始,如此循环。在模数计数模式下,计数器从0x0000开始,累加到我们预设的一个模数值(存放在TBMODH:TBMODL寄存器中),然后溢出归零。这个模数值就决定了定时器溢出的周期,是PWM周期和许多定时任务的时间基准。

这个计数器的“心跳”时钟从哪里来?由TIMB状态控制寄存器(TBSC)中的PS[2:0]这三位决定。它们提供了7个内部总线时钟的分频选项(1, 2, 4, 8, 16, 32, 64分频)和一个外部时钟输入选项。

关键经验 :选择时钟源是计算所有时间参数的第一步。例如,如果你的系统总线频率是8MHz,选择4分频(PS[2:0]=010),那么TIMB的计数时钟就是2MHz,每个计数周期就是0.5微秒。这直接决定了你能测量的最小时间分辨率(0.5us)和能生成的最短PWM脉冲。

外部时钟通过PTD4/ATD12/TBCLK引脚输入,最高频率不能超过4MHz或总线频率的一半(取两者中较小值)。使用外部时钟时,需要将PS[2:0]设置为111,并且将该引脚配置为输入(无论DDRD4如何设置,此时它都是输入模式)。

2.2 控制与状态寄存器:TBSC

地址 $0040 的TBSC寄存器是TIMB的总指挥。我们逐位分析:

  • TOF(Bit 7) :溢出标志位。当计数器达到模数值(模数模式)或0xFFFF(自由运行模式)时,硬件自动置1。 清除它需要“读-改-写”操作 :先读取TBSC(此时TOF=1),然后向TOF位写0。这个顺序很重要,是防止丢失中断请求的关键机制。
  • TOIE(Bit 6) :溢出中断使能位。置1后,当TOF=1时,会向CPU申请中断。
  • TSTOP(Bit 5) :定时器停止位。置1则计数器暂停。 特别注意 :在需要TIMB中断唤醒WAIT模式的场景下,绝对不能设置此位。同时,如果设置此位前有定时器标志位(如TOF)已经置1,必须先清除TSTOP,再清除标志位,最后再置位TSTOP,否则标志位可能无法正确清除。
  • TRST(Bit 4) :定时器复位位。 这是一个只写位,读出来永远是0 。向它写1会立即将计数器和预分频器清零,然后从0开始计数。它不影响其他任何寄存器。通常用于定时器的精确同步启动。
  • PS[2:0](Bit 2-0) :如前所述,时钟预分频选择位。

2.3 通道控制寄存器:TBSC0与TBSC1

每个通道都有一个自己的控制寄存器(TBSC0地址 $0045 ,TBSC1地址 $0048 ),结构类似但略有不同(Channel 1没有MS1B位)。它们是配置通道具体行为的关键。

  • CHxF(Bit 7) :通道x标志位。在输入捕获模式下,当指定边沿到来时置1;在输出比较模式下,当计数器值与通道寄存器值匹配时置1。清除方式同TOF,也需要“读-改-写”序列。
  • CHxIE(Bit 6) :通道x中断使能位。
  • MSxB(仅TBSC0有,Bit 5) :模式选择B位。这是实现 缓冲模式 的开关。 只有当MS0B=1时,Channel 0和Channel 1才会被链接起来,用于缓冲输出比较或缓冲PWM,此时Channel 1的控制寄存器TBSC1失效,其引脚PTF5/TBCH1可作为通用IO使用。
  • MSxA(Bit 4) :模式选择A位。它与ELSxB:A位共同决定通道模式,具体组合见下文表格。
  • ELSxB, ELSxA(Bit 3, Bit 2) :边沿/电平选择位。这是配置中最灵活也最容易出错的地方。它根据MSxA的状态,有不同的含义:
    1. 当通道被配置为输入捕获(MSxA=0)时,它们选择捕获边沿:01=上升沿,10=下降沿,11=任意边沿。
    2. 当通道被配置为输出比较/PWM(MSxA=1)时,它们选择匹配动作:01=翻转,10=清零,11=置位。
    3. 当ELSxB:A = 00时,通道与引脚断开,引脚归端口控制。此时MSxA决定引脚初始电平(1=低,0=高)。
  • TOVx(Bit 1) :溢出翻转位。这是实现PWM功能的核心之一。置1后,每次定时器溢出(TOF置位)时,对应通道的引脚电平会自动翻转。 对于PWM生成,此位必须置1
  • CHxMAX(Bit 0) :通道x最大占空比位。当TOVx=1且CHxMAX=1时,会强制输出100%占空比(常高)的PWM信号。结合TOVx=0可以产生0%占空比(常低)。

为了更直观地理解MSx和ELSx位的组合,我将数据手册中的表格重新整理并加入了中文注释:

MSxB MSxA ELSxB ELSxA 模式与配置 功能说明
X 0 0 0 输出预置 引脚由端口控制,初始输出高电平(MSxA=0)
X 1 0 0 输出预置 引脚由端口控制,初始输出低电平(MSxA=1)
0 0 0 1 输入捕获 仅在上升沿触发捕获
0 0 1 0 输入捕获 仅在下降沿触发捕获
0 0 1 1 输入捕获 上升沿或下降沿均触发捕获
0 1 0 0 输出比较/PWM 软件比较 (仅置标志,不操作引脚)
0 1 0 1 输出比较/PWM 比较匹配时翻转引脚
0 1 1 0 输出比较/PWM 比较匹配时清零引脚(输出低)
0 1 1 1 输出比较/PWM 比较匹配时置位引脚(输出高)
1 X 0 1 缓冲输出比较/PWM 比较匹配时翻转引脚 (双通道缓冲)
1 X 1 0 缓冲输出比较/PWM 比较匹配时清零引脚 (双通道缓冲)
1 X 1 1 缓冲输出比较/PWM 比较匹配时置位引脚 (双通道缓冲)

2.4 数据寄存器:计数器、模值与通道寄存器

  • TIMB计数器寄存器(TBCNTH: $0041 , TBCNTL: $0042 :只读。这里有个 重要细节 :读取高字节(TBCNTH)时,低字节(TBCNTL)的当前值会被锁存到一个缓冲区。后续读取TBCNTH得到的都是这个锁存值,直到你读取一次TBCNTL,这个锁存才会更新。因此,为了读取完整的16位计数器值,必须先读TBCNTH,再读TBCNTL。 在断点中断中读取时,务必在退出断点前读取TBCNTL来解锁,否则TBCNTL将一直保持断点时的锁存值。
  • TIMB计数器模数寄存器(TBMODH: $0043 , TBMODL: $0044 :读写。设置模数值。 写入时必须先写高字节(TBMODH),再写低字节(TBMODL) 。在写高字节后、写低字节前,溢出标志TOF和溢出中断会被禁止,以防止出现错误的溢出事件。 最佳实践是,在修改模数值前,先用TRST位复位计数器。
  • TIMB通道寄存器(TBCH0H: $0046 , TBCH0L: $0047 , TBCH1H: $0049 , TBCH1L: $004A :读写。在输入捕获模式下,它们是只读的,存放捕获到的计数值。在输出比较/PWM模式下,它们存放用于比较的目标值。

3. 三大功能模式详解与实战配置

理解了寄存器,我们就可以深入三大功能模式了。我会为每种模式提供清晰的配置流程、代码片段(基于C语言伪代码)和必须注意的“坑”。

3.1 输入捕获模式:精准测量时间间隔

输入捕获的本质,是在你关心的外部事件(引脚边沿)发生的那个瞬间,让硬件自动“拍一张快照”,把当前计数器的值保存起来。这常用于测量脉冲宽度、信号周期或频率。

配置流程与示例:测量PTF4引脚上正脉冲的宽度

假设我们需要测量PTF4/TBCH0引脚上一个正脉冲的高电平持续时间。思路是:在上升沿和下降沿各捕获一次,两次捕获值之差就是高电平持续的计数次数,再乘以计数周期就得到时间。

  1. 初始化TIMB基础时钟 :假设总线频率8MHz,我们选择8分频,则TIMB时钟为1MHz,计数周期为1us。

    // TBSC: 停止定时器,复位,选择时钟,禁止溢出中断
    TBSC = 0x20 | 0x10 | 0x03; // TSTOP=1, TRST=1, PS=011 (8分频)
    // 注意:TRST是只写位,上述操作后应清除TRST启动,但通常先配置其他寄存器
    
  2. 配置通道0为输入捕获 :捕获上升沿和下降沿。

    // TBSC0: 输入捕获模式,任意边沿触发,禁止中断(先轮询)
    // MS0A=0 (输入捕获), ELS0B:A=11 (任意边沿)
    TBSC0 = 0x0C; // 二进制 0000 1100
    
  3. 启动定时器并清空旧标志

    // 清除可能存在的旧标志
    dummy = TBSC0; // 读操作
    TBSC0 &= ~0x80; // 写0清除CH0F
    dummy = TBSC; // 读操作
    TBSC &= ~0x80; // 写0清除TOF
    // 启动定时器:清除TSTOP和TRST
    TBSC &= ~0x30; // 清除TSTOP(bit5)和TRST(bit4)
    
  4. 等待并处理捕获事件

    unsigned int rise_time, fall_time, pulse_width;
    // 等待上升沿
    while(!(TBSC0 & 0x80)); // 等待CH0F置位
    rise_time = (unsigned int)TBCH0H << 8 | TBCH0L;
    dummy = TBSC0;
    TBSC0 &= ~0x80; // 清除CH0F标志
    // 等待下降沿
    while(!(TBSC0 & 0x80));
    fall_time = (unsigned int)TBCH0H << 8 | TBCH0L;
    // 计算脉冲宽度(考虑计数器溢出)
    if(fall_time >= rise_time) {
        pulse_width = fall_time - rise_time;
    } else {
        // 发生了溢出,需要结合溢出次数计算,这里简化处理
        pulse_width = (65536 - rise_time) + fall_time;
    }
    // 实际时间 = pulse_width * 1 us (根据时钟分频计算)
    

避坑指南

  • 边沿稳定性 :在使能输入捕获前,务必确保目标引脚的电平已经稳定了至少两个总线周期,否则可能捕获到毛刺。
  • 计数器溢出处理 :在测量长间隔信号时,定时器可能溢出多次。简单的差值计算会出错。 可靠的方案是 :开启溢出中断(TOIE=1),在中断服务程序里维护一个软件扩展的“溢出计数器”(比如一个 volatile unsigned long overflow_count )。计算时间时: 总时间 = (overflow_count * 65536) + (capture_value - previous_capture_value) 。在捕获中断里也要记录对应的溢出计数。
  • 标志清除顺序 :务必遵循“先读寄存器(标志位置1时),再写0清除”的顺序。直接写0是无效的。

3.2 输出比较模式:硬件定时与波形生成

输出比较模式是让硬件帮你“守时”。你设定一个目标计数值(存入通道寄存器),当定时器计数达到这个值时,硬件会自动执行你预设的动作(置高、置低或翻转引脚),并可以产生中断。这非常适合生成精确的延时、方波或驱动时序。

配置流程与示例:在PTF4引脚生成一个1KHz,占空比50%的方波

假设TIMB时钟为1MHz(8MHz总线,8分频)。1KHz方波周期为1ms,即1000个计数周期。50%占空比意味着高电平持续500个计数周期。

  1. 初始化TIMB基础时钟与模值 :我们使用自由运行模式(模值寄存器保持0xFFFF),或者将模值设为999(0x03E7)以实现精确的1ms溢出周期。这里采用模数模式,方便后续扩展。
    // 1. 停止并复位定时器
    TBSC = 0x30 | 0x03; // TSTOP=1, TRST=1, PS=011
    // 2. 设置模值,决定方波周期 (1000个计数 -> 1ms)
    TBMODH = 0x03; // 1000 = 0x03E8
    TBMODL = 0xE8; // 注意:先写高字节,再写低字节
    // 3. 配置通道0为输出比较,匹配时翻转引脚,并使能溢出翻转(用于生成周期)
    // MS0A=1 (输出比较), ELS0B:A=01 (翻转), TOV0=1 (溢出时也翻转)
    TBSC0 = 0x12; // 二进制 0001 0010
    // 4. 设置比较值,决定第一次翻转(即上升沿)的时间点 (500个计数 -> 0.5ms)
    TBCH0H = 0x01;
    TBCH0L = 0xF4; // 500 = 0x01F4
    // 5. 启动定时器
    TBSC &= ~0x30; // 清除TSTOP和TRST
    

这段代码配置后,引脚PTF4会输出精确的1KHz方波。其工作原理是:

  • 计数器从0开始,计数到500(0x01F4)时,发生比较匹配,根据ELS0B:A=01的配置,引脚电平翻转(假设初始为低,则变为高)。
  • 计数器继续计数到1000(0x03E8)时,发生溢出(TOF置位),根据TOV0=1的配置,引脚电平再次翻转(高变回低)。同时计数器归零,开始下一个周期。
  • 如此循环,就得到了周期1ms(1000计数)、高电平0.5ms(500计数)的方波。

核心要点 :在这个例子中, 输出比较决定了脉冲的边沿(上升沿),而定时器溢出决定了周期的结束(下降沿) 。两者结合才构成了一个完整的PWM周期。这正是PWM模式的基础。

3.3 PWM模式:缓冲与非缓冲的深度解析

PWM可以看作是输出比较的一种自动化、周期性的应用。TIMB支持两种PWM生成方式: 非缓冲PWM 缓冲PWM 。它们的区别是更新占空比时的“安全性”。

非缓冲PWM :直接向当前正在控制输出的通道寄存器写入新的比较值。如果写入时机不对(比如在计数器已经超过新旧值之间的某个时刻写入),可能导致当前周期波形错误,甚至丢失一次比较事件。数据手册给出了安全的更新策略:

  • 当需要减小占空比(新值 < 旧值)时 :在 输出比较中断 中更新新值。因为中断发生在当前脉冲边沿之后,你有整个剩余周期的时间去写入,确保在下一个周期生效。
  • 当需要增大占空比(新值 > 旧值)时 :在 定时器溢出中断 中更新新值。因为中断发生在周期结束、新周期开始时,此时写入最安全。如果在输出比较中断中写入一个更大的值,可能导致在当前周期内发生第二次比较匹配,产生错误波形。

缓冲PWM(双通道链接) :这是TIMB的一个高级特性,通过将Channel 0和Channel 1链接起来实现。其核心思想是“双缓冲”或“乒乓缓冲”:一个通道(例如Ch0)控制当前周期的输出,另一个通道(Ch1)则预先写入下一个周期的值。在当前周期结束时(溢出瞬间),硬件会自动切换,让Ch1的值生效,同时Ch0变为缓冲寄存器,可以安全地写入再下一个周期的值。这样就完全避免了写入冲突,可以实现平滑、无毛刺的PWM更新,特别适用于电机控制等对波形连续性要求高的场合。

配置流程与示例:在PTF4引脚生成缓冲PWM,频率100Hz,初始占空比30%

假设总线频率8MHz,预分频64,则TIMB时钟为125KHz。100Hz对应周期10ms,即1250个计数周期。30%占空比对应高电平时间375个计数周期。

  1. 初始化TIMB

    // 1. 停止并复位定时器
    TBSC = 0x30 | 0x06; // TSTOP=1, TRST=1, PS=110 (64分频)
    // 2. 设置PWM周期 (1250 = 0x04E2)
    TBMODH = 0x04;
    TBMODL = 0xE2;
    // 3. 配置通道0和1为缓冲PWM模式
    // 首先,设置TBSC0:MS0B=1 (使能缓冲模式), MS0A无关, ELS0B:A=10 (匹配时清零引脚), TOV0=1 (溢出翻转)
    // 我们希望PWM高电平有效,则匹配时应清零(变低),溢出时翻转(变高)。
    TBSC0 = 0x2C; // 二进制 0010 1100 (MS0B=1, ELS0B:A=10, TOV0=1)
    // 此时,TBSC1寄存器被忽略,PTF5/TBCH1引脚可作为通用IO。
    
  2. 设置初始占空比

    // 4. 初始输出由Channel 0寄存器控制。设置比较值(决定高电平结束时间)
    // 占空比30%,高电平时间 = 1250 * 0.3 = 375 = 0x0177
    TBCH0H = 0x01;
    TBCH0L = 0x77;
    // 5. 预先填充Channel 1寄存器(缓冲寄存器),假设我们下一个周期想改为50%占空比
    // 50%占空比,高电平时间 = 1250 * 0.5 = 625 = 0x0271
    TBCH1H = 0x02;
    TBCH1L = 0x71;
    
  3. 启动定时器

    // 6. 启动定时器
    TBSC &= ~0x30; // 清除TSTOP和TRST
    

运行后,PTF4引脚将输出100Hz,占空比30%的PWM波。在第一个周期结束时(计数器溢出),硬件会自动将控制权从TBCH0H:L切换到TBCH1H:L,于是第二个周期占空比变为50%。 关键来了 :在第二个周期期间,软件可以安全地向 当前未激活 的寄存器(此时是TBCH0H:L)写入第三个周期的占空比值(例如0x03E8对应80%),而不会干扰正在输出的波形。

缓冲模式下的致命陷阱 绝对不要向当前正在控制输出的那个通道寄存器写入新值! 这相当于破坏了缓冲机制,回到了非缓冲模式,可能引发波形错误。软件必须跟踪当前是哪个通道在控制输出(通常可以通过检查上一次是在哪个通道的中断里更新的,或者利用一个软件标志位来跟踪)。

4. 高级应用与疑难问题排查

掌握了基本模式后,我们来看一些更复杂的场景和那些容易让人栽跟头的问题。

4.1 利用输入捕获与输出比较实现可编程延迟

这是一个经典组合应用:在检测到一个外部事件(如按键按下)后,需要精确延迟一段时间再执行动作(如点亮LED)。用CPU软件延时不准且占用资源,用定时器则非常精准。

思路

  1. 将一个通道(如Ch0)配置为输入捕获,捕获事件边沿。
  2. 在输入捕获中断服务程序中,读取捕获到的时刻 capture_val
  3. 计算目标时刻: target_val = capture_val + delay_ticks 。注意处理溢出(如果相加结果超过0xFFFF,则取模)。
  4. target_val 写入另一个配置为输出比较的通道(如Ch1)的寄存器,并设置匹配时执行所需操作(如置位引脚)。
  5. 使能Ch1的输出比较中断,在中断中执行后续动作。

这样,从事件发生到动作执行,延迟时间就是 delay_ticks * timer_period ,由硬件精确保证,不受其他中断或代码执行时间影响。

4.2 低功耗模式下的TIMB行为

MCU进入WAIT模式后,TIMB默认继续运行。如果你的应用依赖TIMB中断来唤醒MCU,那么 绝对不能 在进入WAIT前设置TSTOP位。同时,在WAIT模式下,CPU不能访问TIMB寄存器。如果不需要TIMB唤醒,则在进WAIT前停止TIMB可以降低功耗。

执行STOP指令后,TIMB时钟停止,模块完全冻结。唤醒后,TIMB从停止时的状态继续运行。这意味着计数器值、寄存器配置全部保持原样。

4.3 常见问题排查清单

当你配置的TIMB功能不按预期工作时,可以按以下清单逐一排查:

  1. 完全没有输出或捕获不到

    • 引脚复用 :PTF4/TBCH0和PTF5/TBCH1是复用引脚。你配置了TIMB功能,但相应的端口方向寄存器(DDRF)配置对了吗?对于输出模式,需要将DDRFx设为1(输出);对于输入捕获模式,DDRFx应设为0(输入)。 一个常见错误是只配置了TIMB,忘了配置端口方向
    • 时钟源 :TBSC中的PS[2:0]选对了吗?TSTOP位清除了吗?用示波器或软件读取TBCNTH:L,看看计数器在递增吗?
    • 模式选择 :TBSCx中的MSxA和ELSxB:A位组合是否正确?对照前面的表格仔细检查。例如,想输出PWM,但MSxA设成了0,那就成了输入捕获模式。
  2. PWM频率或占空比不对

    • 计算错误 :重新计算周期和占空比对应的计数值。公式: 计数值 = 时间 / 定时器时钟周期 。定时器时钟周期 = 1 / (总线频率 / 预分频系数)
    • 模数寄存器 :PWM周期由TBMODH:L决定,你写入了吗?写入顺序对吗(先高后低)?
    • 比较值寄存器 :占空比由通道寄存器TBCHxH:L决定。在非缓冲模式下,你更新的是正确的寄存器吗?在缓冲模式下,你更新的是非活动通道的寄存器吗?
    • TOVx位 :生成PWM必须将TOVx置1,否则引脚只会在比较匹配时动作一次,不会周期性翻转。
  3. 中断不触发

    • 中断使能 :TBSC中的TOIE(溢出中断)或TBSCx中的CHxIE(通道中断)置1了吗?
    • MCU总中断 :MCU的全局中断开关(通常类似 asm(“cli”) asm(“sei”) 指令)打开了吗?
    • 中断标志 :中断服务程序(ISR)里清除标志位了吗?必须用“先读后写0”的顺序清除TOF或CHxF。
    • 中断向量 :你的开发环境正确设置了TIMB溢出或通道中断的中断服务程序入口地址吗?
  4. 缓冲PWM模式下载入异常

    • MS0B位 :确保TBSC0的MS0B位被置1,这是启用双通道缓冲的唯一开关。
    • 通道跟踪 :你的软件逻辑是否准确跟踪了当前哪个通道(0或1)是活动通道?是否错误地向活动通道写了数据?建议用一个 volatile 变量,在溢出中断中翻转其值来指示当前活动通道。
    • 初始化顺序 :严格按照数据手册20.3.4.3节的PWM初始化流程:先停止(TSTOP)复位(TRST)定时器,再写模值(TBMOD)和比较值(TBCHx),最后配置控制寄存器(TBSCx)并启动定时器(清TSTOP)。
  5. 测量输入捕获值不稳定

    • 信号毛刺 :被测信号是否有抖动或毛刺?可以在输入端增加简单的RC滤波。
    • 边沿选择 :是否错误配置了边沿?用示波器观察信号,确认你配置的边沿(上升、下降、任意)与实际信号一致。
    • 消抖处理 :对于机械开关等信号,必须在硬件或软件上做消抖处理,否则会多次触发捕获。

调试时,最有效的工具就是读取寄存器状态。编写一个简单的函数,通过串口打印出TBSC、TBSC0、TBSC1、TBCNTH:L、TBMODH:L、TBCH0H:L、TBCH1H:L等关键寄存器的值,与实际预期对比,大部分问题都能定位。记住,嵌入式编程,尤其是底层驱动, “寄存器状态就是一切”

您可能感兴趣的与本文相关内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值