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

第四章 Timer定时器
文章目录
第四章 Timer定时器
前言
一、Timer使用场景
二、Timer编程
三、总结
前言
GD32F3x0系列有多达六种不同的定时器类型,每种定时器含有不同的特性,比如高级定时器几乎包含所有功能,L0级定时器可以将两个定时器合并作为32位定时器使用,基本定时器可以作为DAC时钟源等。


一、Timer使用场景
单片机定时器一般使用场景有:
精准定时,通过计数器和中断方式来达到精准定时的目的;
波形分析,通过输入捕获功能来测量波形的频率,占空比等;
电机控制,通过PWM输出模式,输出占空比可调的方波信号,对电机进行控制;
二、Timer编程
因为我们刚刚使用,就从精准定时来开始入手,先把它用起来再去考虑它的高级功能吧。
先来看一下固件库给我提供哪些函数,无非就是初始化和使能,来找刚好有这两个函数。

以上三个函数只是让定时器的计数功能能跑起来,但是我们并不知道它跑到哪里了,这里我们用到了中断,当它计数到指定值时候,让它提醒一下我,时间到了,中断就相当于闹钟的功能,那我们再往下找一下中断相关的函数,以下3个是我们本次用到的。

看玩库函数我们就开始编程吧,我们在上一章工程中进行修改,新建两个文件bsp_timer.c和bsp_timer.h,保存到我们的APPS目录下,并添加到工程中。

来看一下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为重复计数,就是重复计数几次才产生中断,但是我这里试了一下没用,看有没有懂的大虾解释一下。

下来还有一个陌生的函数nvic_irq_enable(TIMER13_IRQn,3,3),这个是中断优先级配置函数,单片机内部很多中断,多个中断同时产生时,就需要知道谁优先处理,所以需要对中断优先级进行配置,这里配置成最低优先级。
再来就是TIMER13_IRQHandler中断服务函数,TIMER13的所有中断都会进入到这里,如果我们不知道某个外设中断服务函数名是什么,我们可以去startup_gd32f3x0.s文件中查找,大部分的单片机都类似,在启动前都会将中断函数地址写入中断向量表中,所以可以在这里找到所有中断服务函数名。

中断服务函数中,我们主要对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定时器
————————————————
版权声明:本文为CSDN博主「ZzJan0」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zj820137793/article/details/125583301

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值