# 通用定时器 **Repository Path**: tomfree_opensource/gm_timer ## Basic Information - **Project Name**: 通用定时器 - **Description**: 通用定时器,适用于任何单片机平台或PC平台,可以方便的进行时间管理 - **Primary Language**: C - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 7 - **Forks**: 0 - **Created**: 2020-08-02 - **Last Updated**: 2024-04-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 通用定时器 ## 通用定时器介绍 通用定时器用来扩展硬件定时器的个数限制,理论上可以扩展到任意个,具有以下特性 > * 超长定时周期(可以通过宏配置是16/32/64位定时周期和计数器值) > * 三种定时模式(单次计时、多次计时和永远循环计时) > * 可以手动停止和重新启动定时器 > * 可动态增删定时器 > * 自动回调处理 ## 代码结构 文件 | 描述 | | :-- | :-- | gm_timer.c | 定时器实现源码 gm_timer.h | 定时器头文件 gm_timer_cfg.h | 定时器配置文件 ## 使用说明 0、准备一个含有一个硬件定时器的工程,定时器中断设置为1ms或10ms 1、下载此代码到工程源码目录,添加`*.c`文件到工程,将文件夹目录添加入头文件搜索路径 2、配置`gm_timer_cfg.h`文件中的`GM_TIMER_CFG_CNT_BITS`宏为指定位数,低内存的单片机可选8或16,但使用时要注意最大周期长度,不要超过最大值,高容量单片机可选32或64,可以实现更长的计时周期 3、将`gm_timer_inc_ticks`函数放入中断服务函数,调用文件需要添加头文件包含`#include "gm_timer.h"` 4、将`gm_timer_poll_event`函数放入主循环轮询调用,调用文件需要添加头文件包含`#include "gm_timer.h"` 5、编译代码,可能会因编译器区别产生警告或错误,请按照报警提示修改,直到无错误或警告 6、使用定时器结构`gm_timer_t`创建一个定时器,需要创建`全局`或`静态`结构体,不能创建局部结构体,因为定时器采用链表管理,且无内置内存管理,局部结构体存于栈内部,函数返回就失效了,再次访问会带来无法预知的意外发生 7、使用`gm_timer_mgr_init`函数初始化定时器管理器,使用`gm_timer_init`函数初始化定时器并插入系统链表,注意需要设置定时器模式和参数以及注册回调函数 8、使用启动函数`gm_timer_start`启动定时器 9、填写回调函数内容,进行超时处理,回调函数原型为 ```C int timer_xxx_callback(gm_timer_t* ptimer) ``` ## 例子伪代码 以实现一个LED闪烁为例 ```C /* 包含头文件 */ #include "gm_timer.h" /* 创建定时器结构体 */ static gm_timer_t timer_led; /* LED定时器回调函数 */ static int led_timer_callback(gm_timer_t* ptimer) { /* LED闪烁,每次电平取反 */ led_blink(); return 0; } /* 主函数 */ int main(int argc, char* argv[]) { /* 其他设备初始化 */ others_init(); /* 硬件定时器初始化 */ hal_timer_init(); /* 初始化LED */ led_init(); /* 创建定时器,永久循环模式,次数为0(永久模式下此数据无效),500ticks个周期,回调函数 */ gm_timer_init(&timer_led, GM_TIMER_MODE_FOREVER, 0, 500, led_timer_callback); /* 启动定时器 */ gm_timer_start(&timer_led); for (;;) { /* 其他事件处理 */ others_handle(); /* 定时器轮询 */ gm_timer_poll_event(); } return 0; } /* 硬件定时器中断服务函数 */ ISR_FUNC void hal_timer_isr(void) { /* 计数值自增 */ gm_timer_inc_ticks(); } ```