systick开发指南
概述
Systick(System Tick)模块基于外部32.768kHz晶振或内部32kHz时钟为系统提供计数功能。
计数系统架构

快速跑通 Systick Demo
功能说明
Systick 计时示例 在 20 ms 等待前后读取 Systick 毫秒计数并校验计数向前推进,不依赖外接硬件。
Demo 代码归档路径
samples/native_samples/systick/
├── CMakeLists.txt # 独立组件构建配置
├── README.md # 项目级运行说明
├── systick_demo.c # 计数增量验证和 AT 指令
└── systick_demo.h # 对外运行接口和 AT 注册函数声明
编译与烧录
完成一站式 CLI 环境配置后执行:
使用一站式 CLI 烧写固件并打开 UART2 串口监视器。以下为 Windows USB DFU 示例;将 COM3 替换为实际日志串口,其他参数参见一站式 CLI 开发环境使用指南。
fbb flash -f "$env:FBB_SDK_DIR\output\3322\fwpkg\diting-community.fwpkg" --chip 3322 -d --timeout 180
fbb monitor --port COM3 --baud 750000
使用方式
预期结果
实际增量可能受任务调度影响而略大于 20 ms:
需要一次性检查 Systick、Systime、TCXO 等板载能力时,也可以执行 AT+DRIVERSELFTEST。
文件结构与代码走读
文件职责
| 文件 | 职责 | 关键内容 |
|---|---|---|
systick_demo.c |
读取毫秒计数、等待并校验增量 | diting_systick_demo_run() |
systick_demo.h |
公开运行和 AT 注册接口 | at_diting_systick_example_cmd_register() |
CMakeLists.txt |
定义独立组件和注册宏 | diting_systick_sample、AT_DITING_EXAMPLE_SYSTICK_TEST |
README.md |
说明运行方法和预期结果 | AT+SYSTICKTEST |
核心流程
bool diting_systick_demo_run(void)
{
uint64_t before = uapi_systick_get_ms();
(void)osal_msleep(SYSTICK_DEMO_DELAY_MS);
uint64_t delta = uapi_systick_get_ms() - before;
printf("[DRV][SYSTICK] delta=%llums\n", (unsigned long long)delta);
return delta >= SYSTICK_DEMO_DELAY_MS;
}
这里使用 osal_msleep() 让出 CPU,Systick 只负责提供前后计数。判断条件使用“不小于 20 ms”,避免任务调度造成的正常延迟被误判为失败。AT 处理函数输出单项结果,聚合自测通过同一公开函数复用这段逻辑。
基于 Systick Demo 开发自己的应用
- 复制 samples/native_samples/systick,修改组件名和构建开关,保留
diting_systick_demo_run()这类可直接调用的运行函数。 - 从应用任务、系统服务或
app_run启动入口调用运行函数。 - 根据精度要求选择
uapi_systick_get_s()、uapi_systick_get_ms()或uapi_systick_get_us()。 - 测量任务执行时间时只包围目标代码;需要主动延时时,根据场景选择 OS 睡眠或 Systick 延时接口。
- 不要将任务调度延迟等同于 Systick 误差,应给验收范围保留合理裕量。
- 在上层 CMake 和目标配置中增加新组件入口。
需要串口触发板端回归时,可再配置 AT 命令名、命令 ID 和 AT 适配层注册;业务计时功能不依赖该调试入口。
功能描述
Systick模块提供的接口:
| 接口名称 | 功能简述 | API文档 |
|---|---|---|
| uapi_systick_init | 初始化Systick模块 | systick.md |
| uapi_systick_get_count | 获取Systick当前计数值 | systick.md |
| uapi_systick_get_s | 获取Systick当前计数秒值 | systick.md |
| uapi_systick_get_ms | 获取Systick当前计数毫秒值 | systick.md |
| uapi_systick_get_us | 获取Systick当前计数微秒值 | systick.md |
| uapi_systick_count_clear | 清除Systick计数值 | systick.md |
| uapi_systick_delay_s | 按秒数延时 | systick.md |
| uapi_systick_delay_ms | 按毫秒数延时 | systick.md |
| uapi_systick_delay_us | 按微秒数延时 | systick.md |
| uapi_systick_delay_count | 按计数值延时 | systick.md |
开发指引
操作流程

初始化Systick
获取计数值
获取时间值
uint64_t seconds;
uint64_t milliseconds;
uint64_t microseconds;
seconds = uapi_systick_get_s();
milliseconds = uapi_systick_get_ms();
microseconds = uapi_systick_get_us();
PRINT("Time: %llu s, %llu ms, %llu us\r\n", seconds, milliseconds, microseconds);
清除计数
延时功能
// 延时1秒
uapi_systick_delay_s(1);
// 延时100毫秒
uapi_systick_delay_ms(100);
// 延时1000微秒
uapi_systick_delay_us(1000);
// 按count延时(count数取决于时钟频率)
uapi_systick_delay_count(32768); // 约1秒(基于32.768kHz)
延时验证示例
void test_systick_delayms(void)
{
uint64_t count_before_delay_count;
uint64_t count_after_delay_count;
/* systick模块初始化 */
uapi_systick_init();
/* 通过count数差值验证延迟时间 */
count_before_delay_count = uapi_systick_get_count();
uapi_systick_delay_ms(1000); // 延时1秒
count_after_delay_count = uapi_systick_get_count();
printf("test case delay count %lu.\r\n",
count_before_delay_count - count_after_delay_count);
return;
}
注意事项
-
时钟源:基于外部32.768kHz晶振或内部32kHz时钟
-
计数频率:32.768kHz时,每计数一次约30.5μs
-
溢出:计数值类型为uint64_t,溢出概率极低
-
延时精度:受时钟源精度影响

延时时间计算:
- 延时1秒 ≈ 32768 count(基于32.768kHz)
- 延时1ms ≈ 32.768 count
- 延时1μs ≈ 0.032768 count