已剪辑自: https://mp.weixin.qq.com/s/-RPLQn4KO9Aqu1fpfZeOKA
前不久有个读者在问关于延时的问题,大概就是问:软件延时和硬件延时是啥意思?做项目时他俩有什么区别?
今天就来讲讲关于硬件延时和软件延时的内容,以及它们的区别。
延时的种类很多,先给大家普及一下延时相关概念和分类。
指利用具有计数功能的硬件进行延时。
比如:定时器(Timer)、 实时时钟(RTC)、 系统滴答定时器(SysTick)等具有计数功能的硬件。
相对硬件延时而言,软件延时就是写一段软件代码,通过消耗CPU时间进行延时。
比如软件延时函数:
void Delay(uint32_t Cnt){ uint32_t i;
while(Cnt--) { for(i=0; i<0x80000; i++); }}
实际应用中,延时分阻塞和非阻塞延时。
指CPU一直停留阻塞,不去做其它事情,直到延时结束结束。
像上面那个软件延时(Delay)就是一个典型的阻塞延时,一直消耗CPU,直到延时结束。
指在延时期间,没有阻塞CPU,也就是说CPU在延时期间可以执行其它代码。
比如:利用定时器中断延时,只需要开启定时器,在中断(计数)到来之前,CPU可以执行其它代码。
a.利用定时器也能实现阻塞延时,比如STM32的HAL自带的阻塞延时:
__weak void HAL_Delay(uint32_t Delay){ uint32_t tickstart = HAL_GetTick(); uint32_t wait = Delay;
/* Add a freq to guarantee minimum wait */ if (wait < HAL_MAX_DELAY) { wait += (uint32_t)(uwTickFreq); }
while ((HAL_GetTick() - tickstart) < wait) { }}
b.利用RTOS自带的系统延时实现非阻塞延时,这个实现原理实际是利用了硬件延时(系统滴答定时器)。
当然,这个延时的原理(延时函数代码)相对比较复杂,对于普通用户只需要知道如何调用以及简单原理即可,感兴趣的老铁可以自行研究一下。
通常在一些RTOS的(Demo)例子的任务中都有系统延时,比如ucos非阻塞延时:
OSTimeDly(10);
再比如FreeRTOS非阻塞延时:
vTaskDelay(10);
关于RTOS的延时,这里额外拓展一下关于RTOS中的相对延时和绝对延时的内容,请移步至文章《RTOS中相对延时和绝对延时的区别》
通过以上分析,其实不难得出,硬件延时相对软件延时更普遍。
1.软件相对硬件延时精度更差;
2.软件延时为阻塞延时,硬件延时可阻塞,也可非阻赛延时;
3.硬件延时应用更灵活、更广泛;
已剪辑自: https://mp.weixin.qq.com/s?__biz=MzI4MDI4MDE5Ng==&mid=2247513149&idx=2&sn=90586ddd99a0871745e5e57c3a6b1cfb&chksm=ebb819d6dccf90c008aeb35e6de7eb24f9ec39c8d7ae27b8613f89822a626f942fb8d3482c3d&scene=21#wechat_redirect
嵌入式软件代码中延时是很常见的,只是延时种类有很多,看你用什么延时。
**问题:**周期性(固定一个时间)去处理某一件事情。你会通过什么方式去实现?
比如:间隔10ms去采集传感器的数据,然后通过一种算法计算出一个结果,最后通过串口发送出去。
可能对于很多习惯裸机编程的读者,首先想到的是:利用定时器,定时10ms中断,在中断里面处理。
中断函数适合处理简单数据,不适合算法、通信等需要长时间占用CPU的处理。
对计时精度要求比较高的地方适合定时器,像本章节说的周期性采集传感器数据,要求不适合很高,那么就引入本文说的绝对延时。
在实时操作系统FreeRTOS任务中,利用vTaskDelayUntil绝对延时即可完美解决这个问题。
本文拿FreeRTOS中相对延时函数vTaskDelay,绝对延时函数vTaskDelayUntil来说明。
**相对延时:**指每次延时都是从执行函数vTaskDelay()开始,直到延时指定的时间(参数:滴答值)结束。
**绝对延时:**指每隔指定的时间(参数:滴答值),执行一次调用vTaskDelayUntil()函数的任务。
文字描述可能不够直观理解,下面章节结合代码例子、延时值(IO高低变化波形)、任务执行图来详细讲述一下他们的区别。