摘要: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`的最小延迟限制,提供了更接近即时执行的体验。
以上就是在不同场景下添加延迟时间的几种方法,每种方法都有其适用的环境和限制条件。