尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
RT-Thread 软件定时器 5 大 API 实战:单次/周期模式在 STM32 上的 3 个应用案例
RT-Thread 软件定时器 5 大 API 实战单次/周期模式在 STM32 上的 3 个应用案例1. 软件定时器基础与核心 API 解析在嵌入式实时系统中定时器是控制任务执行节奏的关键组件。RT-Thread 提供的软件定时器功能允许开发者突破硬件定时器数量的限制创建灵活的定时任务。与硬件定时器不同软件定时器的超时函数执行在 RT-Thread 的定时器线程上下文中而非中断环境这使得开发者可以在回调函数中使用更多的系统 API。RT-Thread 软件定时器主要提供以下 5 个核心 API创建定时器 (rt_timer_create)动态分配内存并初始化定时器控制块适用于需要频繁创建/销毁的场景。关键参数包括rt_timer_t rt_timer_create(const char* name, void (*timeout)(void*), void* parameter, rt_tick_t time, rt_uint8_t flag);name定时器名称用于调试timeout超时回调函数指针time定时周期单位tickflag组合标志单次/周期、软件/硬件模式启动定时器 (rt_timer_start)将定时器激活并插入到系统定时器链表中开始计时rt_err_t rt_timer_start(rt_timer_t timer);停止定时器 (rt_timer_stop)将定时器从活动链表中移除停止计时但不释放资源rt_err_t rt_timer_stop(rt_timer_t timer);删除定时器 (rt_timer_delete)彻底释放定时器占用的内存资源rt_err_t rt_timer_delete(rt_timer_t timer);控制定时器 (rt_timer_control)动态修改定时器参数支持以下命令rt_err_t rt_timer_control(rt_timer_t timer, rt_uint8_t cmd, void* arg);RT_TIMER_CTRL_SET_TIME修改定时周期RT_TIMER_CTRL_SET_ONESHOT切换为单次模式RT_TIMER_CTRL_SET_PERIODIC切换为周期模式关键区别软件定时器RT_TIMER_FLAG_SOFT_TIMER的超时函数执行在线程上下文允许调用如rt_thread_delay等可能阻塞的 API而硬件定时器模式RT_TIMER_FLAG_HARD_TIMER的超时函数执行在中断上下文要求快速执行完毕。2. 案例一单次定时器控制 LED 闪烁2.1 硬件连接与初始化本案例基于 STM32F407 开发板使用 PE3 引脚连接 LED。首先完成硬件初始化#define LED_PIN GET_PIN(E, 3) static void led_init(void) { rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT); rt_pin_write(LED_PIN, PIN_HIGH); // 初始熄灭 }2.2 单次定时器实现创建单次定时器在超时后翻转 LED 状态并自动销毁static rt_timer_t led_timer RT_NULL; static void led_timeout(void *param) { rt_uint32_t *count (rt_uint32_t *)param; rt_pin_write(LED_PIN, !rt_pin_read(LED_PIN)); rt_kprintf(LED toggled %d times\n, (*count)); // 定时器自动销毁单次模式 if (*count 5) { rt_kprintf(Timer completed its work\n); } } int led_blink_sample(void) { static rt_uint32_t toggle_count 0; led_init(); led_timer rt_timer_create(led_timer, led_timeout, toggle_count, 1000, // 1000 ticks 1s (RT_TICK_PER_SECOND1000) RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER); if (led_timer ! RT_NULL) { rt_timer_start(led_timer); rt_kprintf(Single-shot timer started\n); } return RT_EOK; }关键点说明使用RT_TIMER_FLAG_ONE_SHOT标志创建单次定时器定时器超时后自动从系统移除但控制块仍存在需手动删除通过参数传递计数变量实现状态保持2.3 进阶用法链式单次定时器实现连续闪烁效果每次超时后重新启动定时器static void chained_timeout(void *param) { rt_pin_write(LED_PIN, !rt_pin_read(LED_PIN)); // 重新配置并启动定时器 rt_timer_control(led_timer, RT_TIMER_CTRL_SET_TIME, (void*)500); rt_timer_start(led_timer); }3. 案例二周期定时器实现数据采样3.1 模拟数据采集环境假设通过 ADC 采集传感器数据此处用随机数模拟static rt_uint16_t mock_adc_read(void) { return rand() % 4096; // 12位ADC模拟值 }3.2 周期定时器配置创建 100Hz 采样率的周期定时器#define SAMPLE_RATE_HZ 100 static rt_timer_t adc_timer RT_NULL; static rt_uint32_t sample_count 0; static void adc_sample_timeout(void *param) { rt_uint16_t adc_val mock_adc_read(); rt_kprintf([%04d] ADC: %04d\n, sample_count, adc_val); } int adc_sample_init(void) { rt_tick_t interval RT_TICK_PER_SECOND / SAMPLE_RATE_HZ; adc_timer rt_timer_create(adc_timer, adc_sample_timeout, RT_NULL, interval, RT_TIMER_FLAG_PERIODIC | RT_TIMER_FLAG_SOFT_TIMER); if (adc_timer ! RT_NULL) { rt_timer_start(adc_timer); rt_kprintf(ADC sampling started at %dHz\n, SAMPLE_RATE_HZ); } return RT_EOK; }性能优化技巧使用RT_TIMER_FLAG_PERIODIC避免重复创建/启动开销计算 tick 间隔时考虑整除问题避免累积误差在回调函数中避免耗时操作防止影响定时精度3.3 动态调整采样率通过rt_timer_control实现运行时参数调整void set_adc_sample_rate(rt_uint32_t new_rate_hz) { rt_tick_t new_interval RT_TICK_PER_SECOND / new_rate_hz; rt_timer_control(adc_timer, RT_TIMER_CTRL_SET_TIME, new_interval); rt_kprintf(Sample rate changed to %dHz\n, new_rate_hz); }4. 案例三动态修改定时周期实现 PWM 调光4.1 PWM 原理与软件实现通过动态调整 LED 亮灭时间的占空比模拟 PWM 输出参数说明周期固定为 20ms (50Hz)占空比0-100% 可调分辨率1% (200μs/步进)4.2 代码实现使用两个定时器分别控制亮灭时间static rt_timer_t pwm_on_timer RT_NULL; static rt_timer_t pwm_off_timer RT_NULL; static rt_uint8_t pwm_duty 50; // 初始50%占空比 static void pwm_on_timeout(void *param) { rt_pin_write(LED_PIN, PIN_LOW); // LED亮 rt_timer_start(pwm_off_timer); // 启动灭定时器 } static void pwm_off_timeout(void *param) { rt_pin_write(LED_PIN, PIN_HIGH); // LED灭 rt_timer_start(pwm_on_timer); // 启动亮定时器 } void set_pwm_duty(rt_uint8_t duty) { if (duty 100) duty 100; pwm_duty duty; rt_tick_t on_time 20 * duty; // 单位tick (假设1tick1ms) rt_tick_t off_time 2000 - on_time; rt_timer_control(pwm_on_timer, RT_TIMER_CTRL_SET_TIME, on_time); rt_timer_control(pwm_off_timer, RT_TIMER_CTRL_SET_TIME, off_time); } int pwm_init(void) { led_init(); pwm_on_timer rt_timer_create(pwm_on, pwm_on_timeout, RT_NULL, 1000, // 初始1ms RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER); pwm_off_timer rt_timer_create(pwm_off, pwm_off_timeout, RT_NULL, 1000, // 初始1ms RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER); if (pwm_on_timer pwm_off_timer) { set_pwm_duty(pwm_duty); rt_timer_start(pwm_on_timer); rt_kprintf(Software PWM initialized at %d%% duty\n, pwm_duty); } return RT_EOK; }关键优化使用两个单次定时器形成循环触发动态计算亮灭时间实现占空比调整确保总周期时间恒定20ms5. 软件定时器高级应用技巧5.1 定时器精度优化策略虽然软件定时器精度受限于系统 tick但可通过以下方法提高提高系统 tick 频率修改rtconfig.h中的RT_TICK_PER_SECOND但会增加系统开销补偿技术记录实际超时时间与理论时间的偏差下次定时进行补偿static rt_tick_t last_time; static rt_int32_t accum_error 0; static void precise_timeout(void *param) { rt_tick_t now rt_tick_get(); rt_int32_t deviation (now - last_time) - target_interval; accum_error deviation; // 下次定时补偿误差 rt_tick_t adj_interval target_interval - (accum_error / 4); rt_timer_control(timer, RT_TIMER_CTRL_SET_TIME, adj_interval); last_time now; // ... 业务逻辑 ... }5.2 多定时器协同工作通过一个管理器定时器调度多个任务减少系统资源占用#define MAX_TASKS 5 struct timer_task { rt_tick_t interval; rt_tick_t last_run; void (*func)(void); }; static struct timer_task task_list[MAX_TASKS]; static void scheduler_timeout(void *param) { rt_tick_t now rt_tick_get(); for (int i 0; i MAX_TASKS; i) { if (now - task_list[i].last_run task_list[i].interval) { task_list[i].func(); task_list[i].last_run now; } } rt_timer_start((rt_timer_t)param); // 重新启动 }5.3 资源管理与注意事项内存管理动态定时器需配对使用create/delete静态定时器使用init/detach线程安全在中断中操作定时器需使用rt_interrupt_enter/leave性能监控通过list_timer命令查看定时器状态msh /list_timer timer periodic timeout flag ------ --------- --------- ------- t1 1000 500 SOFT,PERIODIC t2 2000 1500 SOFT,ONE_SHOT常见问题排查定时不准确检查系统负载和 tick 配置回调未执行确认定时器是否已启动内存泄漏确保删除不再使用的定时器
RELATED

相关推荐

B端AI产品的客户POC流程设计:从技术演示到合同签约的关键节点

B端AI产品的客户POC流程设计:从技术演示到合同签约的关键节点

B端AI产品的客户POC流程设计:从技术演示到合同签约的关键节点 一、深度引言 过去两年,我参与并复盘了超过20个B端AI产品的POC项目,从智能客服、知识问答到流程自动化Agent,覆盖金融、制造、零售等多个行业。一个反复出现的现象是&…

📅 2026/10/19 11:45:16
3分钟掌握WaveTools:让你的《鸣潮》游戏体验飙升的秘密武器

3分钟掌握WaveTools:让你的《鸣潮》游戏体验飙升的秘密武器

3分钟掌握WaveTools:让你的《鸣潮》游戏体验飙升的秘密武器 【免费下载链接】WaveTools 🧰鸣潮工具箱 项目地址: https://gitcode.com/gh_mirrors/wa/WaveTools 你是否在《鸣潮》的世界里遇到过这样的烦恼?游戏帧率不稳定,…

📅 2026/10/19 7:53:42
Gemini API后台执行与MCP协议:AI应用异步处理新范式

Gemini API后台执行与MCP协议:AI应用异步处理新范式

如果你正在构建AI应用,一定遇到过这样的困境:当需要处理长时间运行的任务时,要么让用户干等几分钟,要么自己搭建复杂的异步任务队列。现在,Google DeepMind为Gemini API带来的后台执行功能,正在从根本上改变…

📅 2026/10/19 8:16:33
MORE NEWS

更多资讯

📰

应用商店合规下架潮:开发者应对策略与趋势分析

1. 应用商店生态变局观察最近业内同行们都在讨论一个现象:国内主流应用商店出现了一波明显的应用下架潮。作为从业十余年的移动应用开发者,我深切感受到这次调整带来的震动。不同于以往零星的下架事件,这次波及范围广、持续时间长&#xff0c…

📰

Flutter与OpenHarmony的Crontab定时任务开发实践

1. 项目背景与核心价值在跨平台开发领域,Flutter与OpenHarmony的结合正在开辟新的技术可能性。这个项目实现了Linux风格的定时任务调度系统(Crontab语法解析)在Dart环境中的完整移植,并特别针对鸿蒙系统进行了深度适配。作为开发者…

📰

text-to-cad 实战:从自然语言到参数化 CAD 模型的完整落地链路

1. 从一句话到三维模型:text-to-cad 到底在解决什么问题第一次听到 "text-to-cad" 这个词,很多人脑子里浮现的画面大概是:对着电脑说一句"给我画个带法兰的弯管接头",屏幕上就自动旋转出一个可以导出加工的 3…

📰

FFmpeg字幕嵌入GUI工具:批量硬编码SRT/ASS到MP4的生产级方案

简介:这是一款面向音视频后期从业者与字幕制作新手的本地化SRT字幕自动生成工具,解决人工听写效率低、在线识别需上传隐私视频、多文件批量处理困难等痛点。软件基于FFmpeg与语音识别模型构建,支持中英文双语识别,无需联网上传原视…

📰

iOS应用合规下架潮:开发者应对策略与技术方案

1. 事件背景与行业震动上周三早晨,不少iOS开发者一觉醒来发现自己的应用从中国区App Store神秘消失。这次下架潮波及范围远超往常,涉及游戏、工具、社交等多个品类,其中不乏月活百万级的应用。根据第三方监测数据,单日下架应用数量…

📰

S7-1214C Modbus TCP通信实战:从组态到排错

简介:这份资源面向自动化工程师与PLC初学者,聚焦西门子S7-1214C紧凑型PLC与机器人之间基于Modbus TCP的通信配置,解决以太网接口设置、主从站角色定义、寄存器地址映射及功能码使用等实际问题,适合具备一定Step 7编程基础、需要落…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬