没事逛荡 发表于 2016-10-9 21:42:56

关于延时的实现

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


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

黑皮男 发表于 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)的时间间隔相同(总体来说相同)。
页: [1] 2
查看完整版本: 关于延时的实现