OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2222|回复: 5

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

[复制链接]

31

主题

81

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
329
金钱
329
注册时间
2016-6-5
在线时间
53 小时
发表于 2019-6-15 18:13:39 | 显示全部楼层 |阅读模式
1金钱
如何使用Stm32f103系列单片机中的普通定时器写准确延时函数,延时最小步进1ms,能够给出详细程序和备注最好?能给出详细程序并注释最好

最佳答案

查看完整内容[请看2#楼]

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); ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

31

主题

81

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
329
金钱
329
注册时间
2016-6-5
在线时间
53 小时
 楼主| 发表于 2019-6-15 18:13:40 | 显示全部楼层
本帖最后由 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循环里面程序自减消耗时间,时钟信号的不稳定,以及其他的一些软、硬件原因。由此可以延伸到原子哥用滴答定时器写的延时函数误差最大是多少?滴答定时器与普通定时器的定时函数有哪些优缺点等。。。
欢迎大家进一步讨论
回复

使用道具 举报

31

主题

1955

帖子

3

精华

论坛元老

Rank: 8Rank: 8

积分
4524
金钱
4524
注册时间
2018-5-11
在线时间
947 小时
发表于 2019-6-15 20:39:48 | 显示全部楼层
/**
* @brief TIM3 定时器3初始化函数
该定时器用于系统计数,配置为每ms中断一次
* @param none
* @return none
*/

#define    bSYS_TIMERx        bTIM3
void timerInit(void)
{
    u16 arr = 7199;
    u16 psc = 9;

    Enable_DEVx_CLK(bSYS_TIMERx,1); //Clock enable

    //Timer TIM3 init
                pTIM(bSYS_TIMERx)->ARR=arr; //预分频值10,即时钟频率为7200000,即时钟周期为1/7200k (s)          
                pTIM(bSYS_TIMERx)->PSC=psc; //溢出时间为7200计数次,即溢出时间为7200次* 1/7200k (s)=1ms        
       
    SET_TIM_CR_CKD(bSYS_TIMERx,0); //Set the clock split:TDTS = Tck_tim

                bTIM_CR_DIR(bSYS_TIMERx)= 0;//向上计数 (TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;)
                bTIM_DIER_UIE(bSYS_TIMERx)=1;//允许TIM3溢出(更新)中断(TIM_ITConfig(TIMER, TIM_IT_Update,ENABLE );)

//设置中断优先级(集中放在主程序的MX_NVIC_Init()函数中设置)

    bTIM_CR_CEN(bSYS_TIMERx)=1;//打开定时器(TIM_Cmd(TIMER, ENABLE);)  
               
}
我的开源链接 https://github.com/ShuifaHe/STM32.git  请关注,点赞支持哦。
回复

使用道具 举报

31

主题

1955

帖子

3

精华

论坛元老

Rank: 8Rank: 8

积分
4524
金钱
4524
注册时间
2018-5-11
在线时间
947 小时
发表于 2019-6-15 20:46:22 | 显示全部楼层
/**
* @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--;
   }
}
我的开源链接 https://github.com/ShuifaHe/STM32.git  请关注,点赞支持哦。
回复

使用道具 举报

31

主题

1955

帖子

3

精华

论坛元老

Rank: 8Rank: 8

积分
4524
金钱
4524
注册时间
2018-5-11
在线时间
947 小时
发表于 2019-6-15 21:03:04 | 显示全部楼层
延时函数
void MyDelay(u16 tim)
{
DelayTime=tim;
while(DelayTime);
}
不过,一般不建议使用这种笨拙的死等延时的方法,
而是在循环中类似这样使用:
DelayTime=xx;  //先设延时时间
if(!DelayTime) DoWork1(); //延时时间到,做工作1
else DoWork2();    //延时时间未到,做工作2

我的开源链接 https://github.com/ShuifaHe/STM32.git  请关注,点赞支持哦。
回复

使用道具 举报

31

主题

1955

帖子

3

精华

论坛元老

Rank: 8Rank: 8

积分
4524
金钱
4524
注册时间
2018-5-11
在线时间
947 小时
发表于 2019-6-15 21:07:08 | 显示全部楼层
请原谅我在上面的代码中使用了我自编的头文件,参见此帖
http://www.openedv.com/forum.php?mod=viewthread&tid=294788
我的开源链接 https://github.com/ShuifaHe/STM32.git  请关注,点赞支持哦。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-26 18:39

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表