如何在定时器中添加延迟时间

2024-12-31

摘要:1. 单片机(以STM32为例,使用SysTick定时器) 在单片机编程中,特别是使用STM32系列微控制器时,可以通过配置SysTick定时器来实现微秒级别的延迟。SysTick是一个内置于CortexM内核的系统定时器,可以...

1. 单片机(以STM32为例,使用SysTick定时器)

在单片机编程中,特别是使用STM32系列微控制器时,可以通过配置SysTick定时器来实现微秒级别的延迟。SysTick是一个内置于CortexM内核的系统定时器,可以方便地用于生成精确的延时。以下是一个基于SysTick的延时函数示例:

```c

define SYSTEM_FQ 120000000 // 假设系统时钟频率为120MHz

define LOAD_CORRECT 37 // 修正值,用于抵消寄存器操作和判断时间

void delay_us(int count) {

SysTick>LOAD = count (SYSTEM_FQ / 1000000) LOAD_CORRECT; // 设置重装载值

SysTick>VAL = 0; // 清零计数器

SysTick>CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk; // 使能定时器

while (!((SysTick>CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0)); // 等待计数完成

SysTick>CTRL &= (~SysTick_CTRL_ENABLE_Msk); // 延时后关闭定时器

```

这个函数通过调整`LOAD`寄存器的值来设定延时时间,但需要注意的是,实际延时会受到CPU执行其他指令(如寄存器操作、判断等)的影响,因此需要通过实验或计算来确定一个合适的修正值。

2. Qt/QEventLoop(C++环境)

在基于Qt的应用中,可以利用`QEventLoop`和`QTimer`来实现非阻塞式的延迟执行。以下是一个简单的例子:

```cpp

QEventLoop loop;

QTimer timer;

如何在定时器中添加延迟时间

connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit);

timer.start(1000); // 设置延时时间为1000毫秒

loop.exec();

```

这段代码通过启动一个定时器并连接到`QEventLoop`的退出槽,当定时器触发时,事件循环结束,从而达到延迟执行的目的。

3. JavaScript环境

在JavaScript中,标准的`setTimeout`函数可以用来添加延迟,但存在最小延迟时间的问题(通常至少4ms)。为了实现接近零延迟的定时器,可以利用`window.postMessage`方法:

```javascript

(function() {

var timeouts = [];

var messageName = "zerotimeoutmessage";

function setZeroTimeout(fn) {

timeouts.push(fn);

window.postMessage(messageName, "");

window.addEventListener("message", function(event) {

if (event.source == window && event.data == messageName) {

event.stopPropagation();

if (timeouts.length > 0) {

timeouts.shift()();

}, true);

})();

// 使用时

setZeroTimeout(function() {

console.log("立即执行");

});

```

这种方法通过消息传递机制绕过了`setTimeout`的最小延迟限制,提供了更接近即时执行的体验。

以上就是在不同场景下添加延迟时间的几种方法,每种方法都有其适用的环境和限制条件。

相关推荐