小熊派gd32f303学习之旅(6)—使用基本定时器实现LED闪烁
一、前言
通过查看gd32f30x的参考手册,可以知道gd32f303共有14个定时器,其中2个基本定时器,10个通用定时器,2个高级定时器。
接下来,我们使用基本定时器5的定时器中断来完成LED的闪烁功能。
二、初始化定时器
首先,编写定时器5的初始化函数:
/* 基本定时器5初始化函数
* 参数: psr:时钟预分频系数,预分频值=psr+1
arr:自动重装载值,计数次数=arr+1
* 返回值:无 */
void timer5_init(uint32_t psr, uint32_t arr)
{
/* 定义一个定时器初始化结构体 */
timer_parameter_struct timer_init_struct;
/* 开启定时器时钟 */
rcu_periph_clock_enable(RCU_TIMER5);
/* 初始化定时器 */
timer_deinit(TIMER5);
timer_init_struct.prescaler = psr; /* 预分频系数 */
timer_init_struct.period = arr; /* 自动重装载值 */
timer_init_struct.alignedmode = TIMER_COUNTER_EDGE; /* 计数器对齐模式,边沿对齐(定时器5无效)*/
timer_init_struct.counterdirection = TIMER_COUNTER_UP; /* 计数器计数方向,向上(定时器5无效)*/
timer_init_struct.clockdivision = TIMER_CKDIV_DIV1; /* DTS时间分频值(定时器5无效) */
timer_init_struct.repetitioncounter = 0; /* 重复计数器的值(定时器5无效)*/
timer_init(TIMER5, &timer_init_struct);
/* Timer5中断设置,抢占优先级0,子优先级0 */
nvic_irq_enable(TIMER5_IRQn, 1, 1);
/* 使能Timer5更新中断 */
timer_interrupt_enable(TIMER5, TIMER_INT_UP);
/* 使能Timer5 */
timer_enable(TIMER5);
}
三、编写中断服务函数
接下来编写定时器5的中断服务函数,每次进入中断后就将LED的状态进行翻转
/* TIMER5 中断服务函数
* 参数:无
* 返回值:无 */
void TIMER5_IRQHandler(void)
{
static uint8_t led_flag = 0;
if(timer_interrupt_flag_get(TIMER5, TIMER_INT_FLAG_UP))
{
/* 清除TIMER5 中断标志位 */
timer_interrupt_flag_clear(TIMER5, TIMER_INT_FLAG_UP);
led_flag = !led_flag;
LED(led_flag);
}
}
四、修改main函数
最后要在main函数中调用定时器初始化函数,设置预分频系数和自动重装载值,通过查看时钟树可以看到,TIMER5是挂在APB1下的,其时钟为60MHz,当我们将定时器的预分频系数设置不为1时,则CK_TIMER为两倍的CK_APB1进行分频,即120MHz进行分频;
这样我们将预分频系数设为1200-1,自动重装载值为50000-1,则定时器每隔500ms进入一次中断,即每秒LED闪烁一次
int main(void)
{
int t = 0;
/* 配置系统时钟 */
systick_config();
/* 初始化LED */
led_init();
/* 初始化USART0 */
uart0_init(115200);
/* 初始化定时器5 */
timer5_init(1200-1, 50000-1);
/* 通过串口打印 Hello world! */
u1_printf("Hello world! ");
u1_printf("I am William. \r\n");
while(1)
{
if(UART0_RX_STAT > 0)
{
UART0_RX_STAT = 0;
u1_printf("RECEIVE %d data:%s \r\n", UART0_RX_NUM, UART0_RX_BUF);
}
delay_1ms(10);
t++;
// if(t % 200 == 0) LED(0); /* turn off LED */
// else if(t % 200 == 100) LED(1); /* turn on LED */
}
}
五、功能验证
编译链接烧录到小熊派开发板,然后观察LED的闪烁情况:
六、附录
完整代码我存放在码云,可以查看:https://gitee.com/william_william/BearPi-GD32F303RGT6.git
上一篇:小熊派gd32f303学习之旅(5)—使用DMA和空闲中断实现串口接收
下一篇:小熊派gd32f303学习之旅(7)—使用PWM实现LED呼吸灯