前言
通过本次的学习,了解定时器的分类和配置,高级定时器,通用定时器等不同等级的定时器拥有的功能,学习定时器的输入捕获与输出比较功能(PWM)脉冲宽度调制,来控制电机等外设。
定义
定时器的分类
在GD32这款单片机中不同的单片机拥有的功能数不同的,其中高级定时器的功能最多,通用定时其次,基本定时的功能最少。
高级定时器简介
高级定时器(TIMER0 和 TIMER7)是四通道定时器,支持输入捕获和输出比较。可以产生 PWM信号控制电机和电源管理。高级定时器含有一个 16 位无符号计数器。
高级定时器是可编程的,可以被用来计数,其外部事件可以驱动其他定时器。高级定时器包含了一个死区时间插入模块,非常适合电机控制。
定时器和定时器之间是相互独立,但是它们的计数器可以被同步在一起形成一个更大的定时器。
高级定时器的主要特征
总通道数: 4;
计数器宽度: 16位;
时钟源可选:内部时钟,内部触发,外部输入,外部触发;
多种计数模式:向上计数,向下计数和中央计数;
正交编码器接口:被用来追踪运动和分辨旋转方向和位置;
霍尔传感器接口:用来做三相电机控制;
可编程的预分频器: 16位,运行时可以被改变;
每个通道可配置:输入捕获模式,输出比较模式,可编程的PWM模式,单脉冲模式;
可编程的死区时间;
自动重装载功能;
可编程的计数器重复功能;
中止输入功能;
中断输出和DMA请求:更新事件,触发事件,比较/捕获事件和中止事件;
多个定时器的菊链使得一个定时器可以同时启动多个定时器;
定时器的同步允许被选择的定时器在同一个时钟周期开始计数;
定时器主/从模式控制器。
预分频的概念
预分频器可以将定时器的时钟(TIMER_CK)频率按 1 到 65536 之间的任意值分频,分频后的时钟 PSC_CLK 驱动计数器计数。分频系数受预分频寄存器 TIMERx_PSC 控制,这个控制寄存器带有缓冲器,它能够在运行时被改变。新的预分频器的参数在下一次更新事件到来时被采用。(简单来说就是GD32这款MCU的时钟频率默认是120MHz,经过一分频之后的值是60MHz,经过2分频后的时钟频率是30MHz),预分频器可以和重装计数器CAR和计数值CNT之间进行配合控制系统的运行周期和时间。
计数方式
高级定时器提供三种计数方式,第一中方式的向上计数,第二种方式是向下计数,第三种方式是中央对齐的方式进行计数,以下是本人对于三种计数方式的理解。
1:向上计数方式
CAR 表示的是重装计数器的值,当计数值重装计数器的值时系统产生一个中断,此时CNT计数值加 1同时计数重新设置为0开始下一轮的计数
2: 向下计数的方式
向下计数的方式和向上计数的方式原理上是一样的,一个的数值是向上加,一个的数值是向下减,当计数的值减到0的时候产生中断计数一次。
3:中央对齐的方式计数
计数的值首相向上开始计数,当计数到规定的数值的时候产生一个中断(注意:在嵌入式系统中中断是一定存在的,无论是你想还是不想中断一定存在),达到中断触发条件中断被触发此时开始向另外的一个方向开始新的一轮计数。
定时器使用场景
定时器的使用场景主要有三种,第一种是基本的定时功能,当定时计数器达到某个设定的值之后去执行认为规定的系统相关操作,输出比较:主要是对PWM脉冲宽度调制的比较,输入捕获,主要是对PWM的波形进行捕获之后对一些外设或者时钟的周期进行相关的操作。
定时器的基本原理
定时器的本质:
定时器被本质上是一个电子计数器,当输入端输入三个周期的脉冲信号之后,CNT的计数值 + 3
假设一个脉冲的信号周期的时间是1s,那么三个时钟周期的时间就过去了三秒。
系统主频和定时时间的关系:
在GD32这款单片机系统的主频是120MHz的时钟主频那么一个周期的计数时间就是T = 1 / 120us,那么如果计数120次,对应过去的时间t就是1us。
定时器计时的上限:
CAR寄存器是用于设置CNT计时上限的,比如将Car设置成12000,CNT从0开始向上计数,当CNT=12000时、CNT将被系统清零.同时,系统可以产生一个定时中断。
这里将CNT的值设置为12000,系统时钟的主频是120MHz,这个时候一个计时的周期就是T = 1/ 120 ,然后定时的时间t = CNT * (1/120)us = 12000 * 1 / 120 = 100us
预分频器:
PSC是预分频器,可以灵活调整进入计数器的时钟频率,比如PSC设置为120后,那么实际进入CNT的信号周期也就变成了1us,然后再把CAR设置成100,此时定时中断的周期依然是100us,所以PSC可以从硬件层面调节定时周期的长短,非常灵活:
高级定时器的硬件结构:
这里定时器配置主要使用到的是CNT计数器,CAR重装载寄存器,预分频器PSC
定时器驱动配置
这里设置的是一个1ms中断一次的定时器延时函数,基于1ms中断一次,我们这里默认系统时钟的主频是120MHz的时钟主频,然后预分频器的值设置为120这个时候t定时一个的时间就是1us,那么我们设置重装载寄存器的值为1000,也就是计数值达到1000的时候溢出一次,产生一次定时器中断,那么1000 * 1us就是1ms,也就是我们这个定时器定时到1ms的时候会产生一次定时中断。
注:在定时器配置的同时,定时器预分频的值和CAR重装载寄存器的值要减去1,原因数和C语言的数组下标类似,数组的下表是从0开始的,我们配置定时器CAR的值如果我们希望是1000那么如果直接写1000的话实际的值是1001,所以需要将我们的数值减去1这样CAR的值才是1000。
代码编写
这里使用通用定时器4为例进行定时器驱动的编写,创建定时器初始化函数,这里的