外观
HWTIMER 示例
2026-07-14
概述
本文介绍如何在 睿擎工业开发平台 中创建并运行 硬件定时器 示例工程。通过驱动 TL3576 平台内置硬件定时器,演示了利用 RT-Thread 设备驱动框架进行硬件定时器操作的完整流程,支持单次定时和周期定时两种模式。
硬件定时器简介
硬件定时器是 RT-Thread 中用于管理片上定时器资源的核心框架。它提供设置定时模式(单次/周期)、配置超时时间、注册超时回调函数、读取当前计数值及停止定时器等功能,支持通过标准化接口实现硬件定时器的精确控制与事件管理。
查询手册获取硬件定时器资源
根据 TL3576 技术参考手册(TRM)可知:
- TL3576 内部集成多路硬件定时器,本示例使用
hwtimer5 - 支持单次(oneshot)和周期(period)两种工作模式
- 定时精度可达微秒级,超时时间可通过参数动态配置
构建与烧录
创建工程点击展开
依次点击 “文件” -> “新建” -> "RT-Thread RuiChing App 项目"。

在弹出新建向导中选择 开发版 、BSP: 、示例 、 调试器/下载器。选择好之后点击 “完成”。

点击 “完成” 后,等待工程创建完成。

创建完成。

构建工程点击展开
单击工程使工程进入 Active-Debug 模式。

点击工具栏上的构建按钮进行工程编译。

构建成功后,会显示构建成功的信息。

固件下载点击展开
固化驱动

固化 APP

核心示例代码
硬件定时器示例相关 API
rt_device_find:查找硬件定时器设备;rt_device_open:打开设备;rt_device_set_rx_indicate:注册超时回调函数;rt_device_control+HWTIMER_CTRL_MODE_SET:设置定时模式(单次/周期);rt_device_write:设置超时时间并启动定时器;rt_device_control+HWTIMER_CTRL_STOP:停止定时器;
- HWTIMER 示例
#define TEST_HWTIMER_NAME "hwtimer5" // 硬件定时器设备名
static rt_err_t timeout_cb(rt_device_t dev, rt_size_t size)// hwtimer 中断回调函数
{
rt_kprintf("[hwtimer] timeout! callback size=%d, tick=%lu\n",
size, rt_tick_get());
return RT_EOK;
}
static void hwtimer_test(int argc, char *argv[])// HWTIMER 测试入口函数
{
rt_device_t hw_dev = RT_NULL;
rt_hwtimerval_t timeout;
rt_hwtimer_mode_t mode;
rt_err_t err;
const char *dev_name;
rt_uint32_t sec = 2;
rt_uint32_t usec = 500000;
if (argc < 3)
{
rt_kprintf("Usage:\n");
rt_kprintf(" hwtimer_test <hwtimer5> <oneshot|period> [sec] [usec]\n");
rt_kprintf(" hwtimer_read <hwtimer5>\n");
rt_kprintf(" hwtimer_stop <hwtimer5>\n");
return;
}
dev_name = argv[1];
if (rt_strcmp(argv[2], "oneshot") == 0)
mode = HWTIMER_MODE_ONESHOT;
else if (rt_strcmp(argv[2], "period") == 0)
mode = HWTIMER_MODE_PERIOD;
else
{
rt_kprintf("Invalid mode! Use 'oneshot' or 'period'.\n");
return;
}
if (argc >= 4)
sec = atoi(argv[3]);
if (argc >= 5)
usec = atoi(argv[4]);
hw_dev = rt_device_find(dev_name);// 查找硬件定时器设备
if (hw_dev == RT_NULL)
{
rt_kprintf("Can't find device: %s (enable BSP_USING_HWTIMER5)\n", dev_name);
return;
}
err = rt_device_open(hw_dev, RT_DEVICE_FLAG_RDWR);
if (err != RT_EOK)
{
rt_kprintf("Open %s failed, err=%d\n", dev_name, err);
return;
}
rt_device_set_rx_indicate(hw_dev, timeout_cb);// 注册超时回调
err = rt_device_control(hw_dev, HWTIMER_CTRL_MODE_SET, &mode);// 设置定时模式
if (err != RT_EOK)
{
rt_kprintf("Set mode failed, err=%d\n", err);
rt_device_close(hw_dev);
return;
}
timeout.sec = sec;
timeout.usec = usec;
rt_kprintf("[hwtimer] %s start: mode=%s, timeout=%d.%06d sec\n",
dev_name,
(mode == HWTIMER_MODE_ONESHOT) ? "ONESHOT" : "PERIOD",
timeout.sec, timeout.usec);
if (rt_device_write(hw_dev, 0, &timeout, sizeof(timeout)) != sizeof(timeout))// 启动定时器
{
rt_kprintf("Start %s failed\n", dev_name);
rt_device_close(hw_dev);
return;
}
if (mode == HWTIMER_MODE_PERIOD)
{
rt_thread_mdelay(10000);
rt_kprintf("[hwtimer] stopping %s after 10s...\n", dev_name);
rt_device_control(hw_dev, HWTIMER_CTRL_STOP, RT_NULL);// 停止周期定时器
}
else
{
rt_thread_mdelay(sec * 1000 + usec / 1000 + 1000);
}
rt_device_close(hw_dev);
rt_kprintf("[hwtimer] %s test finished.\n", dev_name);
}- HWTIMER 读取
static void hwtimer_read(int argc, char *argv[])
{
rt_device_t hw_dev;
rt_hwtimer_t *timer;
rt_base_t level;
rt_uint32_t cnt;
rt_uint32_t remain_us;
if (argc < 2)
{
rt_kprintf("Usage: hwtimer_read <hwtimer5>\n");
return;
}
hw_dev = rt_device_find(argv[1]);// 查找硬件定时器设备
if (hw_dev == RT_NULL)
{
rt_kprintf("Can't find device: %s\n", argv[1]);
return;
}
if (rt_device_open(hw_dev, RT_DEVICE_FLAG_RDWR) != RT_EOK)
{
rt_kprintf("Open %s failed\n", argv[1]);
return;
}
timer = (rt_hwtimer_t *)hw_dev;
if (timer->ops == RT_NULL || timer->ops->count_get == RT_NULL)
{
rt_kprintf("[hwtimer] count_get not supported\n");
rt_device_close(hw_dev);
return;
}
level = rt_hw_interrupt_disable();
cnt = timer->ops->count_get(timer);
rt_hw_interrupt_enable(level);
cnt = (rt_uint32_t)(timer->freq * timer->period_sec) - cnt;
remain_us = cnt * 1000000 / timer->freq;
rt_kprintf("[hwtimer] %s count=%lu remain=%lu us\n",
argv[1], (unsigned long)cnt, (unsigned long)remain_us);
rt_device_close(hw_dev);
}- HWTIMER 停止
static void hwtimer_stop(int argc, char *argv[])
{
rt_device_t hw_dev;
rt_err_t err;
if (argc < 2)
{
rt_kprintf("Usage: hwtimer_stop <hwtimer5>\n");
return;
}
hw_dev = rt_device_find(argv[1]);// 查找硬件定时器设备
if (hw_dev == RT_NULL)
{
rt_kprintf("Can't find device: %s\n", argv[1]);
return;
}
err = rt_device_open(hw_dev, RT_DEVICE_FLAG_RDWR);
if (err != RT_EOK)
{
rt_kprintf("Open %s failed, err=%d\n", argv[1]);
return;
}
err = rt_device_control(hw_dev, HWTIMER_CTRL_STOP, RT_NULL);
if (err == RT_EOK)
rt_kprintf("[hwtimer] %s stopped.\n", argv[1]);
else
rt_kprintf("[hwtimer] stop %s failed, err=%d\n", argv[1], err);
rt_device_close(hw_dev);
}运行示例
操作步骤
- 将程序下载到开发板
- 打开串口终端连接开发板
- 在终端输入
hwtimer_test hwtimer5 period启动周期定时(默认 2.5s 超时,运行 10s 后自动停止) - 定时器超时后自动打印日志,程序自动退出
- 输入
hwtimer_test hwtimer5 oneshot 1 0启动 1 秒单次定时 - 等待超时回调触发后程序自动退出
- 先启动周期定时器,再输入
hwtimer_read hwtimer5查看剩余计数值
预期结果
验证 TL3576 开发板的硬件定时器外设基本功能正常,三种命令行为如下:
RT-Thread 终端
msh />hwtimer_test hwtimer5 period
[hwtimer] hwtimer5 start: mode=PERIOD, timeout=2.500000 sec
[hwtimer] timeout! callback size=8, tick=81920713
[hwtimer] timeout! callback size=8, tick=81923188
[hwtimer] timeout! callback size=8, tick=81925663
[hwtimer] timeout! callback size=8, tick=81928138
[hwtimer] stopping hwtimer5 after 10s...
[hwtimer] hwtimer5 test finished.RT-Thread 终端
msh />hwtimer_test hwtimer5 oneshot 1 0
[hwtimer] hwtimer5 start: mode=ONESHOT, timeout=1.000000 sec
[hwtimer] timeout! callback size=8, tick=82134778
[hwtimer] hwtimer5 test finished.RT-Thread 终端
msh />hwtimer_test hwtimer5 period
[hwtimer] hwtimer5 start: mode=PERIOD, timeout=2.500000 sec
[hwtimer] timeout! callback size=8, tick=82162085
[hwtimer] timeout! callback size=8, tick=82164560
[hwtimer] timeout! callback size=8, tick=82167035
[hwtimer] timeout! callback size=8, tick=82169510
[hwtimer] stopping hwtimer5 after 10s...
[hwtimer] hwtimer5 test finished.
msh />hwtimer_read hwtimer5
[hwtimer] hwtimer5 count=57593280 remain=85 us
msh />hwtimer_stop hwtimer5
[hwtimer] hwtimer5 stopped.