单片机FreeRTOS系统中,CPU计算的延时函数

在 FreeRTOS 系统中,如果需要实现一个 CPU 计算的延时函数(即忙等待延时,不释放 CPU 资源),通常不建议直接使用空循环来实现,因为这会导致 CPU 资源被浪费,无法让其他任务运行。FreeRTOS 是一个多任务系统,设计目标是高效利用 CPU 资源。

不过,如果你确实需要实现一个 短时间的 CPU 计算延时(例如在硬件初始化或某些特殊场景下),可以使用空循环来实现。以下是一个简单的实现方法:


1. 简单的 CPU 计算延时函数

复制代码
void cpu_delay_us(uint32_t microseconds) {
    uint32_t count = microseconds * (SystemCoreClock / 1000000); // 计算需要的循环次数
    for (volatile uint32_t i = 0; i < count; i++); // 空循环实现延时
}
  • 参数

    • microseconds:需要延时的微秒数。
  • 实现原理

    • 根据 CPU 的主频(SystemCoreClock)计算出需要执行的空循环次数。

    • 通过空循环占用 CPU 时间,实现延时。


2. 注意事项

  1. CPU 主频

    • SystemCoreClock 是 CPU 的主频(单位:Hz),需要根据具体的单片机型号和时钟配置设置。

    • 例如,如果 CPU 主频是 72MHz,则 SystemCoreClock = 72000000

  2. 延时精度

    • 这种延时方法的精度取决于 CPU 主频和编译器优化。

    • 如果编译器优化过高,可能会将空循环优化掉,导致延时失效。可以通过 volatile 关键字防止优化。

  3. 适用场景

    • 这种延时方法适用于 短时间的忙等待延时(通常不超过几毫秒)。

    • 对于较长的延时,建议使用 FreeRTOS 的 vTaskDelay()vTaskDelayUntil(),以避免浪费 CPU 资源。


3. 示例代码

以下是一个完整的示例代码,结合 FreeRTOS 任务和 CPU 计算延时:

复制代码
#include "FreeRTOS.h"
#include "task.h"
#include "stm32f4xx.h" // 假设使用 STM32F4 系列单片机

// CPU 计算延时函数
void cpu_delay_us(uint32_t microseconds) {
    uint32_t count = microseconds * (SystemCoreClock / 1000000); // 计算需要的循环次数
    for (volatile uint32_t i = 0; i < count; i++); // 空循环实现延时
}

// 任务函数
void vTaskExample(void *pvParameters) {
    while (1) {
        // 任务逻辑
        printf("Task is running...\n");

        // CPU 计算延时 1000us(1ms)
        cpu_delay_us(1000);

        // 使用 FreeRTOS 延时函数延时 1000ms(1秒)
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

int main(void) {
    // 初始化系统时钟
    SystemCoreClockUpdate();

    // 创建任务
    xTaskCreate(vTaskExample, "TaskExample", configMINIMAL_STACK_SIZE, NULL, 1, NULL);

    // 启动调度器
    vTaskStartScheduler();

    // 如果调度器启动失败,进入死循环
    for (;;);
}

4. 替代方案

如果不需要精确的 CPU 计算延时,建议使用 FreeRTOS 提供的延时函数(如 vTaskDelay()vTaskDelayUntil()),这些函数会让出 CPU 资源,供其他任务运行。

例如:

复制代码
vTaskDelay(pdMS_TO_TICKS(1)); // 延时 1ms

5. 总结

  • CPU 计算延时函数适用于 短时间的忙等待延时,但会浪费 CPU 资源。

  • 在 FreeRTOS 中,建议优先使用 vTaskDelay()vTaskDelayUntil() 实现延时。

  • 如果需要精确的短时间延时,可以使用空循环实现,但要注意防止编译器优化。

相关推荐
天月风沙15 分钟前
PX4 | 无人机关闭磁力计罗盘飞行(yaw estimate error报错解决方法)
单片机·嵌入式硬件·mcu·无人机
int型码农2 小时前
数据结构第八章(二)-交换排序
c语言·数据结构·算法·排序算法
计蒙不吃鱼3 小时前
星闪开发之Server-Client 指令交互控制红灯亮灭案例解析(SLE_LED详解)
嵌入式硬件·物联网·iot·星闪·星闪开发
想搞嵌入式的小白4 小时前
STM32 NVIC中断控制器
stm32·单片机·嵌入式硬件·nvic
A-花开堪折4 小时前
Android7 Input(十)View 处理Input事件pipeline
android·嵌入式硬件
深圳市尚想信息技术有限公司5 小时前
【深尚想】OPA855QDSGRQ1运算放大器IC德州仪器TI汽车级高速8GHz增益带宽的全面解析
单片机·嵌入式硬件
陕西艾瑞科惯性技术有限公司5 小时前
让飞行姿态 “可感知”:为什么无人机需要三轴陀螺仪?
嵌入式硬件·机器学习·机器人·无人机·pcb工艺
代码总长两年半5 小时前
STM32----IAP远程升级
stm32·单片机·嵌入式硬件
广药门徒6 小时前
STM32手册上标称的18MHz GPIO翻转速度和你实际测量到的速度之间的差异是预期之内且合理的
单片机·嵌入式硬件
广药门徒6 小时前
在使用一些不用驱动大电流的设备就可以用stm32的自己的上下拉但是本身上下拉不就是给iicspi这些他通信给信号的吗中怎么还跟驱动能力扯上了有什么场景嘛
stm32·单片机·fpga开发