漫谈LiteOS之开发板-Timer(基于GD32450i-EVAL)
7 Timer
1 简介
Timer即定时器,与SysTick定时器不同的是,并非ARM Cortex-M3/M4处理器都有,而是某一些开发板特有的,且数量和类别存在一定差别。
GD32450i-EVAL开发板共有14个定时器,分别为TIMER0-TIMER13,其中有2个高级定时器,10个通用定时器,2个基本定时器,具体如表1所示。
表1 GD32450i-EVAL开发板定时器
定时器编号 | 0、7 | 1、2、3、4 | 8、11 | 9、10、12、13 | 5、6 |
类型 | 高级 | 通用L0 | 通用L1 | 通用L2 | 基本 |
预分频数 | 16位 | 16位 | 16位 | 16位 | 16位 |
计数器位数 | 16位 | 32位(1、4) 16位(2、3) | 16位 | 16位 | 16位 |
捕获/比较通道数 | 4 | 4 | 2 | 1 | 0 |
计数模式 | 向上、 中央对齐、 向下、 | 向上、 中央对齐、 向下、 | 向上 | 向上 | 向上 |
2 定时器分类
定时器按照分类分为基本定时器、通用定时器、高级定时器,其中通用定时器包括通用定时器L0、L1、L2。
定时器都具有16位可编程预分频器、16位无符号计数器、自动重载计数器。
2.1 基本定时器
基本定时器结构较为简单,主要包括两个功能,(1)基本定时功能,生成时基;(2)用于驱动数模转换器,定时器5和定时器6,功能完全一样,但是所用资源彼此完全独立,可以同时使用。
基本定时器具有以下特性:
时钟源:内部时钟;
可产生DMA请求,TRGO连接到DAC;
触发DAC的同步电路;
中断/DMA请求:更新事件;
其结构框图如图1 所示。
图1 基本定时器结构框图
2.2 通用定时器
通用定时器可被同步形成一个更大的定时器。通用定时器包括通用定时器L0、通用定时器L1、通用定时器L2。除上述表1中提到的,三者存在相同之处也存在一定区别。
2.2.1 通用寄存器共同特性
时钟源可选:内部时钟、内部触发、外部输入、外部触发。
每个通道可配置:输入捕获模式,输出比较模式,可编程的PWM模式,单脉冲模式。
2.2.1 通用寄存器特性差异
(1)通用定时器L0
4通道定时器,支持输入捕获、输出比较、产生PWM信号控制电机和电源管理;
正交编码器接口:被用来追踪运动和分辨旋转方向和位置;
霍尔传感器接口:用来做三相电机控制;
中断输出和DMA请求:更新事件,触发事件,比较/捕获事件;
多个定时器的菊链使得一个定时器可以同时启动多个定时器。
图2 通用计时器L0结构框图
(2)通用定时器L1
中断输出:更新事件,触发事件,比较/捕获事件和中止事件;
多个定时器的菊链使得一个定时器可以同时启动多个定时器;
定时器的同步允许被选择的定时器在同一个时钟周期开始计数;
定时器主/从模式控制器。
图3 通用计时器L1结构框图
(3)通用定时器L2
中断输出:更新事件,触发事件,比较/捕获事件和中止事件。
图4 通用计时器L2结构框图
2.3 高级定时器
高级寄存器相对于基本定时器以及高级定时器具有更强大的功能。具体如下所示:
正交编码器接口:被用来追踪运动和分辨旋转方向和位置;
霍尔传感器接口:用来做三相电机控制;
每个通道可配置:输入捕获模式,输出比较模式,可编程的PWM模式,单脉冲模式;
可编程的死区时间;
可编程的计数器重复功能;
中止输入功能使定时器按照用户的配置输出;
中断输出和DMA请求:更新事件,触发事件,比较/捕获事件和中止事件;
多个定时器的菊链使得一个定时器可以同时启动多个定时器;
定时器的同步允许被选择的定时器在同一个时钟周期开始计数;
定时器主/从模式控制器。
其结构如图5所示。
图5 高级定时器结构框图
3 功能描述
可见定时器具有很多功能,下面仅对几个常见的基础功能加以介绍。
3.1 时基
时基即时间基准,就是一个时间显示的基本单位。时基单元包括计数器寄存器,预分频器寄存器,自动重载寄存器。计数器、自动重载寄存器和预分频器寄存器都可以通过软件进行读写,即使在计数器运行时。
3.2 时钟源
对于基本定时器时钟源有内部时钟源提供,对于通用定时器和高级寄存器,其时钟源可以有内部时钟源或者由从模式寄存器(SMC)控制复用的时钟源驱动。包括内部时钟源、外部时钟模式0和外部时钟模式1。
3.3 预分频器
计数器的时钟可以通过预分频器进行1到65536之间任意值分频,分频后的时钟驱动计数器计数,分频系数受预分频寄存器控制,其带有缓冲器,可以在运行时被改变。新的预分频器的参数在下一次更新事件到来时被使用。
3.4 计数模式
计数模式共分为三种,包括向上计数模式、向下计数模式、中央对齐模式,对于不同类别的计数器,其具有的计数器模式各不相同,具体如表1所示。
(1)向上计数模式
向上计数模式即计数器从0开始向上连续计数到自动加载值(定义在自动重载寄存器中),并生成计数器上溢事件,当计数到自动重载值时,会重新从0开始计数。每次计数器上溢时会生成更新事件。但是如果设置了重复计数器,在(TIMERx_CREP+1)次上溢后产生更新事件。当产生更新事件时,所有寄存器都将被更新。
(2)向下计数模式
与向上计数方式相反,该模式下,计数器从自动重载值向下连续计数到0(倒计时),并生成计数器下溢事件,当计数器到0时,会重新开始计数,每次计数器下溢时会产生更新事件。但是如果设置了重复计数器,在(TIMERx_CREP+1)次上溢后产生更新事件。当产生更新事件时,所有寄存器都将被更新。
(3)中央对齐模式
与前两者不同,该模式下,计数器交替的从0开始向上计数到自动加载值,然后在向下计数到0。向上计数时,定时器模块在计数器计数到自动加载值-1时产生一个上溢事件;向下计数时定时器在计数器计数到1时产生一个下溢事件。在中央计数模式中,寄存器中的计数方向控制位设置为只读。计数方向被硬件自动更新。将SWEVG寄存器的UPG位置1时可以初始化计数值为0,并产生一个更新事件。
3.5 重复计数器
重复计数器是用来在N+1个计数器周期之后产生更新事件,更新定时器的寄存器。向上计数模式下,重复计数器在每次计数器上溢时递减;向下计数模式下,冲反复计数器在每次计数器下溢时递减;中央对齐模式下,重复计数器在计数器上溢和下溢时递减。
3.6 捕获/比较输出通道
定时器的通道用于捕获输入或比较输出是否匹配,通道围绕一个通道捕获比较寄存器简历,包括一个输入级、通道控制器和输出级。
捕获模式允许通道测量一个波形时序、频率、周期、占空比等,输入级包括一个数字滤波器、一个通道极性选择、边沿检测和一个通道预分频器。如果在输入引脚上出现被选择的边沿,TIMERx_CHxCV寄存器会捕获计数器当前的值,同时CHxIF位被置1,如果CHxIE = 1则产生通道中断。
通道输入信号CIx先被TIMER_CK信号同步,然后经过数字滤波器采样,产生一个被滤波后的信号。通过边沿检测器,可以选择检测上升沿或者下降沿。通过配置CHxP选择使用上升沿或者下降沿。配置CHxMS.,可以选择其他通道的输入信号,内部触发信号。配置IC预分频器,使得若干个输入事件后才产生一个有效的捕获事件。捕获事件发生,CxC存储计数器的值。
配置主要包括5步:滤波器配置、边沿选择、捕获源选择、中断使能、捕获使能。
在输出比较模式,TIMERx可以产生时控脉冲,其位置,极性,持续时间和频率都是可编程的。当一个输出通道的CxCV寄存器与计数器的值匹配时,根据CHxCOMCTL的配置,这个通道的输出可以被置高电平,被置低电平或者反转。当计数器的值与CxCV寄存器的值匹配时,CHxIF位被置1,如果CHxIE = 1则会产生中断,如果CxCDE=1则会产生DMA请求。
配置过程主要包括5步:时钟配置、比价模式配置、中断或DMA使能、使能定时器。
3.7 PWM模式
在PWM输出模式下,根据TIMERx_CAR寄存器和TIMERx_CHxCV寄存器的值,输出PWM波形。根据计数模式,我们可以分为两种PWM波:EAPWM(边沿对齐PWM)和CAPWM(中央对齐PWM)。EAPWM 的周期由 TIMERx_CAR 寄存器值决定,占空比由 TIMERx_CHxCV 寄存器值决定。CAPWM 的周期由(2*TIMERx_CAR 寄存器值)决定,占空比由(2*TIMERx_CHxCV 寄存器值)决定。
3.8 调试模式
与SysTick定时器不同的是,当MCU进入调试模式时,计数器会根据DBG模块中的DBG_CTL2寄存器TIMERx_HOLD配置位选择继续工作与否,而不是直接伴随着内核的停止而终止,该位置1计数停止。
4 示例
4.1 程序
主函数主要包括GPIO配置和时钟配置,以及延时函数用到的SysTick配置,之后就是对于呼吸灯的循环变量控制。下面主要对定时器配置加以介绍,主要包括对于两个结构体的初始化,定时器比较输出结构体以及定时器捕获输入。实现对于PWM模式0的配置,最终对于通道2实现PWM模式0,占空比为25%。
void timer_config(void) { timer_oc_parameter_struct timer_ocintpara; //定时器比较输出初始化结构体 timer_parameter_struct timer_initpara; // 定时器捕获输入初始化结构体 rcu_periph_clock_enable(RCU_TIMER1); // 使用TIM1时钟 rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4); //配置定时器时钟和预分频器选择 timer_deinit(TIMER1); timer_initpara.prescaler = 119; //时钟预分频器 timer_initpara.alignedmode = TIMER_COUNTER_EDGE; //计数器触发方式 timer_initpara.counterdirection = TIMER_COUNTER_UP; //计数器模式选择向上计数 timer_initpara.period = 500; // 定时器周期个数 自动重载值 timer_initpara.clockdivision = TIMER_CKDIV_DIV1; //时钟分频因子 timer_initpara.repetitioncounter = 0; //重复计数值 timer_init(TIMER1,&timer_initpara); //初始化计数器 timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH; // 有效电平的极性,可以将有效电平设置成高电平或者低电平 timer_ocintpara.outputstate = TIMER_CCX_ENABLE; //配置比较输出模式状态(使能或禁止输出) timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH; //互补输出有效极性 timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE; //互补比较输出状态 timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW; //空闲状态下定时器输出引脚状态 timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW; //空闲状态定时器互补输出引脚状态 timer_channel_output_config(TIMER1,TIMER_CH_2,&timer_ocintpara); //配置定时器通道输出功能 timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_2,0); //配置定时器通道输出脉冲值 timer_channel_output_mode_config(TIMER1,TIMER_CH_2,TIMER_OC_MODE_PWM0); //配置定时器通道输出比较模式 timer_channel_output_shadow_config(TIMER1,TIMER_CH_2,TIMER_OC_SHADOW_DISABLE); //配置定时器通道输出影子寄存器 timer_auto_reload_shadow_enable(TIMER1); timer_enable(TIMER1); }
4.2 硬件操作
首先使用杜邦线将Timer_CH2(PB10)和 LED 1(PE2)连接到一起,然后将程序下载到开发板,按复位键后可见LED灯由暗变亮,往复循环,如人的呼吸一样,因此称为呼吸灯。通过本实验可以学习到如何使用定时器输出PWM波,以及更新定时器通道寄存器的值。具体实验效果如图6以及附件视频所示。
图6 呼吸灯效果
- 点赞
- 收藏
- 关注作者
评论(0)