十五、梁山派GD32F450ZGT6定时器全解析:从基础到高级定时器应用
十五、梁山派GD32F450ZGT6定时器全解析从基础到高级定时器应用大家好我是老李一个在嵌入式行业摸爬滚打了十几年的工程师。最近在用梁山派GD32F450开发板做一个小项目需要用到精确的定时和PWM来控制电机于是又把GD32F450的定时器模块好好研究了一遍。我发现这块芯片的定时器资源相当丰富但种类也多刚上手的朋友可能会有点懵。今天我就结合自己的使用经验给大家掰开揉碎了讲讲梁山派上这颗GD32F450ZGT6的定时器从最基础的概念到不同定时器的区别和应用手把手带你搞明白。咱们的目标是看完这篇文章你不仅能知道定时器是干什么的还能清楚梁山派上这14个定时器各自有什么能耐以及在实际项目中该怎么选、怎么用。1. 定时器到底是什么从“数数”说起很多新手朋友一听到“定时器”就觉得很高深其实它的核心思想特别简单数数。你可以把它想象成一个非常精准的“电子秒表”。单片机内部有一个始终在跳动的心脏——系统时钟。定时器呢就负责数这个时钟跳动的次数。比如系统时钟每跳动一次定时器内部的计数器就加1。当我们预先告诉它“请你数够100万次的时候告诉我一声”那么当它数到100万次时就会产生一个“时间到了”的信号也就是中断然后我们就可以在这个信号里去做事情比如让一个LED灯翻转一下。举个例子咱们想让梁山派开发板上的LED灯每隔1秒闪烁一次。靠人眼去延时肯定不准这时候定时器就派上用场了。我们可以配置一个定时器让它精确地每隔1秒产生一次中断然后在中断服务函数里写下“翻转LED引脚电平”的代码一个精准的1秒闪烁灯就实现了。所以定时器的本质就是一个可编程的、自动的计数器它的主要工作就是计时并在时间到达时通知CPU。2. 梁山派的定时器“全家福”14个成员各司其职GD32F450ZGT6这颗芯片的强大之处在于它内部集成了多达14个独立的定时器。数量多不是关键关键是它们被分成了不同的类型各有各的绝活适合干不同的活儿。咱们得先搞清楚手上有哪些兵才能排兵布阵。根据官方资料这14个定时器可以分为五大类定时器类型包含的定时器编号核心特点与主要用途高级定时器TIMER0, TIMER7功能最全的“王牌”。4个通道带死区时间控制是电机控制如BLDC、PMSM和复杂电源管理的首选。通用定时器 (L0)TIMER1, TIMER2, TIMER3, TIMER4“主力部队”。也是4通道支持输入捕获和输出比较能做PWM适合大多数通用定时、PWM生成任务。通用定时器 (L1)TIMER8, TIMER11“轻骑兵”。2个通道功能比L0稍少但在通道数要求不高的场合更节省资源。通用定时器 (L2)TIMER9, TIMER10, TIMER12, TIMER13“特种兵”。只有1个通道功能专注用于简单的单通道定时或PWM输出。基本定时器TIMER5, TIMER6“基础工兵”。没有输入输出通道主要用来提供基础的时基、触发DAC数模转换或产生DMA请求。提示更详细的功能对比大家可以翻阅《GD32F4xx用户手册》的第356页那里有一张非常清晰的表格。看到这你可能要问这么多类型我该怎么选别急咱们一个个来拆解。2.1 高级定时器电机驱动的核心高级定时器TIMER0和TIMER7是功能最强大的你可以把它理解为定时器里的“瑞士军刀”。它最大的特色是集成了一个死区时间插入模块。死区时间是啥简单说就是在控制电机比如用全桥电路时我们需要控制一对开关管上管和下管交替导通。但电子开关从开到关、从关到开需要一点点时间。如果上管还没完全关断下管就打开了就会造成电源直接短路瞬间烧毁管子死区时间就是在上下管切换时插入一个两者都关闭的“安全区”确保绝对安全。所以当你需要做直流无刷电机BLDC或永磁同步电机PMSM的驱动时高级定时器几乎是唯一的选择。它生成的PWM信号可以硬件自动插入死区省去了软件计算的麻烦也更安全可靠。2.2 通用定时器L0多面手够用就好通用定时器L0TIMER1-TIMER4是我们平时用得最多的“多面手”。它也有4个通道能做的事情很多输出比较可以产生PWM波控制LED亮度、舵机角度、蜂鸣器音调等。输入捕获可以测量外部脉冲的宽度或频率比如读取编码器信号、测量红外遥控信号的脉宽。它和高级定时器的主要区别就是少了死区时间插入、计数器重复功能和紧急停止中止输入功能。对于不涉及电机安全控制的普通PWM和定时应用比如控制多个LED灯、生成多路舵机信号用L0定时器就完全足够了没必要动用高级定时器。2.3 通用定时器L1与L2按需取用节省资源L1和L2定时器可以看作是L0的“精简版”。L1定时器TIMER8, TIMER11通道数减为2个。如果你的项目只需要两路PWM或者捕获两个信号用L1更经济可以把4通道的L0省下来给更复杂的任务。L2定时器TIMER9, TIMER10, TIMER12, TIMER13通道数只有1个。功能最为单一但用来驱动单个蜂鸣器、产生一个固定频率的方波或者做简单的单次定时非常合适。注意一个手册上的小坑在用户手册第475页描述L2定时器时图表里可能写了支持多种计数模式。但根据实际芯片设计和众多工程师的验证通用定时器L2只支持向上计数模式。这一点大家编程时要注意别被手册误导了。2.4 基本定时器纯粹的“计时员”基本定时器TIMER5, TIMER6是最简单的它没有输入输出通道不能产生PWM也不能捕获信号。那它能干嘛 它就是一个纯粹的时间基准发生器。主要用途有两个为整个系统提供一个精确的时基比如操作系统的心跳节拍。为DAC数模转换器提供触发时钟或者产生DMA请求用于定时触发数据搬运。当你只是需要一个简单的、周期性的“滴答”信号来触发某些操作时用基本定时器最合适。3. 理解定时器的核心“旋钮”预分频与计数模式知道了有哪些定时器我们还得知道怎么“调教”它们。配置定时器最关键的就是玩转两个核心参数预分频和计数模式。3.1 预分频器控制“数数”的快慢定时器并不是直接去数系统时钟的跳动那样太快了比如系统时钟是200MHz一秒钟能数2亿次我们根本用不上这么高的精度。这时就需要预分频器来给时钟“减速”。你可以把预分频器想象成一个齿轮箱。系统时钟TIMER_CK是高速旋转的输入轴通过调节齿轮比预分频系数可以得到一个速度合适的输出轴PSC_CLK去驱动后面的计数器。公式很简单PSC_CLK TIMER_CK / (TIMERx_PSC 1)这里的TIMERx_PSC就是我们设置的分频系数寄存器值。它可以是1到65536之间的任意值。如果TIMERx_PSC设为0那就是1分频计数器每个系统时钟周期都加1。如果TIMERx_PSC设为99那就是100分频计数器每100个系统时钟周期才加1。一个实用的技巧这个预分频值在定时器运行时是可以动态修改的但新的值要等到下一次“更新事件”发生时才会生效。这个特性在需要平滑改变PWM频率时非常有用。3.2 向上计数模式最常用的计数方式这是最直观、最常用的计数模式。计数器就像电梯一样从0楼计数器值0开始一层一层往上爬直到到达你设定的顶楼自动重装载值存在TIMERx_CAR寄存器里。当计数器爬到顶楼后会发生两件事产生一个上溢事件也就是更新事件。电梯瞬间回到1楼计数器清零重新开始向上爬。这个“从顶楼回到1楼”的瞬间就是定时器一个周期的结束和下一个周期的开始。我们设定的“顶楼高度”重装载值和“电梯爬楼速度”分频后的时钟共同决定了定时器一个周期有多长也就是定时时间。3.3 更新事件定时器的“心跳时刻”当计数器向上溢出或向下溢出在向下计数模式下时就会产生一个更新事件。这个事件是定时器工作的核心节拍。更新事件能触发什么中断通知CPU“时间到了”CPU就可以跳转到中断服务函数里执行我们预设的任务比如翻转LED。DMA请求可以不经过CPU直接让DMA控制器搬运数据。这在需要高速、连续输出PWM波形或者采集数据时效率极高。更新参数前面提到的运行时修改预分频值就是在更新事件发生时才真正生效的。4. 实战前瞻定时器能干什么纸上谈兵终觉浅咱们最后聊聊定时器在项目里的实际应用。理解了原理用起来就心中有数了。精准定时这是最基本的功能。比如每1毫秒执行一次传感器数据采集每10毫秒检查一次按键状态或者为RTOS实时操作系统提供系统时钟节拍。用基本定时器或任意一个通用定时器都能实现。PWM信号生成这是通用和高级定时器的强项。通过输出比较模式可以轻松产生占空比可调的方波。应用场景极广控制LED亮度调光。控制舵机角度。控制直流电机转速通过驱动芯片。播放简单的音乐驱动蜂鸣器。输入捕获用来测量外部信号的脉宽或频率。比如测量红外遥控器发射的编码信号。读取旋转编码器的脉冲数来计算速度和位置。测量超声波模块回波的高电平时间来计算距离。电机控制这是高级定时器的专属舞台。利用其互补输出通道和硬件死区插入功能可以安全、高效地驱动三相无刷直流电机或永磁同步电机这是做无人机、机器人、变频器等产品的核心技术。在接下来的教程里我就会以梁山派开发板为例带大家实际动手配置一个通用定时器实现1秒定时中断并控制板载LED闪烁。我们会一步步写代码从开启时钟、配置参数、编写中断服务函数到下载调试把今天讲的理论全部落地。你会发现只要理解了底层原理操作起来并没有那么难。