基于tick的单片机delay写法分析

  接触单片机以来,遇到过形形色色的delay写法,分析下来,不外乎以下4种写法(拆成非阻塞来分析了,阻塞的话合并在一起就行,不废话)

1.减法判断

 1 uint32_t Tick_Bak0;
 2 uint32_t Tick_Delay0;
 3 void Test_Set_Delay0(uint32_t tick)
 4 {
 5     Tick_Delay0 = tick;
 6     Tick_Bak0 = Sys_Get_Tick();
 7 
 8     db_printf("\t%s(%u) , bakTick = %u\n", __FUNCTION__, tick, Tick_Bak0);
 9 }
10 
11 uint32_t Test_Is_Timeout0(void)
12 {
13     uint32_t curTick = Sys_Get_Tick();
14     if((curTick - Tick_Bak0) >= Tick_Delay0)
15     {
16         db_printf("[%010u] %s\n", curTick, __FUNCTION__);
17         return 1;
18     }
19     return 0;
20 }

 

2.加法判断

 1 uint32_t Tick_Bak1;
 2 uint32_t Tick_Delay1;
 3 void Test_Set_Delay1(uint32_t tick)
 4 {
 5     Tick_Delay1 = tick;
 6     Tick_Bak1 = Sys_Get_Tick();
 7 
 8     db_printf("\t%s(%u) , bakTick = %u\n", __FUNCTION__, tick, Tick_Bak1);
 9 }
10 
11 uint32_t Test_Is_Timeout1(void)
12 {
13     uint32_t curTick = Sys_Get_Tick();
14     if((0xFFFFFFFFU - Tick_Bak1) < Tick_Delay1)
15     {
16         if((Tick_Bak1 > curTick) && (curTick >= (Tick_Bak1 + Tick_Delay1)))
17         {
18             db_printf("[%010u] %s\n", curTick, __FUNCTION__);
19             return 1;
20         }
21     }
22     else
23     {
24         if(curTick >= (Tick_Bak1 + Tick_Delay1))
25         {
26             db_printf("[%010u] %s\n", curTick, __FUNCTION__);
27             return 1;
28         }
29     }
30 
31     return 0;
32 }

 

3.大于等于目标时刻判断

 1 uint32_t Tick_Bak2;
 2 uint32_t Tick_Target2;
 3 void Test_Set_Delay2(uint32_t tick)
 4 {
 5     Tick_Bak2 = Sys_Get_Tick();
 6     Tick_Target2 = Tick_Bak2 + tick;
 7 
 8     db_printf("\t%s(%u) , bakTick = %u\n", __FUNCTION__, tick, Tick_Bak2);
 9 }
10 
11 uint32_t Test_Is_Timeout2(void)
12 {
13     uint32_t curTick = Sys_Get_Tick();
14     if(Tick_Bak2 <= Tick_Target2)
15     {
16         if(curTick >= Tick_Target2)
17         {
18             db_printf("[%010u] %s\n", curTick, __FUNCTION__);
19             return 1;
20         }
21     }
22     else
23     {
24         if((curTick < Tick_Bak2) && (curTick >= Tick_Target2))
25         {
26             db_printf("[%010u] %s\n", curTick, __FUNCTION__);
27             return 1;
28         }
29     }
30 
31     return 0;
32 }

 

4.等于目标时刻判断

 1 uint32_t Tick_Target3;
 2 void Test_Set_Delay3(uint32_t tick)
 3 {
 4     uint32_t Tick_Bak3 = Sys_Get_Tick();
 5     Tick_Target3 = Tick_Bak3 + tick;
 6 
 7     db_printf("\t%s(%u) , bakTick = %u\n", __FUNCTION__, tick, Tick_Bak3);
 8 }
 9 
10 uint32_t Test_Is_Timeout3(void)
11 {
12     uint32_t curTick = Sys_Get_Tick();
13     if(curTick == Tick_Target3)
14     {
15         db_printf("[%010u] %s\n", curTick, __FUNCTION__);
16         return 1;
17     }
18 
19     return 0;
20 }

 

以上4种方法对比见下表:

代码写法 全局变量 执行效率排行1 风险
1.减法判断 8bytes 2 1.要延时的值接近0xFFFFFFFFU时,程序中一旦有大于对应差值的阻塞,GG
2.加法判断 8bytes 4

1.要延时的值接近0xFFFFFFFFU时,程序中一旦有大于对应差值的阻塞,GG

2.Tick_Bak1 + Tick_Delay1接近0xFFFFFFFFU时,程序中一旦有大于对应差值的阻塞,GG

3.大于等于目标时刻判断 8bytes 3

1.要延时的值接近0xFFFFFFFFU时,程序中一旦有大于对应差值的阻塞,GG

2.Tick_Target2接近0xFFFFFFFFU时,程序中一旦有大于对应差值的阻塞,GG

4.等于目标时刻判断 4bytes 1 1.程序中一旦有大于tick的阻塞,GG

[1]执行效率排行通过在STM32G431CB最小系统板上分别运行以上4种方式的延时代码,取消打印后,统计测试过程中Test_Is_Timeoutx的执行次数,次数越多,排行越低。具体程序:取1ms为tick的间隔,从tick为(0xFFFFFFFFU-3600000U)到3600000U期间,每1000ms设置一次时间为1000ms的延时,并一直查询是否timeout。

 

posted @ 2025-05-02 12:07  蓝bleu  阅读(50)  评论(0)    收藏  举报