【GD32F3x0应用笔记】----- 时间管理者Timer定时器

第四章 Timer定时器


文章目录

  • 第四章 Timer定时器
  • 前言
  • 一、Timer使用场景
  • 二、Timer编程
  • 三、总结


前言

GD32F3x0系列有多达六种不同的定时器类型,每种定时器含有不同的特性,比如高级定时器几乎包含所有功能,L0级定时器可以将两个定时器合并作为32位定时器使用,基本定时器可以作为DAC时钟源等。
【GD32F3x0应用笔记】----- 时间管理者Timer定时器_第1张图片


一、Timer使用场景

  • 单片机定时器一般使用场景有:
  • 精准定时,通过计数器和中断方式来达到精准定时的目的;
  • 波形分析,通过输入捕获功能来测量波形的频率,占空比等;
  • 电机控制,通过PWM输出模式,输出占空比可调的方波信号,对电机进行控制;

二、Timer编程

  • 因为我们刚刚使用,就从精准定时来开始入手,先把它用起来再去考虑它的高级功能吧。
  • 先来看一下固件库给我提供哪些函数,无非就是初始化和使能,来找刚好有这两个函数。
    【GD32F3x0应用笔记】----- 时间管理者Timer定时器_第2张图片
  • 以上三个函数只是让定时器的计数功能能跑起来,但是我们并不知道它跑到哪里了,这里我们用到了中断,当它计数到指定值时候,让它提醒一下我,时间到了,中断就相当于闹钟的功能,那我们再往下找一下中断相关的函数,以下3个是我们本次用到的。
    【GD32F3x0应用笔记】----- 时间管理者Timer定时器_第3张图片
  • 看玩库函数我们就开始编程吧,我们在上一章工程中进行修改,新建两个文件bsp_timer.c和bsp_timer.h,保存到我们的APPS目录下,并添加到工程中。
    【GD32F3x0应用笔记】----- 时间管理者Timer定时器_第4张图片
  • 来看一下bsp_timer.c代码
#include "bsp_timer.h"

void Timer13_Init(uint16_t arr,uint16_t psc)
{
	timer_parameter_struct timer13_parameter;
	//时钟使能
	rcu_periph_clock_enable(RCU_TIMER13);
	//定时器配置
	timer_deinit(TIMER13);
	timer13_parameter.period = arr - 1;
	timer13_parameter.prescaler = psc - 1;//分频因子
	timer13_parameter.clockdivision = TIMER_CKDIV_DIV1;
	timer13_parameter.alignedmode = TIMER_COUNTER_EDGE;
	timer13_parameter.counterdirection = TIMER_COUNTER_UP;
	timer13_parameter.repetitioncounter = 0;
	timer_init(TIMER13,&timer13_parameter);
	//中断配置
	nvic_irq_enable(TIMER13_IRQn,3,3);
	//清除中断标志
	timer_interrupt_flag_clear(TIMER13,TIMER_INT_FLAG_UP);
	//中断使能
	timer_interrupt_enable(TIMER13,TIMER_INT_UP);
	//定时器使能
	timer_enable(TIMER13);
}

void TIMER13_IRQHandler(void)
{
	//是否是更新中断
	if(timer_interrupt_flag_get(TIMER13,TIMER_INT_FLAG_UP) != RESET)
	{
		gpio_bit_toggle(GPIOB,GPIO_PIN_0);
		timer_interrupt_flag_clear(TIMER13,TIMER_INT_FLAG_UP);
	}
}
  • 这里用到了一个结构体timer_parameter_struct,它是timer_init函数的输入参数,找一下结构体说明。
  • Prescaler和Period两个参数,共同决定了我们定时时间,假如GD32的时钟为84MHz,Prescaler设置84,那么Timer的时钟为84MHz / 84 = 1MHz,每计数一次就过了1us,Period设置为1000时,就有1000 * 1us = 1ms,如果这时候使能了中断,会可以产生1ms的中断。
  • Clockdivision为时钟分频因子,一般在输入捕获滤波器中用到,这里没用就设置为不分频即可;
  • Alignedmode为对齐模式,这个在PWM输出用到,这里配置边沿对齐即可;
  • Counterdirection为计数方向,这里配置向上计数;
  • Repetitioncounter为重复计数,就是重复计数几次才产生中断,但是我这里试了一下没用,看有没有懂的大虾解释一下。
    【GD32F3x0应用笔记】----- 时间管理者Timer定时器_第5张图片
  • 下来还有一个陌生的函数nvic_irq_enable(TIMER13_IRQn,3,3),这个是中断优先级配置函数,单片机内部很多中断,多个中断同时产生时,就需要知道谁优先处理,所以需要对中断优先级进行配置,这里配置成最低优先级。
  • 再来就是TIMER13_IRQHandler中断服务函数,TIMER13的所有中断都会进入到这里,如果我们不知道某个外设中断服务函数名是什么,我们可以去startup_gd32f3x0.s文件中查找,大部分的单片机都类似,在启动前都会将中断函数地址写入中断向量表中,所以可以在这里找到所有中断服务函数名。
    【GD32F3x0应用笔记】----- 时间管理者Timer定时器_第6张图片
  • 中断服务函数中,我们主要对LED灯的电平进行翻转,同时main函数修改如下:
int main(void)
{
	//延时函数初始化
	Delay_Init();
	//LED GPIO初始化
	LED_Init();
	//串口初始化
	USART0_Init(115200);
	//定时器初始化
	Timer13_Init(10000,8400);
	
	while(1)
	{
		printf("Hello GD32\r\n");
		Delay_ms(1000);
	}
}
  • 重新编译后烧录到单片机中,可以看到LED灯闪烁,同时串口打印输出Hello GD32字符,可以看到就算主函数里加了延时函数,也不会影响我LED的闪烁,这就是中断的好处。

三、总结

本章主要介绍了GD32定时器的使用,同时学习了中断功能的使用。写作不易,如果觉得对你有用,帮忙点个赞,你的支持会让我有更多动力写下去,感谢!
Timer定时器

你可能感兴趣的:(GD32单片机,单片机,嵌入式硬件)