我正在关注Keil的CMSIS-RTOS Tutorial。它提供了以下方法来放置亚毫秒延迟:
部分:亚毫秒延迟
int32_t tick,delayPeriod; tick = osKernelSysTick(); // get start value of the Kernel system tick // Then we can scale a period in microseconds to a SysTick count value delayPeriod = osKernelTickMicroSec(100)); // This then allows us to create a delay for the the required period. do { // Delay for 100 microseconds } while ((osKernelSysTick() - tick) < delayPeriod);
osKernelSysTick()返回滚动32位计数器的值;此实现不适合该值的环绕。
如果发生环绕,则无法实现预期的延迟。这是官方Keil文档中的错误还是我遗漏了什么?
答案 0 :(得分:3)
由于算术运算的方式,您显示的实现不能满足环绕性。
do { // Delay for 100 microseconds
} while ((osKernelSysTick() - tick) < delayPeriod);
当计时器换行时,这会导致算术溢出。
如果您使用unsigned
变量并计算之前的缩短时间将其与所需的时间进行比较,您将避免这种情况。 C标准保证无符号变量可以包装。
uint32_t tick, delayPeriod, elapsed; // unsigned
tick = osKernelSysTick();
delayPeriod = osKernelTickMicroSec(100));
do {
elapsed = osKernelSysTick() - tick; // separate arithmetic wraps cleanly
} while (elapsed < delayPeriod);
请注意,该函数无论如何都定义为uint32_t osKernelSysTick
,因此使用签名类型时原始示例不正确。