在stm32的freeRTOS上进行微秒级延时(HAL库)

本文介绍了一种在STM32上实现微秒级延时的方法,利用DWT模块提供精确的时间延迟,适用于FreeRTOS环境下需要高精度延时的应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

因为时间片的原因freeRTOS自身貌似无法进行微秒级的延时,实测通过以下函数可以进行微秒级的消息

dwt_stm32_delay.h
#ifndef DWT_STM32_DELAY_H
#define DWT_STM32_DELAY_H

#ifdef __cplusplus
extern "C" {
#endif

#include "stm32f4xx_hal.h"

/**
 * @brief  Initializes DWT_Cycle_Count for DWT_Delay_us function
 * @return Error DWT counter
 *         1: DWT counter Error
 *         0: DWT counter works
 */
uint32_t DWT_Delay_Init(void);

/**
 * @brief  This function provides a delay (in microseconds)
 * @param  microseconds: delay in microseconds
 */
__STATIC_INLINE void DWT_Delay_us(volatile uint32_t microseconds)
{
  uint32_t clk_cycle_start = DWT->CYCCNT;

  /* Go to number of cycles for system */
  microseconds *= (HAL_RCC_GetHCLKFreq() / 1000000);

  /* Delay till end */
  while ((DWT->CYCCNT - clk_cycle_start) < microseconds);
}

#ifdef __cplusplus
}
#endif

#endif
dwt_stm32_delay.c
#include "dwt_stm32_delay.h"

/**
 * @brief  Initializes DWT_Clock_Cycle_Count for DWT_Delay_us function
 * @return Error DWT counter
 *         1: clock cycle counter not started
 *         0: clock cycle counter works
 */
uint32_t DWT_Delay_Init(void) {
  /* Disable TRC */
  CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk; // ~0x01000000;
  /* Enable TRC */
  CoreDebug->DEMCR |=  CoreDebug_DEMCR_TRCENA_Msk; // 0x01000000;

  /* Disable clock cycle counter */
  DWT->CTRL &= ~DWT_CTRL_CYCCNTENA_Msk; //~0x00000001;
  /* Enable  clock cycle counter */
  DWT->CTRL |=  DWT_CTRL_CYCCNTENA_Msk; //0x00000001;

  /* Reset the clock cycle counter value */
  DWT->CYCCNT = 0;

     /* 3 NO OPERATION instructions */
     __ASM volatile ("NOP");
     __ASM volatile ("NOP");
  __ASM volatile ("NOP");

  /* Check if clock cycle counter has started */
     if(DWT->CYCCNT)
     {
       return 0; /*clock cycle counter started*/
     }
     else
  {
    return 1; /*clock cycle counter not started*/
  }
}
main.c
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"
#include "dwt_stm32_delay.h"

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
  MX_GPIO_Init();

  /* USER CODE BEGIN 2 */

  if(DWT_Delay_Init())
  {
    Error_Handler(); /* Call Error Handler */
  }

  while(1)
  {
    /* 10s Delay */
    DWT_Delay_us(10000000);

    HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
  }
}

亲测,通过修改stm32f4xx_hal.h头文件为stm32f1xx_hal.h,
f1系列也适应

### STM32 HAL 延时函数使用方法 #### 函数介绍 STM32 HAL 提供了一组用于实现精确延时的函数。主要分为两类:于滴答定器(SysTick)的毫秒级延时 `HAL_Delay` 和更精细的间控制,如微秒级别的延时。 对于毫秒级别延时,可以使用 `HAL_Delay()` 函数[^1]: ```c void HAL_Delay(uint32_t Delay); ``` 此函数会阻塞当前线程直到指定间过去为止。参数 `Delay` 表示等待多少毫秒(ms)。 为了获得更高精度的延迟效果,在某些情况下可能需要用到微秒(us)级别的延时功能。这通常通过调用特定于硬件平台的方法来完成,例如利用TIMx定器或其他外设特性[^2]。 如果需要更加精准甚至达到纳秒(ns)量级,则需依赖具体型号的支持情况以及额外编写底层代码处理逻辑[^3]。 需要注意的是,当引入第三方提供的高精度延时方案,可能会与标准 HAL 中的默认实现发生冲突,因此建议仔细阅读文档并按照指导操作以避免潜在问题。 #### 示例代码展示 下面给出一段简单的例子说明如何在应用程序里正确地运用上述提到的不同类型的延时服务: ```c #include "stm32f1xx_hal.h" int main(void){ /* 初始化系统 */ HAL_Init(); while (1){ // 执行一些任务... // 插入500ms 的暂停 HAL_Delay(500); // 或者执行其他任务... // 如果有需求的话也可以加入us级别的短暂停顿 __NOP(); // 这只是一个占位符, 实际应用中应替换为合适的API } } ```
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值