1. 项目概述与核心价值
在嵌入式开发,尤其是电机控制、电源管理、数字信号采集这类对时序精度要求苛刻的领域,微控制器内部的定时器/计数器单元(CCU)往往是决定项目成败的关键。很多开发者初期会依赖简单的延时循环,但一旦涉及精确的频率测量、PWM波形生成或复杂的事件同步,就必须深入硬件定时器的世界。P89LPC932A1作为一款经典的8位增强型51单片机,其集成的CCU模块功能相当强大且具有代表性,理解了它的运作机制,就能举一反三,应对大多数中低端嵌入式系统的定时需求。
这个模块的核心价值在于将时间维度数字化。它不再依赖软件循环那不可靠的“大概时间”,而是通过硬件计数器对系统时钟进行精准的“刻度量”,再配合捕获(Input Capture)和比较(Output Compare)这两大功能,实现对外部事件的“抓拍”和对内部输出的“定时曝光”。输入捕获就像一台高速相机,能在外部信号跳变的瞬间,记录下当前计数器的值,从而精确计算出脉冲宽度、信号周期或事件发生的时间点。而PWM(脉宽调制)则是输出比较功能的典型应用,通过动态调整比较值,控制输出引脚高低电平的持续时间比例,实现对电机转速、LED亮度、舵机角度等模拟量的数字化控制。
本文将深入拆解P89LPC932A1的CCU模块,特别是其输入捕获与PWM功能的原理、配置细节和实战技巧。我不会仅仅翻译数据手册,而是结合我多年在电机驱动和电源项目中的实际踩坑经验,告诉你寄存器每个配置位背后的设计意图,不同模式下的波形细节差异,以及如何避开那些手册里没写但实际开发中一定会遇到的“坑”。无论你是刚接触硬件定时器的新手,还是想深入了解特定功能细节的老手,这篇文章都能提供从原理到实操的完整参考。
2. CCU模块整体架构与工作模式解析
在深入细节之前,我们必须先建立起对CCU(Capture/Compare Unit,捕获/比较单元)模块的整体认知。P89LPC932A1的CCU是一个独立的16位定时器/计数器,其核心是一个可以向上、向下或上下计数的16位计数器(TH2:TL2)。围绕这个核心计数器,搭建了输入捕获和输出比较两套子系统,并通过一系列控制寄存器进行精细化管理。
2.1 核心计数器与基础定时模式
CCU的核心是一个16位计数器,其计数时钟源可以是系统时钟(CCLK)或其分频,在启用PLL时甚至可以达到更高的频率。计数方向由TDIR2位控制,0为向上计数,1为向下计数。计数器的工作模式由TMOD2[1:0]两位决定:
- 00: 定时器停止。这是复位后的默认状态。
- 01: 基本定时器模式。这是最基础的模式。计数器按照设定的方向(TDIR2)持续计数。当发生溢出(向上计数到0xFFFF后回到0x0000,或向下计数到0x0000后回到0xFFFF)时,会置位溢出中断标志TOIF2。同时,计数器会从定时器溢出重载寄存器(TOR2H:TOR2L)中自动重载初始值,实现可编程的定时周期。
- 10: 非对称PWM模式。在此模式下,计数器强制为向下计数模式,与TDIR2位的设置无关。这是生成标准PWM波形最常用的模式。
- 11: 对称PWM模式。在此模式下,计数器在0和TOR2值之间往复计数(先向上,到达TOR2后向下,回到0后再向上)。这种模式生成的PWM波形关于中心对称,常用于电机控制中的H桥驱动,可以减少谐波。
注意:模式切换的时机。务必在计数器停止(TMOD2=00)或确保当前PWM周期结束后,再更改TMOD2以切换模式。在计数器运行时突然改变模式,可能导致输出引脚产生毛刺或不可预测的行为。一个稳妥的做法是,先关闭对应的输出比较引脚控制,再修改模式,最后重新启用输出。
2.2 影子寄存器与同步更新机制
这是CCU模块一个非常关键且易被忽略的设计,理解了它能避免很多诡异的波形问题。无论是定时器重载值(TOR2)还是比较值(OCRx),在PWM模式下,对它们的写操作并不会立即生效。
当你向OCRAH(高字节)或OCRAL(低字节)写入一个新的比较值时,这个值首先被存入一个“影子寄存器”。真正的、正在与计数器进行比较的“工作寄存器”内容保持不变。此时,你需要通过向TCOU2位写1来发起一个“更新请求”。这个更新动作,会等到下一个计数器溢出事件(在非对称PWM模式下是计数器下溢到0x0000时)发生时,才将影子寄存器中的值一次性更新到所有的工作寄存器中。
这么设计的好处是什么?假设我们直接修改工作寄存器,而修改的时刻恰好发生在计数器值接近比较值的时候。例如,当前比较值是1000,计数器正从1001向下计数到1000。如果在计数器值为1000时我们将其改为500,那么本次周期内比较匹配事件就不会发生,导致输出引脚该翻转时没有翻转,产生一个“短脉冲”或“长脉冲”,即所谓的“奇偶脉冲”(glitch)。通过影子寄存器和在溢出点同步更新的机制,就确保了整个PWM周期内比较值是稳定的,从而输出完整的、无毛刺的PWM波。
实操心得:更新时机的把握。在需要动态调整PWM占空比的应用中(如呼吸灯、电机调速),最佳实践是在中断服务程序中更新比较值。例如,使能定时器溢出中断(TOIE2),在溢出中断服务程序里,计算新的比较值并写入OCR影子寄存器,然后置位TCOU2。由于中断发生在溢出时刻,此时发起更新请求,能确保在下一个周期开始时新值就生效,实现最平滑的占空比变化。如果是在主循环中异步更新,则需要考虑计算和写入的时机,避免在PWM周期中途操作。
2.3 中断系统与优先级处理
CCU模块的中断源多达7个:1个定时器溢出中断(TOIF2)、2个输入捕获中断(TICF2A, TICF2B)、4个输出比较中断(TOCF2A-D)。它们共享同一个中断向量。这意味着,当进入CCU中断服务程序时,你首先需要判断是哪个事件触发了中断。
硬件提供了一个优先级编码器来解决这个问题。当多个中断标志同时置位时,编码器会按照固定优先级(溢出最高,输入捕获A次之,输出比较D最低)输出一个3位编码值到TISE2寄存器的低3位(ENCINT[2:0])。标准的中断服务流程如下:
- 读取
TISE2寄存器,获取最高优先级的待处理中断源编码。 - 根据编码值,跳转到相应的处理子程序。
- 在处理完该中断事件后,必须手动向
TIFR2寄存器中对应的中断标志位写0以清除它。 - 再次读取
TISE2。如果编码不为0,说明还有其它挂起的中断,返回步骤2继续处理;如果为0,则表示所有CCU中断已处理完毕,可以退出中断服务程序。
这种“查询-处理”机制要求中断服务程序编写必须高效,避免因处理时间过长而丢失其他高速事件。对于输入捕获这类对实时性要求极高的事件,通常只在中断中快速记录捕获值,并设置一个软件标志,具体的计算和分析放在主循环中进行。
3. 输入捕获功能深度剖析与实战配置
输入捕获功能是测量外部信号时间参数的利器,比如测量脉冲宽度、频率、占空比,或者为外部事件打上精确的时间戳。P89LPC932A1提供了两个独立的输入捕获通道(A和B)。
3.1 输入捕获的工作原理
其核心过程可以概括为“触发-锁存-中断”:
- 触发:配置好对应的I/O引脚(例如P1.2或P1.3)为输入模式,并设置捕获边沿选择位
ICESx(在CCCRx寄存器中)。ICESx=0表示在下降沿触发捕获,ICESx=1表示在上升沿触发。 - 锁存:当指定的引脚上发生了符合要求的边沿事件时,硬件会立即将当前16位计数器(TH2:TL2)的值,锁存到对应的16位输入捕获寄存器(
ICRxH:ICRxL)中。这个过程是硬件自动完成的,与CPU是否在执行指令无关,因此精度极高。 - 中断:同时,硬件会置位对应的输入捕获中断标志
TICF2x。如果全局中断(EA)、CCU模块中断(ECCU)以及该通道的中断使能位(TICIE2x)都已打开,CPU就会跳转到中断服务程序。
3.2 高级功能:噪声滤波与事件延迟计数器
在实际的电气环境中,信号线很容易受到噪声干扰,产生毛刺。一个轻微的抖动可能导致多次错误的边沿检测。CCU模块提供了两级硬件防护:
数字噪声滤波器(ICNFx):当
ICNFx位置1时,捕获逻辑变得“迟钝”。它不会在检测到一次边沿变化就立即动作,而是会以2个CCLK周期为间隔,对输入引脚进行连续4次采样。只有当这4次采样的结果都一致(全是0或全是1)时,才认为这是一个有效的边沿,进而触发捕获。这能有效滤除宽度小于8个CCLK周期的窄脉冲噪声。代价是引入了固定的检测延迟,在计算绝对时间时需要予以考虑。事件延迟计数器(ICECx[2:0]):这是一个非常实用的功能,尤其适用于测量频率或进行分频。你可以通过
ICECx[2:0]这3个位(同样在CCCRx寄存器中)设置一个预分频值,范围是0到15(注意:编码110对应7次,111对应15次)。捕获逻辑需要累计检测到指定次数的有效边沿后,才会真正执行一次捕获动作并产生中断。- 应用场景1:频率测量。要测量一个1kHz的方波,如果每个边沿都捕获,则中断频率为2kHz,对CPU负担较大。可以设置
ICECx=2(即每4个边沿捕获一次),这样中断频率降为500Hz,在中断中读取的捕获值之差代表了4个信号周期的时间,再除以4即可得到周期,精度不变但CPU开销大大降低。 - 应用场景2:忽略初始抖动。某些传感器上电初期可能输出几个不稳定的脉冲,设置一个小的延迟计数(如2或3)可以跳过这些无效信号。
- 应用场景1:频率测量。要测量一个1kHz的方波,如果每个边沿都捕获,则中断频率为2kHz,对CPU负担较大。可以设置
3.3 读取捕获值的正确顺序与陷阱
这是一个经典的坑点。数据手册明确说明:必须首先读取低字节ICRxL,然后读取高字节ICRxH。
为什么?因为捕获寄存器是16位的,而51内核是8位总线,需要分两次读取。为了防止在两次读取之间恰好发生新的捕获事件导致数据错位(高字节来自新值,低字节来自旧值),硬件设计了一个影子寄存器机制。当你读取ICRxL时,硬件不仅返回低字节,还会自动将当前捕获寄存器的高字节ICRxH的值锁存到一个专用的影子寄存器中。随后,当你读取ICRxH时,CPU实际读取的是那个影子寄存器里的值,而非ICRxH实时变化的值。这样就保证了你读出的高、低字节是属于同一次捕获事件的。
绝对要避免的错误操作:
ICRxH->ICRxL(错误顺序,数据无意义)ICRxL->ICRxL(连续读两次低字节。第二次读ICRxH时,拿到的是第一次读ICRxL时锁存的旧高字节,如果中间发生了新的捕获,数据就错了)
在C语言中,一个安全的读取函数通常这样写:
unsigned int ReadCaptureA(void) { unsigned int capture_value; unsigned char low_byte, high_byte; low_byte = ICRAL; // 先读低字节,同时锁存高字节到影子寄存器 high_byte = ICRAH; // 再读高字节(来自影子寄存器) capture_value = (high_byte << 8) | low_byte; return capture_value; }3.4 输入捕获实战配置步骤
假设我们要用通道A测量一个外部脉冲的高电平宽度,并启用噪声滤波。
- 初始化I/O:将P1.2(假设为捕获A引脚)设置为输入模式(
P1M1.2=1, P1M2.2=0或根据具体I/O配置寄存器设置)。 - 配置捕获参数:
- 访问
CCCRA寄存器。 - 设置
ICESA=1,选择上升沿捕获。 - 设置
ICNFA=1,使能噪声滤波器。 - 设置
ICECA[2:0]=0,每个边沿都捕获。
- 访问
- 配置定时器:
- 设置
TMOD2[1:0]=01,进入基本定时器模式(向上计数)。 - 根据所需的时间分辨率和测量范围,设置
TOR2作为定时器重载值(即计数上限)。例如,若CCLK=12MHz,希望最大测量65.535ms(即16位计数器满量程),则无需重载(或设置TOR2=0xFFFF)。若想提高分辨率,可以设置更小的TOR2,让定时器溢出更频繁,在中断中处理溢出计数。 - 启动定时器(如果之前已停止)。
- 设置
- 配置中断:
- 使能CCU模块中断:
IEN1 |= 0x10;(ECCU=1)。 - 使能通道A输入捕获中断:
TICR2 |= 0x01;(TICIE2A=1)。 - 使能全局中断:
EA = 1;。
- 使能CCU模块中断:
- 中断服务程序:
- 检查
TISE2,确认是TICF2A中断。 - 调用
ReadCaptureA()函数获取捕获值。 - 根据边沿顺序(先上升沿后下降沿)计算时间差。通常需要结合定时器溢出次数来得到完整的时间长度。
- 清除
TICF2A标志位:TIFR2 &= ~0x01;。
- 检查
4. PWM生成原理与模式详解
PWM是“脉宽调制”的缩写,其本质是通过调节一个固定周期方波信号中高电平所占的时间比例(占空比),来等效地输出不同的平均电压或功率。CCU模块通过输出比较功能来硬件生成PWM,解放CPU。
4.1 非对称PWM模式(模式10)
这是最直观的PWM模式。在此模式下,计数器强制向下计数,从TOR2值开始,递减到0,然后立即重载TOR2值并开始下一个周期。
工作流程:
- 计数器从
TOR2开始递减。 - 在计数过程中,硬件不断将计数器的当前值与输出比较寄存器
OCRx的值进行比较。 - 当两者相等时,发生“比较匹配”事件。根据
OCMx[1:0]位的配置,输出引脚会做出相应动作。 - 计数器继续递减至0,发生“下溢”事件。此时,根据
OCMx[1:0]的配置,输出引脚可能会再次动作,从而完成一个完整的PWM周期。
输出模式配置(OCMx[1:0]):
- 01: 非反相PWM。这是最常用的模式。
比较匹配时置位引脚(输出高电平),定时器下溢时清零引脚(输出低电平)。因此,OCRx的值直接决定了高电平的持续时间。OCRx值越大(越接近TOR2),高电平时间越长,占空比越大。当OCRx >= TOR2时,输出恒高;当OCRx = 0时,输出恒低(或一个极窄的脉冲,取决于具体实现)。 - 11: 反相PWM。逻辑与非反相相反。
比较匹配时清零引脚,定时器下溢时置位引脚。此时,OCRx的值决定了低电平的持续时间。
PWM频率与占空比计算:
- 频率:
Fpwm = CCLK / ( (TOR2 + 1) * Prescaler)其中,Prescaler是定时器时钟预分频系数。TOR2是16位重载值。频率由TOR2决定。 - 占空比:
Duty Cycle = (OCRx + 1) / (TOR2 + 1)(对于非反相PWM) 占空比由OCRx决定。OCRx的取值范围是0到TOR2。通常通过改变OCRx来动态调节占空比。
4.2 对称PWM模式(模式11)
在此模式下,计数器在0和TOR2之间像锯齿波一样往复运动:从0向上计数到TOR2,然后立即反向,从TOR2向下计数回0,如此循环。
工作流程与输出: 这种模式下的输出行为比非对称模式稍复杂,因为每个PWM周期包含上升和下降两个阶段。
- 对于非反相PWM(OCMx[1:0]=01):
- 在向上计数阶段,当计数器值与
OCRx匹配时,清零输出引脚。 - 在向下计数阶段,当计数器值再次与
OCRx匹配时,置位输出引脚。 - 因此,输出波形是中心对称的。引脚在周期开始和结束时为高电平,在中间某个点(由
OCRx决定)变为低电平,并在对称点恢复高电平。这生成了一个“高-低-高”的脉冲,脉冲位于周期中央。
- 在向上计数阶段,当计数器值与
- 对于反相PWM(OCMx[1:0]=11):逻辑相反,输出“低-高-低”的脉冲。
对称PWM的优势:
- 谐波特性好:由于波形对称,其偶次谐波分量被消除,电磁干扰(EMI)更小,特别适合电机驱动和音频应用。
- 适用于H桥控制:在驱动直流电机或逆变器时,对称PWM可以方便地生成互补的驱动信号,并自然地插入死区时间。
频率计算:
Fpwm = CCLK / ( 2 * (TOR2 + 1) * Prescaler )注意分母中的因子2,因为一个完整的周期包含了上计数和下计数两个阶段。
4.3 交替输出模式(Alternate Output Mode)
这是专为驱动全桥或半桥电路设计的高级功能,通过设置TCR20寄存器中的ALTAB或ALTCD位来启用。
工作原理: 以通道A和B组成一对(ALTAB=1)为例。在普通的PWM模式下,通道A和B独立输出。在交替输出模式下,硬件会将这对通道的输出在相邻的PWM周期交替使能。
- 奇数周期:通道A的输出有效,其波形由
OCRA寄存器控制;通道B的输出被强制为无效状态(通常为低电平或高阻,具体由硬件决定)。 - 偶数周期:通道B的输出有效,其波形由
OCRB寄存器控制;通道A的输出被强制为无效状态。
应用价值: 在驱动一个电机绕组时,如果直接将两个对称的PWM波加到H桥的两个对角开关管上,每个开关管在每个周期都需要开关一次。而在交替模式下,每个开关管只在“自己的”周期内开关,在“别人的”周期内完全关闭。这带来了两大好处:
- 降低开关损耗:每个开关管的实际开关频率降低了一半,从而减少了开关过程中的能量损耗,降低了发热。
- 简化死区插入:由于两个通道不会在同一周期内同时有效,从硬件上避免了桥臂直通的风险,对死区时间的要求可以放宽,软件控制更简单。
4.4 停机(HALT)功能
这是一个安全特性。当HLTEN位置1后,如果输入捕获通道A(注意,是固定的通道A)发生了一次有效的捕获事件,所有PWM输出引脚会立即被强制设置为一个预定状态(由FCOA、FCOB等位定义),而定时器本身继续运行。HLTRN位会被置1,指示发生了停机。
应用场景:
- 过流保护:将电流采样信号连接到捕获A引脚。当电流超过阈值时,产生一个边沿信号,CCU会立即关闭所有PWM输出,保护功率器件。
- 紧急停止:将一个急停按钮连接到捕获A引脚,实现硬件的快速关断。
恢复:要重新激活PWM输出,必须由软件清除HLTRN位。你也可以通过软件写1到HLTRN位来主动触发一次停机。
5. PLL功能与高频PWM生成
对于许多应用(如开关电源、数字音频),需要更高频率的PWM以获得更好的动态响应或超出人耳听觉范围。P89LPC932A1的CCU内置了一个锁相环(PLL),可以将输入时钟倍频,为定时器提供高达32MHz的CCUCLK。
5.1 PLL配置流程与注意事项
PLL的输入频率要求严格控制在0.5MHz到1MHz之间。PLL会将其倍频32倍作为CCUCLK。因此,我们需要通过预分频器PLLDV来将系统时钟PCLK分频到这个范围。
配置步骤(必须按顺序):
- 停止定时器:确保
TMOD2[1:0]=00,PWM模块未运行。 - 计算并设置分频系数N:
N = PCLK / Fdesired - 1,其中Fdesired是期望的PLL输入频率(0.5-1 MHz)。N的取值范围是0-15,写入TCR21寄存器的PLLDV[3:0]位。例如,PCLK=12MHz,想要Fdesired=0.75MHz,则N = 12/0.75 -1 = 16-1=15。 - 启动PLL:设置
TCR20寄存器中的PLLEN=1。 - 等待PLL锁定:这是一个关键步骤!不能立即读取
PLLEN位为1。必须循环查询PLLEN位,直到硬件将其置1,这表示PLL已经锁定到目标频率,输出稳定。代码上通常是一个while(!(TCR20 & 0x80));的循环。 - 启动定时器:此时再配置
TMOD2进入PWM模式,启动定时器。
重要警告:异步操作风险。当定时器使用PLL产生的
CCUCLK运行时,它与以PCLK运行的单片机内核是异步的。这意味着:
- 避免在定时器运行时频繁读写其寄存器(如TH2/TL2, TOR2, OCRx)。因为你的读写操作发生在
PCLK域,而定时器运行在CCUCLK域,两者时钟不同步,可能导致读到错误的数据或写入时机不对。所有对PWM参数的更新,都应通过前面提到的影子寄存器机制(写OCR,然后置位TCOU2)来完成,硬件会处理跨时钟域同步。- 中断响应延迟:从CCU模块产生中断事件,到CPU实际检测并响应这个中断,会有几个
CCLK周期的延迟。在编写对时序极其敏感的中断服务程序时,需要考虑到这个异步延迟。
5.2 高分辨率PWM计算实例
假设我们需要一个100kHz的对称PWM,且希望分辨率尽可能高。系统PCLK为12MHz。
- 启用PLL:为了获得高分辨率,我们使用PLL。设置
PLLDV=15,使PLL输入为12/(15+1)=0.75MHz。PLL输出CCUCLK = 0.75 * 32 = 24MHz。 - 计算TOR2:对于对称PWM,
Fpwm = CCLK / (2 * (TOR2+1))。假设预分频为1。TOR2 + 1 = CCLK / (2 * Fpwm) = 24,000,000 / (2 * 100,000) = 120TOR2 = 119(0x77)
- 计算分辨率:计数范围是0-119,共120个计数值。因此PWM的分辨率是
log2(120) ≈ 6.9 bits。也就是说,占空比可以调节120个不同的等级。 - 占空比控制:
OCRx的取值范围是0-119。占空比 =(OCRx+1) / 120。例如,要得到50%占空比,OCRx = 59。
如果不使用PLL,直接使用12MHz的PCLK,要达到100kHz,TOR2=59,分辨率只有约5.9位。可见PLL显著提升了PWM的分辨率。
6. 实战:配置一个完整的电机驱动PWM信号
假设我们要用通道A和B生成一对互补的、带死区的PWM信号来驱动一个H桥,电机PWM频率为20kHz,采用对称模式,并启用交替输出以降低损耗。
步骤1:确定时钟与模式
- 系统
PCLK = 12MHz。为了获得更好的分辨率,启用PLL。设置PLLDV=11,则PLL输入=12/(11+1)=1MHz,输出CCUCLK=32MHz。 - 目标频率
Fpwm=20kHz,对称模式。 - 计算
TOR2:TOR2 = CCLK/(2*Fpwm) -1 = 32,000,000/(2*20,000) -1 = 800 -1 = 799(0x031F)。 - 设置
TMOD2[1:0]=11,进入对称PWM模式。
步骤2:配置PWM输出行为
- 我们希望通道A和B输出互补信号。在对称模式下,通常将一个通道设为非反相,另一个设为反相。
- 设置
OCMA[1:0]=01(通道A,非反相PWM)。 - 设置
OCMB[1:0]=11(通道B,反相PWM)。 - 这样,当
OCRA=OCRB时,两个通道的输出在大部分时间是相反的。
步骤3:插入死区时间死区时间是防止H桥上下管直通的关键。硬件本身不直接产生死区,需要我们用软件计算。
- 假设我们需要3us的死区时间。
CCLK周期Tclk = 1/32MHz = 31.25ns。- 死区时间对应的计数值
DeadTime_Counts = 3us / 31.25ns = 96。 - 因此,我们不能将
OCRA和OCRB设为相等。假设我们希望通道A为主信号,通道B为互补信号。- 设置
OCRA为期望的占空比对应值,例如50%占空比时,OCRA = TOR2/2 = 399。 - 对于通道B(反相),我们希望它在通道A关闭后延迟一段时间(死区)再开启,并在通道A开启前提前一段时间关闭。
- 在对称PWM中,输出翻转发生在比较匹配点。对于非反相通道A,它在向上计数匹配
OCRA时变低,向下计数匹配OCRA时变高。 - 为了让通道B在A变低后延迟开启,我们需要让通道B(反相)的开启点(即向下计数匹配点)比A的关闭点(向上计数匹配点)晚。所以,
OCRB应该小于OCRA。 - 具体计算:
OCRB = OCRA - DeadTime_Counts = 399 - 96 = 303。 - 同样,通道B的关闭点(向上计数匹配点)会比A的开启点(向下计数匹配点)早,实现了另一侧的死区。
- 设置
步骤4:启用交替输出模式
- 设置
TCR20寄存器中的ALTAB=1,启用通道A和B的交替输出。 - 在此模式下,硬件自动管理A和B的交替,我们只需要设置好
OCRA和OCRB即可。
步骤5:配置引脚与启动
- 将PWM输出引脚(如P2.6和P1.6)配置为推挽输出模式。
- 按照前面PLL启动流程,先配置PLL并等待锁定。
- 将计算好的
TOR2、OCRA、OCRB值写入对应的影子寄存器。 - 置位
TCOU2,请求更新。 - 最后,将
TMOD2[1:0]设为11,启动定时器。
通过以上步骤,我们就得到了一个频率20kHz、带3us死区、A/B通道互补且交替输出的高质量电机驱动PWM信号。整个过程由硬件自动完成,CPU仅在需要改变转速(占空比)时才介入修改OCRx值,极大地减轻了软件负担并保证了时序精度。