单片机延时函数怎么写?精准延时技巧揭秘

2025-09发布5次浏览

单片机延时函数是嵌入式系统中常用的一种功能,用于控制程序执行的时间间隔。延时函数的实现方法有很多种,包括软件延时和硬件延时。下面详细介绍几种常见的延时函数实现方法,并揭示一些精准延时的技巧。

软件延时

1. 空循环延时

最简单的延时方法是通过空循环实现。这种方法简单但不够精确,因为延时的长度会受到单片机执行其他任务的影响。

void delay_ms(uint16_t ms) {
    uint16_t i, j;
    for (i = 0; i < ms; i++) {
        for (j = 0; j < 123; j++) {
            __NOP(); // 插入空操作
        }
    }
}

2. 查表延时

查表延时是通过预先计算好延时时间的表格来实现延时,这种方法比空循环延时更精确。

uint16_t delay_table[1000];
void init_delay_table() {
    for (uint16_t i = 0; i < 1000; i++) {
        delay_table[i] = i * 123; // 预先计算延时值
    }
}

void delay_ms(uint16_t ms) {
    if (ms < 1000) {
        while (__get与时计数器() - delay_table[ms] > 0);
    }
}

硬件延时

1. 使用定时器

定时器是实现精准延时的常用方法。大多数单片机都内置了定时器,可以通过设置定时器的重载值来实现延时。

void delay_ms(uint16_t ms) {
    TIM_SetCounter(0); // 将定时器计数器清零
    TIM_SetPeriod(ms * TIM_GetClockFrequency() / 1000 - 1); // 设置定时器重载值
    while (!TIM_GetFlagStatus(TIM_FLAG_UPDATE)); // 等待定时器溢出
    TIM_ClearFlag(TIM_FLAG_UPDATE); // 清除定时器溢出标志
}

精准延时技巧

1. 关闭中断

在执行延时函数时关闭中断可以减少其他任务对延时精度的影响。

void delay_ms(uint16_t ms) {
    __disable_irq(); // 关闭中断
    TIM_SetCounter(0); // 将定时器计数器清零
    TIM_SetPeriod(ms * TIM_GetClockFrequency() / 1000 - 1); // 设置定时器重载值
    while (!TIM_GetFlagStatus(TIM_FLAG_UPDATE)); // 等待定时器溢出
    TIM_ClearFlag(TIM_FLAG_UPDATE); // 清除定时器溢出标志
    __enable_irq(); // 开启中断
}

2. 使用高精度定时器

一些单片机支持高精度定时器,可以选择更高频率的时钟源来提高延时的精度。

3. 避免在延时函数中执行复杂操作

在延时函数中执行复杂的操作会降低延时的精度,尽量保持延时函数的简单性。