【GD32】从0开始学GD32单片机(10)—— TIMER基本定时器详解+1毫秒延时例程

概述

在GD32中定时器是非常重要的外设,它可以帮我们精准的控制程序的调度,就如之前讲过的SysTick就是一个定时器,我们可以通过设置这个定时器的寄存器实现延时函数。
GD32的定时器可大致分为3种——基本定时器、通用定时器、高级定时器
它们之间的区别如下图所示:

在这里插入图片描述
这一节先介绍当中最简单的基本定时器。

简介

GD32中的定时器外设都是使用16位计时器;计数模式只有向上计数;支持单脉冲模式;支持DMA传输请求;在内部有触发线连接至DAC,这样可以使用定时器定时触发DAC的数据转换,这个在后面会讲到。

在这里插入图片描述

时钟设置

要想定时器按预期工作,那么对时钟进行正确的设置是十分重要的。先找到对应的时钟树框图。
在这里插入图片描述
首先,基本定时器挂载在APB1总线上,APB1总线的最高频率为54MHz(GD32F103C8T6),那么是不是进入定时器的频率就是这个呢?不是!不是!不是!(重要事情说3遍)
由时钟树中可看到,从AHB总线上过来的频率经过APB1分频器变成CK_APB1,但还需要经过一个分频器,才能变成定时器的时钟(CK_TIMER);这个分频器非常关键,因为它是带条件的,还是用户不可修改的。根据注释,当APB1分频器的分频系数为1时,该分频器的分频系数为1(不分频),否则倍频2倍。因为CK_APB1的频率为54MHz,所以APB1分频器的分频系数自然为2。当然我们也可以在固件库中找到答案,在system_gd32f10x.c文件中,我们可以找到以下这几行代码。
在这里插入图片描述
从247行看到,在系统时钟初始化时,对APB1分频器进行了2分频的设置。
因为APB1分频器的分频系数为2,所以定时器信号分频器会倍频2倍,所以频率最终会跟AHB总线是一样的108MHz
对于挂载到APB2的定时器,它们的分频器也是这个规则。

基本定时器只有在高密度或以上的产品才搭载

很明显,从APB1总线上进来的时钟频率较快,因此定时器外设给了一个预分频器,预分频器寄存器是16位的,因此可以实现1-65536分频,分频后的时钟频率才是定时器计数的频率。
预分频器的工作其实比较好理解,例如我们的预分频是2分频,那么定时器等待2个CK_TIMER时钟周期才让定时器计数1次,以此类推。
下图是预分频系数从1变为2的时序图。

在这里插入图片描述
其中TIMER_CK是定时器的频率,PSC_CLK是预分频之后的频率。

计数模式

基本定时器只支持向上计数这一种模式。计数器从0开始向上连续计数到自动加载值,一旦计数器计数到自动加载值,会重新从0开始向上计数并产生上溢事件。
下面是一个向上计数的时序图。

在这里插入图片描述

上面的PSC值代表不同的预分频系数,PSC等于0和1分别表示1和2分频。
由上图可以看出当寄存器里的值达到了自动加载值后,会产生更新事件标志位和更新中断标志位会置1(若我们开启了对应的中断),不同的是更新事件标志位在置1后会很快被硬件置0,但更新中断标志位则需要用户进行软件清除,这在代码中是要注意的

例程

现象:LED灯以1秒的间隔闪烁。

timer.c文件

#include "timer.h"

static __IO uint32_t timer_val = 0;

void TIM_Init(void)
{
    timer_parameter_struct tim_struct = {0};
    
    rcu_periph_clock_enable(RCU_TIMER1);
    
    tim_struct.counterdirection = TIMER_COUNTER_UP;  // 向上计数
    tim_struct.prescaler = (108 - 1);  // 预分频:108MHz / 108 = 1MHz
    tim_struct.period = (1000 - 1);  // 周期:1000 / 1MHz = 1ms
    
    timer_init(TIMER1, &tim_struct);
    
    nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);
    nvic_irq_enable(TIMER1_IRQn, 1, 1);
    
    timer_interrupt_flag_clear(TIMER1, TIMER_INT_FLAG_UP);
    timer_interrupt_enable(TIMER1, TIMER_INT_UP);

    timer_enable(TIMER1);
}

void TIM_DelayMs(__IO uint32_t ms)
{
    timer_val = ms;
    while(timer_val);
}

void TIM_ValDecrese(void)
{
    if(timer_val) --timer_val;
}

gd32f10x_it.c文件

void TIMER1_IRQHandler(void)
{
    if(SET == timer_interrupt_flag_get(TIMER1, TIMER_INT_FLAG_UP)){
        timer_interrupt_flag_clear(TIMER1, TIMER_INT_FLAG_UP);
        TIM_ValDecrese();
    }
}

总体的设计跟SysTick是差不多的,但SysTick没有预分频器,定时的配置没有定时器要灵活。我们用定时器实现的是一个1ms的延时,预分频系数为107,把频率定成1MHz,这样重装载值为999就可以实现1ms的定时。

GD32的通用定时器具有多种配置选项。通用定时器可以用于各种不同的应用,例如PWM输出、定时中断等。在配置通用定时器时,我们需要考虑以下几个方面: 1. 选择定时器GD32具有多个通用定时器,例如TIM1、TIM2等。根据需求选择合适的定时器。 2. 配置时钟源:通用定时器的工作需要一个时钟源。可以选择内部时钟源或外部时钟源,并根据需求进行相应的配置。 3. 配置计数模式:通用定时器支持向上计数模式,即计数器从0开始递增。可以根据需求选择其他计数模式,例如向下计数或中央对齐。 4. 配置预分频器:预分频器可以设置定时器的计数频率。通过设置预分频系数,我们可以将输入时钟分频以适应需要的计数频率。 5. 配置自动重载寄存器(ARR):ARR决定了定时器的周期。根据所需的定时周期设置ARR的值。 6. 配置输出比较模式:如果需要使用通用定时器的PWM输出功能,可以配置输出比较模式和相关寄存器,包括通道选择、极性、比较值等。 以上是配置GD32通用定时器的一些基本步骤和要点。具体的配置参数和寄存器设置可以根据具体的应用需求进行调整和配置。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [【GD32】从0开始GD32单片机10)—— TIMER基本定时器详解+1毫秒延时例程](https://blog.youkuaiyun.com/JackieCoo/article/details/127053375)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [GD32F405RGT6定时器固件库(所有定时器的配置(12个))](https://download.youkuaiyun.com/download/tiange1996/84842173)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

马浩同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值