You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在CMSIS-RTOS2中使用硬件定时器实现0.9ms间隔定时?

实现CMSIS-RTOS2下0.9ms高精度定时器方案(STM32F407)

方案一:HAL配置硬件定时器 + CMSIS-RTOS2事件/信号量通知

这是最贴合你现有技能的方案,利用你熟悉的HAL配置硬件定时器,结合RTOS同步机制实现精准周期触发:

1. 用STM32CubeMX配置硬件定时器

选择空闲的32位定时器(比如TIM2,避免16位定时器的溢出限制),参数计算如下:

  • 目标周期:0.9ms → 对应频率≈1111.11Hz
  • 时钟源:内部时钟(168MHz)
  • 分频系数(PSC):设为167,分频后时钟为 168MHz/(167+1)=1MHz
  • 自动重装载值(ARR):设为899,定时器周期为 (899+1)/1MHz=0.9ms
  • 开启定时器更新中断,生成HAL代码。

2. 集成CMSIS-RTOS2同步机制

通过事件标志实现中断与任务的同步,触发周期操作:

定义同步对象

#include "cmsis_os2.h"

osEventFlagsId_t timer_event; // 用于中断-任务同步的事件标志

初始化同步对象与定时器

在初始化任务或main函数中完成:

// 创建事件标志
timer_event = osEventFlagsNew(NULL);
// 启动带中断的硬件定时器
HAL_TIM_Base_Start_IT(&htim2);

重写定时器中断回调

在中断中发送事件通知任务(使用RTOS中断安全API):

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
  if (htim->Instance == TIM2) {
    // 发送事件标志,无需等待返回值
    osEventFlagsSetFromISR(timer_event, 0x01, NULL);
  }
}

编写周期任务

在任务中等待事件触发,执行业务逻辑:

void periodic_task(void *argument) {
  for (;;) {
    // 等待定时器中断触发的事件
    osEventFlagsWait(timer_event, 0x01, osFlagsWaitAny, osWaitForever);
    // 此处执行0.9ms周期的操作
    // 注意:避免在任务中做耗时操作,否则会影响下次触发的响应及时性
  }
}

方案二:直接使用CMSIS-RTOS2硬件定时器API(不推荐)

CMSIS-RTOS2提供的osTimerNew属于软件定时器,依赖内核滴答,精度受限于滴答周期,无法满足0.9ms的高精度需求。若要通过RTX直接配置硬件定时器,需手动对接CMSIS-Driver,步骤繁琐且不如HAL直观,不作为优先方案。

关键注意事项

  • 中断优先级配置:确保定时器中断优先级高于RTX内核中断(RTX默认内核中断优先级为5,可将定时器中断设为4或更高),避免中断被RTOS内核抢占导致延迟。
  • 中断内操作限制:中断回调仅做RTOS同步通知,业务逻辑全部放到任务中执行,防止阻塞中断影响系统响应。
  • 选择32位定时器:32位定时器(TIM2/TIM5)支持更大的ARR范围,后续调整周期更灵活,无需担心16位定时器的溢出问题。

内容的提问来源于stack exchange,提问作者Amin Mollaei

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 15:55:16