赞
踩
#define TMR_COUNT 4 /* 软件定时器的个数 (定时器 ID 范围 0 - 3) */ typedef enum { TMR_ONCE_MODE = 0, /* 一次工作模式 */ TMR_AUTO_MODE = 1 /* 自动定时工作模式 */ }TMR_MODE_E; /* 定时器结构体,成员变量必须增加__IO 即 volatile,因为这个变量在中断和主程序中同时被访问, 有可能造成编译器错误优化。 */ typedef struct { volatile uint8_t Mode; /* 计数器模式,1 次性 */ volatile uint8_t Flag; /* 定时到达标志 */ volatile uint32_t Count; /* 计数器 */ volatile uint32_t PreLoad; /* 计数器预装值 */ }SOFT_TMR; /* 定于软件定时器结构体变量 */ static SOFT_TMR s_tTmr[TMR_COUNT];
void bsp_InitTimer(void) { uint8_t i; /* 清零所有的软件定时器 */ for (i = 0; i < TMR_COUNT; i++) { s_tTmr[i].Count = 0; s_tTmr[i].PreLoad = 0; s_tTmr[i].Flag = 0; s_tTmr[i].Mode = TMR_ONCE_MODE; /* 缺省是 1 次性工作模式 */ } /* 23. 配置 systic 中断周期为 1ms,并启动 systick 中断。 24. 25. SystemCoreClock 是固件中定义的系统内核时钟,对于 STM32H7,一般为 400MHz 26. 27. SysTick_Config() 函数的形参表示内核时钟多少个周期后触发一次 Systick 定时中断. 28. -- SystemCoreClock / 1000 表示定时频率为 1000Hz, 也就是定时周期为 1ms 29. -- SystemCoreClock / 500 表示定时频率为 500Hz, 也就是定时周期为 2ms 30. -- SystemCoreClock / 2000 表示定时频率为 2000Hz, 也就是定时周期为 500us 31. 32. 对于常规的应用,我们一般取定时周期 1ms。对于低速 CPU 或者低功耗应用,可以设置定时周期为 10ms 33. */ SysTick_Config(SystemCoreClock / 1000); }
void bsp_StartTimer(uint8_t _id, uint32_t _period) { if (_id >= TMR_COUNT) { while(1); } DISABLE_INT(); /* 关中断 */ s_tTmr[_id].Count = _period; /* 实时计数器初值 */ s_tTmr[_id].PreLoad = _period; /* 计数器自动重装值,仅自动模式起作用 */ s_tTmr[_id].Flag = 0; /* 定时时间到标志 */ s_tTmr[_id].Mode = TMR_ONCE_MODE; /* 1 次性工作模式 */ ENABLE_INT(); /* 开中断 */ }
void bsp_StartAutoTimer(uint8_t _id, uint32_t _period) { if (_id >= TMR_COUNT) { while(1); } DISABLE_INT(); /* 关中断 */ s_tTmr[_id].Count = _period; s_tTmr[_id].PreLoad = _period; s_tTmr[_id].Flag = 0; s_tTmr[_id].Mode = TMR_AUTO_MODE; ENABLE_INT(); }
void bsp_StopTimer(uint8_t _id)
{
if (_id >= TMR_COUNT)
{
/* 打印出错的源代码文件名、函数名称 */
while(1); /* 参数异常,死机等待看门狗复位 */
}
DISABLE_INT(); /* 关中断 */
s_tTmr[_id].Count = 0; /* 实时计数器初值 */
s_tTmr[_id].Flag = 0; /* 定时时间到标志 */
s_tTmr[_id].Mode = TMR_ONCE_MODE; /* 自动工作模式 */
ENABLE_INT(); /* 开中断 */
}
uint8_t bsp_CheckTimer(uint8_t _id) { if (_id >= TMR_COUNT) { return 0; } if (s_tTmr[_id].Flag == 1) { s_tTmr[_id].Flag = 0; return 1; } else { return 0; } }
static void bsp_SoftTimerDec(SOFT_TMR *_tmr) { if (_tmr->Count > 0) { if (--_tmr->Count == 0) { _tmr->Flag = 1; if(_tmr->Mode == TMR_AUTO_MODE) { _tmr->Count = _tmr->PreLoad; } } } } void SysTick_Handler(void) { for (i = 0; i < TMR_COUNT; i++) { bsp_SoftTimerDec(&s_tTmr[i]); } }
本篇通过滴答定时器中断实现了一个方便可移植的多组软件定时器,主要借鉴于安富莱-V7开发板bsp文档,供个人学习用。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。