阅想网:STM32用定时器精确延时的方法(非SysTick)

来源:百度文库 编辑:偶看新闻 时间:2024/04/24 08:54:07
Description:

用TIM2来做延时,延时基准时间1ms,最大可延时65535ms。
系统基础频率是8MHz*4=32MHz。

先配置定时器:

    TIM_TimeBaseInitTypeDef timInitStruct;

    timInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;   // 定时器基准频率32MHz
    timInitStruct.TIM_Prescaler = 32000;                    // 计数频率为1KHz
    timInitStruct.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数
    timInitStruct.TIM_RepetitionCounter = 0;
    timInitStruct.TIM_Period = 0; // 这个值实际上就是TIMX->ARR,延时开始时重新设定即可

    TIM_TimeBaseInit(TIM2, &timInitStruct);
    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); // 计数溢出时触发中断
    TIM_Cmd(TIM2, DISABLE);

把定时器的计数频率定为1KHz,这样每1ms计数一次,可以做1ms为基准的延时。

定义延时函数:

     u8 _delayTimeOut;

    void delay1ms(u16 delayTime)
    {
        _delayTimeOut = 0;
        TIM2->ARR = delayTime;

        TIM_Cmd(TIM2, ENABLE);
        while(!_delayTimeOut)
        {
        }
        TIM_Cmd(TIM2, DISABLE);
    }

定义计数溢出时的中断函数:

    extern u8 _delayTimeOut;

    void TIM2_IRQHandler(void)
    {
        if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
        {
             _delayTimeOut = 1;
             TIM_ClearFlag(TIM2, TIM_FLAG_Update);
         }
    }

原来的一个思路是配置定时器每1ms就中断一次(TIMX->ARR值固定),在延时前将全局的延时计数器清零(该值在中断中不断累加),然后比较计数器值与欲延时的值,超过了就停止,就像这样:

    void delay1ms(u16 delayTime)
    {
        _delayTimer = 0; // 延时计数器

        TIM_Cmd(TIM2, ENABLE);
        while(_delayTimer < delayTime)
        {}
        TIM_Cmd(TIM2, DISABLE);
    }

    void TIM2_IRQHandler(void)
    {
        if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
        {
             _delayTimer++;
             TIM_ClearFlag(TIM2, TIM_FLAG_Update);
         }
    }