在编程中经常需要精确的延时,或者需要精确的统计一段代码的执行时间,亦或者是需要精确的保证某段代码被调用的频率。比如需要统计某个函数的执行时间,从而判断开销,又比如在飞控中需要精确的保证每隔 2m 调用一次读取传感器的函数,可以使用定时器去实现。在 STM32 平台上,我们可以充分的利用 systick 去实现。
下边是源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| static volatile uint32_t sysTickMillis = 0; static uint32_t sysTickPerUs = 72;
static int systick_check_underflow(void) { return SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk; }
void SysTick_Handler(void) { __disable_irq(); systick_check_underflow(); sysTickMillis++; __enable_irq(); }
void systick_init(void) { sysTickPerUs = SystemCoreClock / 1000000; SysTick_Config(SystemCoreClock / 1000); }
uint32_t micros(void) { uint32_t cycle, timeMs;
do{ timeMs = sysTickMillis; cycle = SysTick->VAL; __ASM volatile("nop"); }while (timeMs != sysTickMillis);
if (systick_check_underflow()) { timeMs++; cycle = SysTick->VAL; }
return (timeMs * 1000) + (SysTick->LOAD + 1 - cycle) / sysTickPerUs; }
uint32_t millis(void) { return sysTickMillis; }
void delay_us(u32 us) { static int currentTime, lastTime = 0; lastTime= micros(); while(1) { currentTime= micros(); if ( currentTime - lastTime >= us ) { break; } } }
void delay_ms(u32 ms) { static int currentTime, lastTime = 0; lastTime= millis(); while(1) { currentTime= millis(); if( currentTime - lastTime >= ms ) { break; } } }
|
使用方法 :
在 main 函数中调用 systick_init() 进行初始化
调用 delay_us 函数实现 us 级延时
调用 delay_ms 函数实现 ms 级延时
计算代码的执行时间 :
1 2 3 4
| last = micro(); ... cur = micro(); usetime = cur - last;
|
在 FreeRTOS 下的移植
由于在 FreeRTOS 下,systick 被系统占用,因此不能直接使用该方式去实现,需要稍作修改。
A、 将原来的 sysTickMillis变量声明为全局变量, 以便于在其他地方可以调用
B、 将 systick_check_underflow();函数声明为外部,可以在port.c 中被调用
C、 删除原来的 Systick中断处理函数,并将函数中的处理代码添加到 port.c 的 xPortSysTickHandler 函数中即可
1 2
| systick_check_underflow(); sysTickMillis++;
|
D、删除 systick_init 函数
E、 micros 以及 delay_ms 等函数保持不变即可
————————————————
原文链接:https://blog.csdn.net/zhou0842/article/details/53574093