OpenEdv-开源电子网

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

长时间延时

[复制链接]

1

主题

3

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2015-9-17
在线时间
2 小时
发表于 2018-11-29 14:53:41 | 显示全部楼层 |阅读模式
近客户须要把延时时间长到120S,而delay_ms()只能延时1.86S。为了达到长延时效果,自己重新写了个函数分享给大家一起学习与改进,此延时函数精度不是很高。
void LongDelay_ms(u32 delay)
{
   u32 Remainder;
   if (delay > 1000)
  {
     Remainder = delay % 1000;//先延时余数
     if (Remainder)
       delay_ms(Remainder);
     delay -= Remainder; //减除余数
     for (; delay >= 1000; delay -= 1000)
     {  
       IWDG_ReloadCounter();//最大间隔时间为1.86S 所以1.86S内必须喂狗
       delay_ms(1000);
     }
     
   }
else
   {
     delay_ms(BackTime);
   }
}
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

3

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2015-9-17
在线时间
2 小时
 楼主| 发表于 2018-11-29 14:58:57 | 显示全部楼层
void LongDelay_ms(u32 delay)
{
    u32 Remainder;
    if (delay > 1000)
   {
      Remainder = delay % 1000;//先延时余数
     if (Remainder)
        delay_ms(Remainder);
      delay -= Remainder; //减除余数
     for (; delay >= 1000; delay -= 1000)
      {  
        IWDG_ReloadCounter();//最大间隔时间为1.86S 所以1.86S内必须喂狗
       delay_ms(1000);
      }
      
    }
else
    {
      delay_ms(delay);
    }
}
回复 支持 反对

使用道具 举报

51

主题

2166

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10653
金钱
10653
注册时间
2017-4-14
在线时间
2780 小时
发表于 2018-11-29 18:58:04 | 显示全部楼层
多逛逛论坛吧

static   u8  fac_us=0;                                                             //us延时倍乘数       
//SYSTICK的时钟固定为HCLK时钟的1/8
//中断时间time  =  ( SysTick->LOAD + 1 ) / f                        f = AHB或AHB/8            (9000-1+1)/9M=1ms
void delay_init(void)
{
        //NVIC_SetPriority (SysTick_IRQn, x);默认是NVIC_SetPriority (SysTick_IRQn,15);
        SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);        //选择外部时钟  HCLK/8  9M 计数器减1为1/9000000秒
        fac_us=SystemCoreClock/8000000;                                                //9  
        SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;                     //开启SYSTICK中断
        SysTick->LOAD=fac_us*1000-1;                                                               //每1/1000s中断一次       
        SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;                     //开启SYSTICK          
}       

//nus:0~2^32/fac_us=477218588.444us=477s        (fac_us=9)                                                                  
void delay_us(u32 nus)
{               
        u32 ticks;
        u32 told,tnow,tcnt=0;
        u32 reload=SysTick->LOAD;                                                            //LOAD的值                     
        ticks=nus*fac_us;                                                                               //需要的节拍数                           
        tcnt=0;
        told=SysTick->VAL;                                                                  //刚进入时的计数器值
        while(1)
        {
                tnow=SysTick->VAL;       
                if(tnow!=told)
                {            
                        if(tnow<told)tcnt+=told-tnow;                                  //这里注意一下SYSTICK是一个递减的计数器就可以了.
                        else tcnt+=reload-tnow+told;            
                        told=tnow;
                        if(tcnt>=ticks)break;                                                      //时间超过/等于要延迟的时间,则退出.
                }  
        }       
}

回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-7-2 11:23

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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