如何使用Stm32f103系列单片机中的普通定时器写准确延时函数

2019-07-20 23:45发布

如何使用Stm32f103系列单片机中的普通定时器写准确延时函数,延时最小步进1ms,能够给出详细程序和备注最好?能给出详细程序并注释最好
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
5条回答
247470035
1楼-- · 2019-07-21 02:00
本帖最后由 247470035 于 2019-6-17 12:45 编辑

void TIM3_Init(void)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
   
    /* 定时器初始化配置 */         
    TIM_TimeBaseStructure.TIM_Period = 999;   
    TIM_TimeBaseStructure.TIM_Prescaler = 71;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
   
    TIM_ARRPreloadConfig(TIM3, ENABLE);
   
    /* 设置更新请求源只在计数器上溢或下溢时产生中断 */
    TIM_UpdateRequestConfig(TIM3,TIM_UpdateSource_Global);
    TIM_ClearFlag(TIM3, TIM_FLAG_Update);
}

/**
  * @brief   ms延时程序,1ms为一个单位
  * @param  
  * @arg nTime: Delay_ms( 10 ) 则实现的延时为 10 * 1ms = 10ms
  * @retval  无
  */
void Delay_mss(vu32 nTime)
{     
    /* 清零计数器并使能定时器 */  
    TIM3->CNT   = 0;  
    TIM_Cmd(TIM3, ENABLE);     

    for( ; nTime > 0 ; nTime--)
    {
     /* 等待一个延时单位的结束 */
     while(TIM_GetFlagStatus(TIM3, TIM_FLAG_Update) != SET);
     TIM_ClearFlag(TIM3, TIM_FLAG_Update);
    }

    TIM_Cmd(TIM3, DISABLE);
}

另需要设计定时器3的中断优先级
程序经本人亲自测试,没有问题,此处不再赘述此处可以进一步探讨定时器在循环过程中的误差会是多大?误差的原因有,while循环里面程序自减消耗时间,时钟信号的不稳定,以及其他的一些软、硬件原因。由此可以延伸到原子哥用滴答定时器写的延时函数误差最大是多少?滴答定时器与普通定时器的定时函数有哪些优缺点等。。。
欢迎大家进一步讨论
warship
2楼-- · 2019-07-21 03:48
 精彩回答 2  元偷偷看……
warship
3楼-- · 2019-07-21 08:55
/**
* @brief TIM3 定时器3中断处理程序
*/
#define SYS_TIMER_IRQ_FUN                         TIM3_IRQHandler        //定时器中断服务函数名称
volatile u16 DelayTime;   //volatile是为了防止编译器进行优化
void SYS_TIMER_IRQ_FUN(void)
{
        if(bTIM_SR_UIF(bSYS_TIMERx)) //如果发生溢出中断(每毫秒1次)
   {
    bTIM_SR_UIF(bSYS_TIMERx)=0;
   if(DelayTime)DelayTime--;
   }
}
warship
4楼-- · 2019-07-21 09:55
 精彩回答 2  元偷偷看……
warship
5楼-- · 2019-07-21 12:06
请原谅我在上面的代码中使用了我自编的头文件,参见此帖
http://www.openedv.com/forum.php?mod=viewthread&tid=294788

一周热门 更多>