单片机
返回首页

STM32用定时器精确延时的方法(非SysTick)

2016-10-18 来源:eefocus

用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);
         }
    }

进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 家用电源无载自动断电装置的设计与制作

  • 短波AM发射器电路设计图

  • 带有短路保护系统的5V直流稳压电源电路图

  • 如何调制IC555振荡器

  • 基于ICL296的大电流开关稳压器电源电路

  • 基于TDA2003的简单低功耗汽车立体声放大器电路

    相关电子头条文章