21 鸿蒙LiteOS软件定时器实战:多定时器周期性任务完整示例(源码+解析)
本文详细介绍了鸿蒙LiteOS中软件定时器的使用方法和注意事项。主要内容包括:软件定时器的核心概念、API函数说明、完整可运行源码示例及逐行解析。文章重点对比了任务与软件定时器的区别,指出定时器回调函数必须简短且不能阻塞,适合简单定时触发场景;而任务适合复杂业务逻辑处理。通过1秒和2秒两个周期性定时器的实例演示,展示了多定时器并发运行的实现方式。最后总结了定时器和任务各自适用的典型场景,为开发者提
鸿蒙LiteOS软件定时器实战:多定时器周期性任务完整示例(源码+解析)
一、前言
在嵌入式鸿蒙(OpenHarmony LiteOS)开发中,软件定时器是实现周期性任务、延时任务、定时触发逻辑的核心内核工具,无需占用硬件定时器资源,支持创建多个定时器同时运行。
本文基于LiteOS内核API,手把手讲解软件定时器创建、启动、周期性运行的完整流程,提供可直接编译运行的标准源码,适合鸿蒙单片机开发入门学习。
哔站视频《06:RK2206 OpenHarmonyOS 鸿蒙 软件定时器与硬件定时器区别 软件定时器与任务区别 软件定时器实战》:https://www.bilibili.com/video/BV1w3546DEBS/?vd_source=3a9dd7a328acafb09dd1b8d05f3e2bf7
哔站视频《05:RK2206 OpenHarmonyOS 鸿蒙 什么是信号量 为什么需要信号量 代码演示》:https://www.bilibili.com/video/BV1to5W6pETF/?vd_source=3a9dd7a328acafb09dd1b8d05f3e2bf7
哔站视频《04:RK2206 OpenHarmonyOS 鸿蒙 任务实战》:https://www.bilibili.com/video/BV15R5E6JEHy/
哔站视频《03:RK2206 鸿蒙 LiteOS 如何通过控制编译选项编译不同案例》:https://www.bilibili.com/video/BV15e5J6QEGY/?spm_id_from=333.1387.homepage.video_card.click&vd_source=3a9dd7a328acafb09dd1b8d05f3e2bf7
哔站视频《02:RK2206 鸿蒙 LiteOS bin 文件 烧写》:https://www.bilibili.com/video/BV1pcRdBaEAt/?spm_id_from=333.1387.homepage.video_card.click&vd_source=3a9dd7a328acafb09dd1b8d05f3e2bf7
哔站视频《01:RK2206 鸿蒙 LiteOS ubuntu 开发环境 全程 安装配置》:https://www.bilibili.com/video/BV1nrRkBoEMR/?spm_id_from=333.1387.homepage.video_card.click&vd_source=3a9dd7a328acafb09dd1b8d05f3e2bf7
二、LiteOS软件定时器核心概念
1. 什么是软件定时器
软件定时器是基于系统时钟节拍实现的定时服务,由LiteOS内核提供,不依赖硬件外设,可创建多个独立定时器,分别设置不同超时时间和回调函数。
2. 软件定时器主要作用
- 实现周期性任务(每隔1s、2s执行一段逻辑)
- 实现延时触发功能
- 替代硬件定时器,节省硬件资源
- 多任务定时调度,简化业务逻辑
3. 核心工作模式
本文使用 LOS_SWTMR_MODE_PERIOD(周期性模式):
定时器超时后自动重启,循环执行回调函数,直到手动停止/删除。
三、软件定时器核心API函数
| API函数 | 功能说明 |
|---|---|
| LOS_SwtmrCreate | 创建软件定时器,指定超时时间、模式、回调函数 |
| LOS_SwtmrStart | 启动已创建的定时器 |
| LOS_SwtmrStop | 停止正在运行的定时器 |
| LOS_SwtmrDelete | 删除定时器,释放内核资源 |
API参数说明
LOS_SwtmrCreate(
timeout, // 超时时间(单位:Tick,LiteOS默认1Tick=1ms)
mode, // 模式:单次/周期
callback, // 超时回调函数
timerID, // 定时器ID(输出)
arg // 回调函数参数
)
四、完整可运行源码
#include "los_swtmr.h"
#include "ohos_init.h"
void timer1_timeout(void *arg)
{
printf("This is Timer1 Timeout function\n");
}
void timer2_timeout(void *arg)
{
printf("This is Timer2 Timeout function\n");
}
void timer_example()
{
unsigned int timer_id1, timer_id2;
unsigned int ret;
/* 创建定时器1:1000ms = 1s 周期性执行 */
ret = LOS_SwtmrCreate(1000, LOS_SWTMR_MODE_PERIOD, timer1_timeout, &timer_id1, NULL);
if (ret == LOS_OK)
{
ret = LOS_SwtmrStart(timer_id1);
if (ret != LOS_OK)
{
printf("start timer1 fail ret:0x%x\n", ret);
return;
}
}
else
{
printf("create timer1 fail ret:0x%x\n", ret);
return;
}
/* 创建定时器2:2000ms = 2s 周期性执行 */
ret = LOS_SwtmrCreate(2000, LOS_SWTMR_MODE_PERIOD, timer2_timeout, &timer_id2, NULL);
if (ret == LOS_OK)
{
ret = LOS_SwtmrStart(timer_id2);
if (ret != LOS_OK)
{
printf("start timer2 fail ret:0x%x\n", ret);
return;
}
}
else
{
printf("create timer2 fail ret:0x%x\n", ret);
return;
}
}
/* 系统自动初始化入口 */
APP_FEATURE_INIT(timer_example);
五、代码逻辑逐行解析
1. 头文件
los_swtmr.h:LiteOS软件定时器内核头文件ohos_init.h:鸿蒙自动初始化模块头文件
2. 定时器回调函数
timer1_timeout:定时器1超时执行函数,1s执行一次timer2_timeout:定时器2超时执行函数,2s执行一次
3. 定时器创建与启动流程
- 调用
LOS_SwtmrCreate创建定时器 - 判断创建是否成功(返回LOS_OK)
- 调用
LOS_SwtmrStart启动定时器 - 两个定时器独立运行,互不干扰
4. 自动初始化
APP_FEATURE_INIT(timer_example);
系统启动时自动执行定时器初始化,无需手动调用。
六、串口运行打印效果

- Timer1:每隔1s打印一次
- Timer2:每隔2s打印一次
- 两个定时器周期性并发运行
七、常见注意事项
- 回调函数不能阻塞:不能在定时器回调里使用延时、死循环、阻塞API
- 回调函数要简洁:只处理快速逻辑,避免占用系统时钟
- 单位是毫秒:LiteOS默认配置 1 Tick = 1ms
- 多定时器互不影响:可同时创建N个软件定时器并行运行
- 必须先创建、再启动,否则定时器不会运行
八、对比分析 任务 与 软件定时器
| 对比项 | 任务(Task / 线程) | 软件定时器(Software Timer) |
|---|---|---|
| 运行方式 | 独立循环执行 | 只在超时时刻触发一次回调 |
| 能否阻塞 | 可以(延时、等待信号量、休眠) | 绝对不能(一阻塞系统就崩溃) |
| 优先级 | 可设置独立优先级 | 共享定时器任务优先级,不可单独设置 |
| 资源占用 | 较高(需要独立栈) | 极低(共用栈) |
| 执行时长 | 可长可短 | 必须极短(几ms内完成) |
| 使用场景 | 大循环逻辑、复杂业务 | 定时计数、定时打印、定时触发标志 |
| 能否等待信号量 | ✅ 可以 | ❌ 不可以 |
| 能否延时 | ✅ LOS_Msleep 可以 | ❌ 绝对不可以 |
定时器回调函数 绝对不能做
- 不能延时(LOS_Msleep)
- 不能死循环
- 不能等待信号量/消息队列
- 不能执行耗时操作(超过10ms都危险)
任务 可以随便做
- 可以循环
- 可以阻塞
- 可以等待
- 可以运行复杂业务
九、什么时候用定时器?什么时候用任务?
✅ 用定时器的场景
- 定时1秒打印一次日志
- 定时刷新LED
- 定时更新计数器
- 定时设置一个标志位
- 功能简单、时间短、到点触发一下
✅ 用任务的场景
- 需要大循环
- 需要等待信号量
- 需要处理复杂逻辑
- 需要阻塞、延时、休眠
- 需要处理串口、网络、文件系统
更多推荐

所有评论(0)