GD32实战12__定时器

引子

1.与PWM章节共用代码
2.生活中经常会用到下面几样,

  1. 闹钟,到时间了给出提醒
  2. 秒表(计时器),统计做一件事花费的时间

原理

GD32实战12__定时器_第1张图片

如上图,定时器需要一个时钟输入,在每个时钟触发时,做如下操作

1. 计数器做增加或减少的操作
2. 跟目标值做比较,达到目标则触发中断,并重新把预置值设置到计数器中

因此,实际配置中需要配置如下几步

  1. 时钟源和分频系数等时钟参数
  2. 预置值和目标值
  3. 计数方式,增长和减少
  4. 循环方式,单次还是循环触发

配置举例

功能设计

​ 使用定时器2,控制LED灯每隔1秒亮一次。

定时器配置

  1. 配置分频,如图,定时器2的时钟来自AHB2(108M)–/2–>APB1(54M)–*2–>TIMER2(108M),因此为了实现1s计时,此处配成108MHz/108100=10KHz,故Prescaler = 10800-1。GD32实战12__定时器_第2张图片

    TIMER_BaseInitParaStructure.TIMER_Prescaler = 10800-1; /* 10KHz */
    
  2. 配置计数方式

    TIMER_BaseInitParaStructure.TIMER_CounterMode = TIMER_COUNTER_UP;
    
  3. 配置预置值,第一步说把时钟配置成10KHz了,在10KHz的频率下,计数10000次,就是1s,故TIMER_Period = 10000-1

    TIMER_BaseInitParaStructure.TIMER_Period = 10000-1; /* 10000*10KHz = 1s */
    
    1. 配置循环方式,默认就是循环计数模式,此步可以省下,如果是单步模式,则必须配置。
    TIMER_SinglePulseMode(TIMER2, TIMER_SP_MODE_REPETITIVE);
    
    1. 注意,定时器中断中,第一步必须先清除定时器中断标记,防止中断反复进入。
    TIMER_ClearIntBitState(TIMER2,TIMER_INT_UPDATE);
    
    1. 完整代码如下,
VOID TIMER2_IRQHandler(VOID)
{
    if(TIMER_GetIntBitState(TIMER2,TIMER_INT_UPDATE) != RESET)
    {   
        /* 定时器中断中,第一步必须先清除定时器中断标记,防止中断反复进入 */
        TIMER_ClearIntBitState(TIMER2,TIMER_INT_UPDATE);
        if (gTimerLedFlag != 0)
        {
            DRV_LED_On(DRV_LED1);
            gTimerLedFlag = 0;
            return;
        }
        DRV_LED_Off(DRV_LED1);
        gTimerLedFlag++;
    }
    
}

VOID DRV_TIMER_Timer2Init(VOID)
{
    TIMER_BaseInitPara TIMER_BaseInitParaStructure;
    NVIC_InitPara NVIC_InitStructure;

    RCC_APB1PeriphClock_Enable(RCC_APB1PERIPH_TIMER2,ENABLE); 
	
    TIMER_DeInit(TIMER2);
    TIMER_BaseInitParaStructure.TIMER_Prescaler = 10800-1; /* 10KHz */
    TIMER_BaseInitParaStructure.TIMER_CounterMode = TIMER_COUNTER_UP;
    TIMER_BaseInitParaStructure.TIMER_Period = 10000-1; /* 10000*10KHz = 1s */
    TIMER_BaseInitParaStructure.TIMER_ClockDivision = TIMER_CDIV_DIV1;
    TIMER_BaseInit(TIMER2,&TIMER_BaseInitParaStructure);

    TIMER_INTConfig(TIMER2, TIMER_INT_UPDATE, ENABLE);
    NVIC_InitStructure.NVIC_IRQ = TIMER2_IRQn;   
    NVIC_InitStructure.NVIC_IRQPreemptPriority = 0; 
    NVIC_InitStructure.NVIC_IRQSubPriority = 0;       
    NVIC_InitStructure.NVIC_IRQEnable = ENABLE;        
    NVIC_Init(&NVIC_InitStructure);
    
    TIMER_SinglePulseMode(TIMER2, TIMER_SP_MODE_REPETITIVE);
    TIMER_Enable(TIMER2,ENABLE);
}

代码路径

https://github.com/YaFood/GD32F103/tree/master/TestTimer

你可能感兴趣的:(ARM)