前言
关于Timer部分,之前一值使用STM32型MCU,定时器时钟大多数都是基于APB1或APB2上分频获得,再设置预分频值和装载值,即可计算出定时时间。但GD32F470型定时器使用定时时间计算与之有很大区别。
时钟源
使用定时器,首先需要从时钟树上获取以下几个信息:
1、外部晶振:本文举例选用25MHz;
2、系统时钟:通过system_gd32f4xx.c文件中开启对应晶振和系统时钟的宏定义。支持8M、16M和25M三种晶振,系统时钟分别为120MHz、168MHz、200MHz以及240MHz。
本文举例使用25M晶振,系统时钟为200MHz。对应宏定义如下:
#define __SYSTEM_CLOCK_200M_PLL_25M_HXTAL (uint32_t)(200000000)
此时系统时钟CK_SYS :200MHz
AHB:CK_SYS CFG0->APHPSC:0X00 不分频 200MHz
APB1:CK_AHB/4 CFG0->APB1PSC:0X05 4分频 50MHz
APB2:CK_AHB/2 CFG0->APB2PSC:0X04 2分频 100MHz
3、时钟树中定时器挂在哪个总线上
选用Timer1,定时器1挂接在APB1总线上
4、时钟源选择CFG1->TIMERSEL
CFG1->TIMERSEL默认为0时:
CFG0->APB1PSC:0X05时,时钟源CK_TIMER1 = 2*CK_APB1 = 2*CH_AHB/4 = 100MHz;
CFG1->TIMERSEL选择为1时:
CFG0->APB1PSC:0X05时,时钟源CK_TIMER1 = CH_AHB = 200MHz。
5、定时时间计算
prescaler:设置用来作为TIMx时钟频率除数的预分频值;
period:设置在下一个更新事件装入活动的自动重装载寄存器周期的值;
定时时间: (prescaler+1)/ CK_TIMER1* (period+1)
例如:prescaler为9(计数从0开始,到prescaler值结束,因而共(prescaler+1)个时钟),period为1999(计数从0开始,到period值结束,因而共(period+1)个时钟)时,CFG1->TIMERSEL为0时,定时时间2ms; CFG1->TIMERSEL为1时,定时时间1ms。
定时器参数配置
定时器实现函数如下:
void DRV_TIM_Config(unsigned int arr, unsigned int psc)
{
timer_parameter_struct initpara;
rcu_periph_clock_enable(RCU_TIMER1);//开启时钟
rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);//对应时钟源选择CFG1->TIMERSEL选择为1
initpara.prescaler = psc;//设置用来作为TIMx时钟频率除数的预分频值
initpara.period = arr;//设置在下一个更新事件装入活动的自动重装载寄存器周期的值
// initpara->alignedmode = TIMER_COUNTER_EDGE;
initpara.counterdirection = TIMER_COUNTER_UP;
initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_init(TIMER1, &initpara);
//清状态,设置中断
timer_flag_clear(TIMER1, TIMER_FLAG_UP);
timer_interrupt_enable(TIMER1, TIMER_INT_UP);
//定时器中断
/* enable and set timer interrupt priority */
nvic_irq_enable(TIMER1_IRQn, 1U, 1U);
timer_enable(TIMER1);
}
main函数中调用以下语句:
DRV_TIM_Config(99,1999);//1ms定时 200MHZ
//定时器中断
void TIMER1_IRQHandler(void)
{
static unsigned int tcntt = 0;
if(SET == timer_interrupt_flag_get(TIMER1, TIMER_INT_FLAG_UP))
{
//添加定时处理代码
tcntt++;
timer_interrupt_flag_clear(TIMER1, TIMER_INT_FLAG_UP);
}
}
总结:
GD32F470定时器使用时,需要根据定时器时钟挂接总线时钟,定时器时钟源CFG1->TIMERSEL以及预分频值和重装载值来计算定时时间。