在单片机项目开发过程中,经常会出现一个有趣的问题,即弄清楚如何延迟代码执行。有时,[单片机开发]人员可能只是希望有10微秒的延迟,以使I/O线在读取之前稳定下来,或者可能希望在两次读取之间指定的时间间隔使它反跳。在本文中,我们将探讨五种延迟代码执行的技术。
一、条件循环
第一种技术是使用条件循环(可能是最常用和最简单的)。条件循环延迟通常会使用for、while或do
while循环重复执行无操作(NOP)指令。例如:
for(int i = 0; i < 100000; i++)
{
__NOP();
}
条件延迟在紧要关头可能会很有用,但很难准确或有效。如果开发人员要针对其他操作模式(例如低功耗操作)调整时钟频率,则延迟时间将完全不同。另外,总会有一个问题,那就是到底有多长时间?有人可能会认为这是100000条指令,但是每次通过循环时,都会有其他指令来检查循环变量并递增i。这些时序循环对于在任何生产代码中使用来说都是不可预测的。
二、使用计时器
可以使用的第二种技术是利用单片机内置的硬件计时器。通常有几种不同的硬件计时器可用于跟踪系统时间,生成波形,捕获输入和通用。如果开发人员需要延迟(例如10微秒),则可以向硬件计时器加载表示10微秒的计数值。在这种情况下,计时器将设置为单次计时器。该代码将启动计时器并等待计时器溢出标志被设置,然后该标志将指示时间已过。
该代码类似于以下内容:
(DELAY_VALUE );
while(Timer_Expired ()== false
)
{
__NOP ();
}
这种技术比条件循环要强大得多。它还具有更高的灵活性,并且可以更轻松地针对所需的延迟时间进行调整。实际上,可以在整个代码中重用该API,以允许单个计时器用于所需的任何数量的延迟。
三、使用系统刻度(HAL示例)
在某些情况下,可能没有专用的硬件计时器。在这种情况下,单片机开发人员可以利用板载系统时钟来创建延迟。即使是裸机系统,通常也具有作为系统时钟的后台计时器,以便从单片机启动的那一刻起,软件就具有时间参考。通常,在典型系统中,将这些系统时钟设置为每1或10毫秒发生一次。
系统通常使用一些API,这些API允许开发人员访问当前的系统刻度,例如SysTick_Get()。开发人员可以利用此延迟来创建类似于以下内容的延迟:
TimeStart =
SysTick_Get();
do
{
TimeNow = SysTick_Get();
TimeDelta = TimeNow – TimeStart;
}while(TimeDelta < DelayTime);
单片机开发人员只需要确保如果他们这样做,就不会陷入计算问题或其他潜在问题中,因此应检查边界条件。
四、使用RTOS产量函数
在使用实时操作系统(RTOS)的更高级的系统中,开发人员可以利用内置的RTOS
API调用来产生创建延迟的任务。例如,如果开发人员正在使用FreeRTOS,则在他们的任务中他们可以使用如下代码:
VTaskDelay
(1);
此延迟功能将使任务产生一个RTOS滴答声的当前任务。取决于配置,RTOS滴答可以设置为1毫秒或10。使用这样的延迟机制可能会出现问题,因为任务将在该时间段内产生CPU,但不能保证一旦系统滴答时间到期,该任务将是最高优先级的任务!如果任务是准备运行的最高优先级任务,则该任务仅在延迟后立即运行,因此延迟时间可能会有些抖动。
五、使用RTOS对象
使用RTOS对象来延迟时间。如果你仔细查看自己喜欢的RTOS中的对象(例如信号量、互斥对象和队列)的API,你会注意到大多数等待等待的API调用还将包含延迟时间。此延迟时间也可导致应用程序延迟。
与RTOS对象相关的是,大多数RTOS都还包含软定时器。这些是基于软件的计时器,是从运行中的硬件计时器触发的。然后,可以将与上面第一、二点中显示的技术相似的技术与这些软计时器一起使用,以在代码执行中产生延迟。
单片机开发人员想要延迟代码执行,可以使用多种不同的技术,使用的技术将取决于系统中可用的软件和硬件资源。然后,开发人员可以决定他们要使用的解决方案的复杂程度。总之,肯定有很多种机制可以帮助将代码执行延迟一定的时间。
-
单片机
+关注
关注
6036文章
44556浏览量
635029 -
单片机开发
+关注
关注
3文章
460浏览量
19733
发布评论请先 登录
相关推荐
评论