GD32F30x系列—定时器基础配置
找到GD32F30x系列的时钟树可以看到,其定时器1,2,3,4,5,6,11,12,13是挂载在APB1总线上,该总线的最大频率为60MHZ,而定时器7,8,9,10则挂载在APB2上,该总线的最大频率为120MHZ。如下图所示:
注意: 当APB1、APB2的prescaler值不为1时,该总线上的时钟频率为分频之后频率的2倍。上图中APB1最小值为2,APB2最小值为1,
这里我们以定时器1为例进行基础配置,TIMER1时钟频率是其他外设时钟频率的2倍(60MHz*2)。:
1、创建一个timer.c和timer.h文件并分别放入到对应的文件夹中,如下图所示:
将创建好的timer.c文件和库文件gd32f30x_timer.c文件添加到keil工程中,如下图所示:
2、完成定时器的初始化配置,以及定时器中断函数。
//timer.c 文件
#include "timer.h"
uint32_t g_timer_tick=0;
/*
定时器1的初始化--默认定时时间1ms
*/
void gd32_timer_init(void)
{
timer_parameter_struct t_para;
timer_deinit(TIMER1);
rcu_periph_clock_enable(RCU_TIMER1);
t_para.alignedmode = TIMER_COUNTER_EDGE;
t_para.clockdivision = TIMER_CKDIV_DIV1;
t_para.counterdirection = TIMER_COUNTER_UP;//向上计数
t_para.period = 1000;//计数值
t_para.prescaler = 120-1;//预分频系数,总线为120MHz
t_para.repetitioncounter = 0;
timer_init(TIMER1, &t_para);
timer_enable(TIMER1);
nvic_irq_enable(TIMER1_IRQn, 2, 0);
timer_interrupt_flag_clear(TIMER1, TIMER_INT_FLAG_UP);
timer_interrupt_enable(TIMER1,TIMER_INT_UP);
}
/*
定时器1中断函数
*/
void TIMER1_IRQHandler(void)
{
if(RESET != timer_interrupt_flag_get(TIMER1, TIMER_INT_FLAG_UP))
{
g_timer_tick++;//定时器中断一次,定时器时钟增加1
timer_interrupt_flag_clear(TIMER1, TIMER_INT_FLAG_UP);
}
}
//timer.h文件
#ifndef __TIMER_H__
#define __TIMER_H__
#include "gd32f30x.h"
void gd32_timer_init(void);
#endif
3、在main.c文件的main函数中,调用定时器1的初始化,编译下载程序到硬件板中,如下图所示:
4、设置断点到定时器1的中断函数中,发现程序能够正常运行并进入定时器中断,如下图所示:
由于初始化定时器1为1ms中断一次,因此该定时器与系统systick基本上是保持一致的,这里我们查看定时器1时钟和系统时钟systick数值增加也基本保持一致,如下图所示:
调整定时器1的计数值为2ms定时,重新下载程序运行,查看定时器1时钟与系统systick相差1倍,如下图所示:
说明定时器运行正常,定时时间可调整配置。