资讯动态

定时器生成PWM信号:从占空比到寄存器配置详解

发布时间:2026/10/22 6:27:48 来源:尧图企业网站定制
1. 从点亮一颗灯到控制一个世界PWM到底解决了什么问题先放下那句老套的“PWM就是脉宽调制”我们直接看一个实际场景。你想让一颗LED实现呼吸灯效果从最亮到最暗平滑过渡而不是简单地开或关。用普通GPIO输出高低电平只能做到两态切换再怎么延时也做不出那种“渐亮渐暗”的丝滑感。但如果你给GPIO接上一种特殊的开关方式让它在极短的时间内反复开、关并且每次开的时间占整个周期的比例不断变化人眼感知到的平均亮度就会随这个比例线性变化。这个“开的时间占周期的时间比例”就叫占空比这种开关方式就是PWM。这里说的“极短的时间”在大多数单片机场景下是微秒到毫秒级别。比如一个20kHz的PWM周期是50微秒每次开关切换都在这个尺度内完成LED的物理惯性加上人眼的视觉暂留就把高频开关“平均”成了连续的亮度。所以你真正要做的不是去写延时函数控制电平而是让硬件自己在那哼哧哼哧地翻转电平CPU在旁边歇着。这就是定时器的核心价值把时间基准、计数、比较、自动翻转这些脏活累活全包了你只需要配置几个寄存器。PWM的应用远不止呼吸灯。电机调速、舵机角度控制、蜂鸣器音调、DC-DC电源的反馈调节、加热器功率控制、音频信号生成……凡是需要模拟量输出但手头只有数字IO的场合PWM几乎是标配方案。我见过很多新手一上来就想着用DAC其实在多数工况下PWM加RC滤波就能凑合出不错的模拟信号成本还低。所以今天这篇文章就围绕“用定时器生成PWM信号”这个主题把从原理到寄存器配置再到实际踩坑的经验一次性讲透。这篇文章适合谁看如果你是刚接触单片机想搞明白定时器除了计时还能干嘛或者你已经会点灯但看到数据手册里那一堆TIM、CCR、ARR、PSC就发怵又或者你正在调电机、舵机被PWM频率和死区折腾得头疼——那这篇内容对你应该挺有价值。我会尽量用实际例子和真实参数说话不搞纸上谈兵。2. 定时器生成PWM的本质计数、比较、翻转2.1 定时器到底在“定时”什么很多人第一次学定时器以为定时器就是一个会闹钟的计数器到点触发中断。这么说没错但只是它功能的一半。定时器更强大的地方在于它不仅能“到点提醒”还能“到点自动干活”不需要CPU介入。生成PWM就是这种“自动干活”的典型场景。以最常用的16位定时器为例它内部有一个不断递增的计数器CNT一个自动重装载寄存器ARR或者说PER不同厂商叫法不同还有若干个比较寄存器CCR。时钟源经过预分频器PSC分频后给计数器提供计数脉冲。计数器从0开始每个脉冲加1计到和ARR相等时会归零重新开始向上计数模式或者向下计数、向上向下计数。这个从0到ARR再回到0的完整过程就构成了一个时间周期。那PWM怎么来的关键在于比较寄存器CCR。计数器CNT在递增过程中会实时和CCR进行比较。如果CNT小于CCR输出引脚输出一种电平如果CNT大于等于CCR输出另一种电平。也就是说CCR的值决定了在一个周期内输出高电平持续的时间。你把CCR改大高电平时间变长占空比变大改小占空比变小。而后面的计数器翻转、归零、重新计数全部由硬件自动完成CPU完全不管。2.2 占空比和频率的计算逻辑PWM有两个核心参数频率和占空比。频率由时钟源、预分频器和ARR共同决定占空比由CCR和ARR共同决定。拿一个经典公式来说PWM频率 时钟源频率 / (PSC 1) / (ARR 1)占空比 CCR / (ARR 1) 向上计数且输出极性为高电平有效时这里为什么要加1因为很多定时器的计数是从0开始的。如果PSC为0ARR为99那么计数器实际上计了0到99一共100个脉冲除以100才是正确频率。很多人第一次配置时忘了这个1导致频率算出来的实际值差了一倍这种细节后面实操部分还会再提。CCR和ARR都是整数所以占空比的分辨率受ARR的限制。ARR越大你可以调节的占空比步进就越小。比如ARR为99那占空比只能以1%步进变化ARR为999就能做到0.1%步进。但ARR大了在相同频率下计数器的时钟就得更高这对定时器时钟源的上限有要求。所以实际设计时要权衡需要什么样的频率分辨率就选多大的ARR。2.3 边缘对齐还是中心对齐这是个问题大多数入门教程只教你配置PWM模式1或模式2也就是所谓的边缘对齐模式。在这种模式下计数器从0递增到ARR然后归零输出电平在CNT到达CCR时翻转一次。这种模式实现简单占空比更新及时适合电机调速、LED调光这类不要求对称波形的场景。但如果你在做开关电源、逆变器这类需要严格对称PWM的场合边缘对齐模式就不够看了。这时候得用中心对齐模式计数器先从0递增到ARR再从ARR递减到0形成一个三角波。比较输出既可以在递增时触发也可以在递减时触发生成的PWM波形相对于周期中心是对称的。中心对齐模式能显著减少偶次谐波对于EMI和电源纹波控制很有帮助。但代价是同样频率下计数器的计数次数是边缘对齐的两倍因此对时钟频率的要求更高而且更新占空比的时机要小心如果处理不当可能在半周期处出现毛刺。对于初学者我建议先从边缘对齐模式入手把基础弄扎实了再碰中心对齐。3. 配置定时器PWM的完整实操以某款主流MCU为例3.1 选型先看定时器资源再看引脚功能先说明一下不同厂商的定时器外设命名和寄存器细节有差异但核心逻辑完全一致。我以市面上最普及的Cortex-M内核MCU为例它的定时器模块通常分为基本定时器、通用定时器和高级定时器。基本定时器只能做定时不能输出PWM通用定时器才有PWM输出通道高级定时器在通用定时器基础上多了互补输出、死区插入、刹车输入等专门用于电机控制、电源转换等场景。看你手头的应用选型如果只是调个LED亮度和蜂鸣器随便一个通用定时器通道就够了如果要做无刷电机驱动那就必须用高级定时器因为你需要互补PWM和死区防止上下桥臂直通。这里提醒一句别把任意GPIO都当成PWM输出脚用定时器的输出通道是固定的要看数据手册里的复用功能映射。很多新手把PWM配置在了普通GPIO上折腾半天波形出不来其实只是没打开复用功能。3.2 寄存器级别的配置步骤手把手走一遍下面我以通用定时器某个通道输出PWM为例完整走一遍寄存器配置流程。假设系统时钟为72MHz目标是输出50Hz的舵机控制信号占空比可在2.5%到12.5%之间调节对应0.5ms到2.5ms的脉宽。第一步配置时钟。使能定时器时钟和对应GPIO端口时钟。然后再把GPIO引脚复用为定时器输出功能。这里两个时钟都要打开漏一个都不行——别问我为什么知道我当年漏过GPIO时钟PWM死活不出来查了半天才发现引脚根本没通电。第二步配置GPIO为复用推挽输出速度设为高速。对于PWM这类高频翻转信号GPIO的翻转速率必须足够快否则波形边沿会变缓影响精度。一般设置成50MHz或更高比较稳妥。第三步计算并写入PSC和ARR。目标频率50Hz那么PSC和ARR需要满足72MHz / (PSC1) / (ARR1) 50Hz为了让舵机控制有足够的脉宽分辨率我们希望ARR选得大一些。取ARR1为20000即ARR19999那么PSC1 72MHz / 50 / 20000 72所以PSC71。这样在50Hz频率下计数器计数周期是20000每个计数对应的时间是1秒 / 50 / 20000 0.001秒 1微秒。CCR的值就直接等于脉宽微秒数方便到离谱。舵机中位1.5ms对应CCR1500范围0.5ms到2.5ms对应CCR500到2500。第四步配置定时器的PWM模式。这里选择向上计数PWM模式1输出极性为高电平有效。然后设置CCR的初始值比如先设1500。第五步使能定时器的PWM输出。这步注意不是使能定时器就完了有些定时器的输出还需要单独使能主输出尤其是高级定时器有个MOE主输出使能位忘了置1前面配置全白搭。通用定时器没有这一步但高级定时器必须做。第六步使能定时器。计数器开始跑PWM就出来了。3.3 用代码实现动态改变占空比静态输出一个固定占空比的PWM意义不大实际项目里肯定要动态调节。比如通过ADC读取电位器电压然后映射到舵机角度。这里的核心操作就是更新CCR寄存器。有个细节需要注意在边缘对齐模式下如果ARR不变直接往CCR里写新值新的占空比会在下一个计数周期开始生效。这是硬件行为的正常表现不等于写入失败。但在中心对齐模式下如果写入时机不对可能导致波形不对称所以某些高端MCU提供了预装载功能就是先把新值写入影子寄存器等到更新事件发生时才真正复制到工作寄存器。如果你不想在控制过程中产生毛刺建议把预装载使能打开。代码层面动态更新占空比通常有两种写法。一种是直接写CCR寄存器比如TIMx-CCR1 new_value;简单粗暴适合绝大多数场景。另一种是通过定时器的DMA功能把一段预设的占空比变化表通过DMA自动搬移到CCR寄存器实现无CPU干预的平滑渐变。比如做呼吸灯你可以用DMA把正弦表按一定速率写入CCRCPU全程休眠效果还特别顺滑。这个方法我在实际项目里用过省心又高效。下面给个简单的代码示例展示初始化函数和更新占空比函数。void pwm_init(void) { // 使能时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); // GPIO复用为TIM3_CH1对应PA6 GPIO_InitTypeDef gpio {0}; gpio.GPIO_Pin GPIO_Pin_6; gpio.GPIO_Mode GPIO_Mode_AF; gpio.GPIO_Speed GPIO_Speed_50MHz; gpio.GPIO_OType GPIO_OType_PP; GPIO_Init(GPIOA, gpio); GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_TIM3); // 定时器时基配置 TIM_TimeBaseInitTypeDef tb {0}; tb.TIM_Prescaler 71; // 72MHz / 72 1MHz tb.TIM_CounterMode TIM_CounterMode_Up; tb.TIM_Period 19999; // 1MHz / 20000 50Hz tb.TIM_ClockDivision TIM_CKD_DIV1; TIM_TimeBaseInit(TIM3, tb); // PWM通道配置 TIM_OCInitTypeDef oc {0}; oc.TIM_OCMode TIM_OCMode_PWM1; oc.TIM_OutputState TIM_OutputState_Enable; oc.TIM_Pulse 1500; // 初始1.5ms脉宽 oc.TIM_OCPolarity TIM_OCPolarity_High; TIM_OC1Init(TIM3, oc); TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); TIM_Cmd(TIM3, ENABLE); } void pwm_set_pulse_us(uint16_t pulse_us) { if (pulse_us 500) pulse_us 500; if (pulse_us 2500) pulse_us 2500; TIM_SetCompare1(TIM3, pulse_us); }这段代码里的TIM_SetCompare1最终也就是写入CCR1寄存器库函数帮你做了一层封装。实际工程中用寄存器直写和用库函数都可以但从可维护性角度用库函数封装好一点方便以后换芯片。3.4 用逻辑分析仪看波形验证参数是否和预期一致配置完之后别急着高兴拿逻辑分析仪或者示波器看一下实际波形。这一步在大多数入门教程里都被忽略了但恰恰是最重要的一步——寄存器配置对了没有波形会直接告诉你答案。把探针接到PWM输出引脚上查看周期和脉宽。以我上面这个例子周期应该是20ms脉宽初始应该是1.5ms。如果测出来周期不对先检查预分频和重装载值的算数有没有出错别忘1。如果测出来完全没有波形先检查GPIO复用配置再检查定时器主输出使能。用逻辑分析仪还有一个好处可以观察占空比动态更新时波形是否有毛刺。把占空比设置成一直在变观察边沿位置是否抖动。如果抖动明显多半是CCR写入与计数器运行不同步导致的这时打开预装载功能大多能解决。4. 频率、分辨率、谐波PWM参数设计中的权衡艺术4.1 如何选择PWM频率从负载特性反推很多刚接触PWM的人会问频率到底设多少合适这个没有标准答案完全由负载决定。LED调光频率必须高于人眼闪烁感知阈值一般在200Hz以上就看不到闪了但更推荐1kHz以上一则更稳二则也能避免和摄像头的采样频率产生差拍不然拍视频时会出现滚动条纹那叫一个痛苦。电机驱动则不同频率低了电机会发出明显的啸叫而且电流纹波大力矩波动明显频率高了MOS管的开关损耗会显著上升驱动芯片发热。一般直流有刷电机选10kHz到20kHz比较合适既超出人耳听觉范围又不会让开关损耗过于夸张。舵机控制则比较特殊它看的是脉宽而不是占空比频率所以接收标准PWM信号一般就是50Hz脉宽从0.5ms到2.5ms。你把频率升高到200Hz舵机大概率不转因为它内部电路宽度判断的是高电平持续时间和周期之间的比例关系。对于开关电源这类应用PWM频率通常由电感尺寸、开关管耐压、控制环路带宽共同决定常见在100kHz到1MHz之间。这时边缘对齐模式已经不太够用中心对齐、死区控制、逐周期限流这些高级功能就得上场了。4.2 占空比分辨率想精细还是想快速占空比分辨率直接取决于ARR。ARR越大可表示的占空比级数越多。比如ARR为255占空比调节步进是1/256大约0.39%。对于LED调光这个级别大概够用但呼吸灯如果想特别平滑0.39%的步进在大约10%以内的低亮度区间仍然能看出阶跃感。ARR为1023时步进约0.098%肉眼基本就分辨不出来了。但ARR变大代价有两个一是计数器要数更多次才完成一个周期如果时钟频率固定你最大能输出的PWM频率就降低了二是更新占空比时如果使用DMA或中断每次更新的数据量变大但实时性要求不一定跟得上。所以在设计阶段先明确你能忍受多大的占空比步进再反推最小ARR然后计算在目标频率下需要的时钟频率最后对照芯片定时器的时钟上限看是否可行。如果时钟不够就得在分辨率和频率之间做取舍。4.3 死区时间高级定时器才能给你的安全感无刷电机、H桥、半桥驱动这类拓扑最怕的事情就是上下管同时导通那基本上就是短路轻则炸MOS管重则烧板子。防止同时导通的关键在于当一个管子关断后必须等一段安全时间再打开另一个管子这段等待时间就是死区时间。高级定时器里有个专门机制叫死区发生器。它能自动在一对互补PWM之间插入可配置的时间间隔。比如你配置死区为1微秒那么上管关断后下管要等1微秒才导通反过来也一样。这样一来不管你怎么修改占空比硬件都会自动保证两个开关管之间有一段互锁时间软件层面完全不用操心。死区时间设多少取决于功率管的关断延迟和电荷抽取时间。太短不安全太长会引入额外的功率损耗并降低输出波形质量。在实际调试中可以通过示波器观察互补PWM的交叉点确保在开关过程中没有重叠同时尽量把死区设到满足安全的最小值。我用过一个模块死区设置小了上电瞬间电流就飙到保护值死区调大一倍就稳定了。这个参数确实得靠现场试不同批次管子特性还有差异。5. 让PWM更聪明DMA、中断与多通道协同5.1 用DMA搬运数据CPU零负担如果只是每秒更新几次占空比直接写寄存器就够了。但在某些实时性要求高的场合比如音频播放、三相电机控制占空比可能需要以几十kHz的频率刷新这时候如果用CPU在中断里频繁写CCR你会浪费大量时间而且中断响应延迟还会导致波形抖动。解决方案是用DMA。你事先在内存里放一张占空比变化表然后配置DMA把这张表按指定速率自动搬到CCR寄存器。DMA搬运一次数据CCR更新一次完全不需要CPU参与。配合定时器的更新事件触发DMA传输可以实现非常精确时序的PWM序列。我实际做过一个简易音频播放器用16kHz的采样率生成语音。就是把语音采样数据做映射通过DMA输出到定时器的CCR生成对应脉宽的PWM再经过低通滤波器还原声音。整段播放过程中CPU几乎零占用还能同时跑显示和按键扫描。DMA就是这么好用。DMA配置时要注意两个细节一是数据宽度要和寄存器匹配CCR是16位你定义的数据表也应该是16位数组二是DMA传输模式选循环模式还是正常模式循环模式适合播放循环音频正常模式适合播放一次就停。5.2 定时器中断配合PWM实现精确动作序列PWM不能解决所有问题有些场景需要精确控制“什么时候开始改变PWM”。比如你要做一个步进电机的S形加速曲线每一阶段对应不同的脉冲频率和占空比那就需要定时器中断来切换参数。常见做法是定时器每隔一段固定时间产生更新中断在中断服务函数里根据当前所处的阶段修改ARR和CCR的值。这里有个要注意的坑在中断里修改ARR时如果预装载没有打开新的ARR值会在当前计数周期立即生效可能导致周期突变波形异常。所以最好把ARR的预装载也打开让改动在下一次更新事件时统一生效。另一个经验中断服务函数里不要做耗时的计算应该提前把每个阶段的参数算好放进数组中断里只做查表和赋值。我见过有人在中断里跑浮点运算直接把中断周期拖到溢出导致整个控制链路失稳。做嵌入式永远不要把中断当普通函数用。5.3 多通道PWM同步输出避免相位错乱在很多电机控制场景中你需要同时输出三路或者六路PWM而且通道之间必须有严格的相位关系。比如三相逆变器三个桥臂的PWM相差120度电角度如果相位不对电机转矩会剧烈波动。同一定时器的多个通道天然是同步的因为它们共享同一个计数器。比如TIM1的CH1、CH2、CH3它们的CNT是同一个只要分别设置不同的CCR值输出波形之间的相位偏移就是确定的不会出现累计误差。不同定时器之间的通道同步就要麻烦一些需要配置从模式把一个定时器作为另一个的主模式通过触发信号实现同步启动。如果不想搞得那么复杂建议优先把多路PWM放在同一个定时器上不足再考虑定时器同步。多通道还有一个坑当你同时更改多个通道的CCR时如果预装载没开每个通道的写入生效时间可能不同导致在某一瞬间出现错误的占空比组合。这在电机控制中是致命问题——上下桥臂的组合状态瞬间错乱可能直接短路。所以务必打开预装载让所有通道的更新在同一时刻生效。6. 常见问题排查与避坑指南6.1 PWM完全没有输出先别怀疑芯片坏了按照下面这个顺序排查最有效率引脚有没有复用对。查阅数据手册确认你选的定时器通道和引脚映射关系有些芯片引脚有多个复用功能要用正确的AF配置。GPIO有没有被其他外设占用比如JTAG、调试接口。某些芯片的PA13到PA15和PB3、PB4是调试口默认不能当普通IO用需要关闭调试功能才释放出来。我把PA15复用成PWM输出时踩过这个坑配置了半天没反应最后发现是JTAG占着。定时器时钟是否使能。可能听上去低级但新手或换平台时很容易漏掉RCC时钟配置。不止定时器时钟GPIO时钟也一样漏一个都不工作。高级定时器的主输出是否使能。前面提过高级定时器有一个控制主输出的位默认是关闭的。如果你用的是通用定时器没这个问题但换到高级定时器必须置1。检查计数器有没有在走。通过调试器读CNT寄存器看它是否递增。如果CNT都没动那就是时基配置有问题重点查PSC和ARR有没有写进去。6.2 占空比有变化但频率不对频率不对先检查ARR1和PSC1的计算。一个极容易犯的错把ARR设成19999PSC设成71以为和上面例子一样但系统时钟不是72MHz而是8MHz结果实际频率就完全不是50Hz。这种情况下如果手头有示波器一测就能发现。如果没有示波器可以用另一个定时器测量输入信号的频率或者用计数器和定时器估算也能算出来。还有一个可能你在运行时修改了ARR但同时又修改了PSC两个修改的生效时间不一致导致计数器一段时间内跑得乱七八糟最终输出的平均频率和期望值有偏差。修改PSC对计数器运作的影响比修改ARR更复杂某些芯片甚至要求先停止计数器再修改PSC。所以如果你在动态调频优先改ARR不要轻易动PSC。6.3 占空比调不到0%或100%很多人把CCR设成0以为输出的就是全低电平但实际可能还有很窄的高电平脉冲把CCR设成ARR1以为全高但实际可能还有下拉的毛刺。这是因为PWM输出在计数比较过程中比较器在CNT等于CCR时翻转如果CCR为0在CNT从0开始递增时第一个瞬间就会产生比较匹配输出状态会经历微小的逻辑转换具体结果取决于输出极性和计数模式。如果你需要严格的0%或100%占空比也就是输出恒低或恒高不要试图靠PWM通道自身实现正确的做法是通过刹车输入或强制输出功能。很多定时器支持强制输出高或低电平比如调用库函数里TIM_ForcedOC1Config这类接口让通道强制输出某个电平。这样比靠CCR边缘情况可靠得多。另外电机控制在占空比极值处上下桥臂的切换逻辑容易出现竞争风险。即便钳位到0%高压侧管子关断低压侧管子也不能长时间处于线性放大区。这时候通常要配合同步整流控制和死区保护才能保证可靠。6.4 输出波形有毛刺或抖动毛刺的来源很多最常见的是CCR写入时机和计数器运行不同步。解决方式是打开预装载让新值在下一次更新事件时才生效。另一个来源是电源噪声。PWM引脚高速翻转时如果板子地平面处理不好电流突变会在电源轨上产生尖峰这些尖峰耦合到参考电压或IO口会导致比较器翻转抖动。此时可以降低GPIO翻转速度或者在引脚附近加一个小电容滤波但要注意电容过大会让波形边沿变缓影响时序所以通常加几十皮法级别的电容就够了。如果抖动发生在动态更新占空比时而且你在用DMA传输那检查DMA的优先级和总线仲裁。如果DMA被其他外设抢占过久CCR的更新间隔就不均匀导致占空比抖动。可以适当提高DMA优先级或者把更新表的长度缩短减少单次传输时间。6.5 中断频繁触发导致主程序卡死有些应用需要定时器中断来刷新占空比但如果刷新的频率过高比如每50微秒触发一次中断而中断服务函数里的处理时间超过50微秒那就会造成中断嵌套或丢失主程序完全被饿死。解决思路有几种一是降低PWM刷新频率看是否满足系统响应需求二是把中断中的处理尽可能精简只做必要的寄存器赋值算法移到主循环或低优先级中断中处理三是直接换成DMA搬运彻底绕开中断。我个人倾向于第三种能不用中断就不用中断。做运动控制、电源控制这种实时系统时中断越多越容易出事DMA才是真正的朋友。6.6 一个容易被忽略的问题引脚带负载能力PWM输出引脚的驱动能力有限直接驱动LED或小蜂鸣器没问题但直接驱动大功率MOS管或者电机就不够看了。很多新手把PWM引脚直接接到MOS栅极结果MOS管半开半闭发热严重波形也乱七八糟。正确做法是PWM先经过栅极驱动器再驱动功率管。栅极驱动器的选型要考虑峰值电流、传播延迟和死区兼容性。高频PWM下栅极驱动器的传输延迟会造成占空比失真这时需要用死区补偿或者校准手段。我自己做过一个直流电机调速器一开始直接PWM接MOS波形在慢速时还能看频率一上10kHzMOS直接烫手后来加了栅极驱动芯片并且串了一个几十欧姆的栅极电阻波形和温升才正常。这类问题不是定时器配置能解决的但确实是PWM应用里最常见归类错误。7. 想到哪说到哪一点个人经验最后分享几个我自己在实际项目中养成的习惯不算系统性的教程但用顺了之后确实能少走不少弯路。第一配置任何外设之前先花十分钟把数据手册里相关章节的寄存器框图和时序图画出来别急着敲代码。定时器这种外设寄存器之间耦合特别多只看库函数不看手册非常容易写出一堆“看起来对但实际错”的配置。第二所有关键的定时参数比如ARR、PSC、CCR的计算不要手算写一个小工具函数或者直接用公式在注释里标注方便后面调参。第三尽量在项目早期就把逻辑分析仪接上从第一个PWM波形开始就验证别攒到最后一起调试不然出错根本不知道是哪一步引入的。我记得第一次调三相电机驱动时死区时间设得太小一上电电流直接冲顶保护电路反复触发当时我以为是程序逻辑问题折腾了两天后来用示波器一看互补PWM在切换时上下管有明显重叠导通才意识到是死区问题。改成硬件死区之后一切安静了。从那以后我养成了“先看波形再改代码”的调试顺序这句话也送给你。如果你正打算用定时器做PWM别被那一堆寄存器吓到。核心就三件事时基定了频率比较定了宽度极性定了电平。把这三件事想清楚再复杂的PWM应用也只是在这个基础上叠加各种触发、DMA和同步机制而已。多动手焊板子、接示波器踩几次坑自然就熟练了。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑