请选择 进入手机版 | 继续访问电脑版

你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

关于延时的实现

[复制链接]
没事逛荡 提问时间:2016-10-9 21:42 /
单片机裸机系统中,常用的延时操作有不少。1、for()循环延时等待。这样的操作最简单,但单片机的工作效率最低,而且可能会错过其他比较重要的操作,影响功能的实现。
2、定时器延时+for()循环延时。给每个延时较长的操作使用定时器判断,较短的延时仍然用for()循环延时。代码写起来比较麻烦,可读性也不好。
3、纯定时器延时。每个延时都用定时器处理。


是否有其他更好的实现方式?

收藏 1 评论12 发布时间:2016-10-9 21:42

举报

12个回答
黑皮男 回答时间:2016-10-9 23:27:37
可参考如下代码,在main中做一个每10ms或是自定义的循环函数,这个循环函数的建立,需借助一个定时器做系统滴答定时器,以此来计算main函数的循环周期。

//在定时器中断中调用,定时器周期可设定为1ms中断
void vSysTickInc(void){
        ulSysTick++;

        if(0==ulSysTick%LOOP_TICK){
                SET_SYSREG(REG_LOOPTICK);       
        }
}

main(){
        while (1)
        {

                if(READ_SYSREG(REG_LOOPTICK)){
                        CLEAR_SYSREG(REG_LOOPTICK);
               
                       if(ucDescrementChar(&ucPowerTimer)){
                         //此处延时到后才会执行
                        
                         }
       
                }
        }
}



UINT8_T ucDescrementChar(UINT8_T *p_ucVal){
        UINT8_T ucRes = 0;

        if((*p_ucVal)!=0){
                (*p_ucVal)--;
                if((*p_ucVal)==0){
                        ucRes = 1;
                }
        }
       
        return ucRes;
}
高二毛 回答时间:2016-10-10 08:35:37
裸跑的时候,可以用st的系统时钟。
如果要求延时精度比较严格,就得用心规划一下了。
大部分的需求都是10ms+的延时,问题不大。
anywill 回答时间:2016-10-10 10:30:10
mbed最简单
int main() {
    mytimer.start();
    btn.fall(&fallfunc);
    //按键上升沿读取当前时间
    btn.rise(&risefunc);
    //下降沿再次读取当前时间并输出时间间隔
    while (1);
}
没事逛荡 回答时间:2016-10-13 09:13:44
黑皮男 发表于 2016-10-9 23:27
可参考如下代码,在main中做一个每10ms或是自定义的循环函数,这个循环函数的建立,需借助一个定时器做系统 ...

可能描述不大清楚。
我是想用一种方式代替for()循环延时,在延时的过程中还可以处理其它的流程,类似于操作系统的样子,在代码中会出现多次这样的延时。只是想用在裸机上面。
没事逛荡 回答时间:2016-10-13 09:14:17
高二毛 发表于 2016-10-10 08:35
裸跑的时候,可以用st的系统时钟。
如果要求延时精度比较严格,就得用心规划一下了。
大部分的需求都是10ms ...

可能描述不大清楚。
我是想用一种方式代替for()循环延时,在延时的过程中还可以处理其它的流程,类似于操作系统的样子,在代码中会出现多次这样的延时。只是想用在裸机上面。
精度问题,倒是其次了。
没事逛荡 回答时间:2016-10-13 09:14:36
laiyingjie 发表于 2016-10-10 09:31
由于我使用的是STM32CubeMX配置的HAL库,所以裸机中用到的是HAL_Delay(1000);延时1秒 ...

可能描述不大清楚。
我是想用一种方式代替for()循环延时,在延时的过程中还可以处理其它的流程,类似于操作系统的样子,在代码中会出现多次这样的延时。只是想用在裸机上面。
没事逛荡 回答时间:2016-10-13 09:16:18
anywill 发表于 2016-10-10 10:30
mbed最简单
int main() {
    mytimer.start();

可能描述不大清楚。
我是想用一种方式代替for()循环延时,在延时的过程中还可以处理其它的流程,类似于操作系统的样子,在代码中会出现多次这样的延时。只是想用在裸机上面。
mbed没用过,有空去看一下。看代码,像是获取间隔?和讨论的问题,不大相关呢...
废鱼 回答时间:2016-10-13 10:03:42
用定时器判断,例如:
if(t-t1>=1000)
{
   处理程序
}
黑皮男 回答时间:2016-10-13 15:07:44
没事逛荡 发表于 2016-10-13 09:13
可能描述不大清楚。
我是想用一种方式代替for()循环延时,在延时的过程中还可以处理其它的流程,类似于操 ...

我提供的就是这样一种方式,ucDescrementChar(&ucPowerTimer)的参数是一个全局变量,用来做自减操作,直到减为0,即为延时终止,执行if(ucDescrementChar(&ucPowerTimer))条件语句满足时刻的代码。if()条件满足内的代码即为延时时间到后需要执行的,这个是用if判断时候延时结束,所以不影响延时外部的代码执行,也就是说没有阻塞整个程序的执行。但是你需要提供一个时基,确保每次调用ucDescrementChar(&ucPowerTimer)的时间间隔相同(总体来说相同)。
mark0668 回答时间:2016-10-13 15:17:10
方法很多
zbber 回答时间:2016-10-13 16:37:19
裸跑的时候,可以用st的系统时钟
anywill 回答时间:2016-10-13 20:16:12
本帖最后由 anywill 于 2016-10-13 20:34 编辑

补充,中断省事,不过mbed最简单易懂 一句wait();就行
或者period();

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版