小熊派gd32f303学习之旅(6)—使用基本定时器实现LED闪烁

小熊派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呼吸灯

猜你喜欢

转载自blog.csdn.net/qq_38113006/article/details/108954054