打印
[其他]

延时函数的实现方式有多少?

[复制链接]
108|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
yiy|  楼主 | 2025-3-31 17:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1. 阻塞式延时(忙等待)
(1) 空循环延时(软件延时)
原理:通过执行空循环占用 CPU 时间实现延时。

代码示例:
void delay_us(uint32_t us) {
  for (volatile uint32_t i = 0; i < us * 100; i++); // 根据时钟频率调整循环次数
}
优点:无需硬件支持,简单直接。

缺点:

精度低:受编译器优化、时钟频率影响。

浪费 CPU 资源:阻塞其他任务执行。

适用场景:简单裸机程序,对实时性要求不高。

(2) 定时器查询延时
原理:通过轮询定时器寄存器判断时间是否到达。

代码示例:
void delay_ms(uint32_t ms) {
  uint32_t start_time = TIMER->CNT;  // 假设 TIMER 是硬件定时器
  while ((TIMER->CNT - start_time) < (ms * 1000)); // 根据定时器频率计算
}
优点:比空循环更精确。

缺点:仍占用 CPU 资源,需配置定时器硬件。

使用特权

评论回复
沙发
yiy|  楼主 | 2025-3-31 17:47 | 只看该作者
2. 非阻塞式延时
(1) 定时器中断延时
原理:利用定时器中断触发延时结束事件。

代码示例:
volatile uint8_t delay_done = 0;

void TIMER_IRQ_Handler() {
  if (TIMER->SR & TIMER_FLAG_UPDATE) {
    delay_done = 1;
    TIMER->SR &= ~TIMER_FLAG_UPDATE;
  }
}

void delay_ms(uint32_t ms) {
  TIMER->ARR = ms * 1000;  // 设置定时器自动重装载值
  TIMER->CR1 |= TIMER_ENABLE;  // 启动定时器
  while (!delay_done);        // 等待中断标志
  delay_done = 0;
}
优点:释放 CPU 资源,可与其他任务并行执行。

缺点:需配置中断和定时器,代码复杂度稍高。

(2) 硬件定时器 + 非阻塞查询
原理:使用硬件定时器记录时间戳,通过差值计算是否超时。

代码示例:
uint32_t get_tick() {
  return TIMER->CNT;  // 获取当前定时器计数值
}

void delay_non_blocking(uint32_t start_tick, uint32_t delay_ticks) {
  while ((get_tick() - start_tick) < delay_ticks);
}

// 调用示例:
uint32_t start = get_tick();
delay_non_blocking(start, 1000); // 延时 1000 个定时器周期
优点:非阻塞,适合主循环中处理多任务。

缺点:需主动调用时间检查。

3. 高级延时方案
(1) SysTick 定时器(ARM Cortex-M 内核)
原理:利用 Cortex-M 内置的 SysTick 定时器实现精准延时。

代码示例:
void SysTick_Init() {
  SysTick->LOAD = SystemCoreClock / 1000 - 1; // 1ms 中断一次
  SysTick->VAL = 0;
  SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
}

void delay_ms(uint32_t ms) {
  uint32_t start = SysTick->VAL;
  while (ms--) {
    while (((start - SysTick->VAL) & 0xFFFFFF) >= (SystemCoreClock / 1000));
    start = SysTick->VAL;
  }
}
优点:高精度,与内核时钟同步。

缺点:依赖特定硬件(如 ARM Cortex-M)。

(2) RTOS 延时(如 FreeRTOS)
原理:利用实时操作系统(RTOS)的任务调度机制实现延时。

代码示例:
#include "FreeRTOS.h"
#include "task.h"

void task_function() {
  while (1) {
    vTaskDelay(pdMS_TO_TICKS(100)); // 延时 100ms
    // 执行其他任务
  }
}
优点:完全非阻塞,支持多任务并发。

缺点:需引入 RTOS,增加系统复杂度。

(3) PWM 或 DMA 硬件延时
原理:利用 PWM 输出或 DMA 传输自动控制延时(如生成精确脉冲)。

适用场景:需要硬件级精准延时的场景(如 WS2812 LED 驱动)。

4. 其他特殊实现
看门狗定时器:复用看门狗定时器实现超时检测(需谨慎使用)。

低功耗模式延时:在低功耗模式下使用 RTC 或低功耗定时器唤醒。

使用特权

评论回复
板凳
yiy|  楼主 | 2025-3-31 17:47 | 只看该作者
场景                                                推荐方案
简单裸机程序                                空循环或定时器查询
高精度需求                                硬件定时器(如 SysTick)
多任务系统                                RTOS 延时
低功耗场景                                RTC 或低功耗定时器 + 中断唤醒
硬件级精准控制(如 PWM)        专用硬件模块(PWM/DMA)

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

yiy

112

主题

1894

帖子

4

粉丝