stm32有很多組定時器,處理一般業務已經足夠用了。
但是殺雞焉用牛刀,對時間精度要求不高的場合可以考慮使用軟件定時器,使用方便,快捷。
怎麼實現呢?其實並不難,就是使用回調函數即可。
1. 先將使用到的參數用結構體封裝一下吧
#define get_time HAL_GetTick()
typedef void (*pfunc)(u8);
enum task_tmr_t{STMR_A=1,STMR_B,STMR_C,STMR_D,STMR_E};
typedef struct STMR_t_{
u32 start_value;
u32 overtime_value;
u8 timer_id;
u8 busy;
u8 repeat;
u8 param;
}stmr_TypeDef;
2. 將要使用的軟件定時器註冊一下
pfunc tmr_func;
stmr_TypeDef soft_tmr;
bool stmr_reg(u8 tmr_id, u32 overtime, u8 repeat, pfunc ptmr, u8 param){
if(false == soft_tmr.busy){
soft_tmr.timer_id = tmr_id;
soft_tmr.start_value = get_time;
soft_tmr.overtime_value = overtime;
soft_tmr.repeat = repeat;
soft_tmr.busy = true;
soft_tmr.param = param;
tmr_func = ptmr;
return true;
}
return false;
}
3. 回調一下
void stmr_isr(void){
tmr_func(soft_tmr.param);
if(soft_tmr.repeat > 0){
soft_tmr.repeat--;
soft_tmr.start_value = geit_time;
}
else{
memset(&soft_tmr, 0, sizeof(soft_tmr));
tmr_func = NULL;
}
}
4. 要回調的任務函數
void stmr_stop(u8 tmr_id){
if(true == soft_tmr.busy){
if((tmr_id == soft_tmr.timer_id) || (tmr_id ==STMR_ALL)){
memset(&soft_tmr, 0, sizeof(soft_tmr));
tmr_func = NULL;
}
}
}
void STMR_A_task(void){
printf("task a running\n");
}
void STMR_B_task(void){
printf("task b ruinning\n");
}
void STMR_C_task(void){
printf("task c ruinning\n");
}
5. 主程序框架
int main(void){
BSP_Init();
stmr_reg( ... );
while(1){
...
if(true == soft_tmr.busy){
if(get_time - soft_tmr.start_value > soft_tmr.overtime_value)
stmr_isr();
}
...
}
}
經過測試,軟件定時器還是比較穩定的,上面的程序中雖然定義了五個定時器,但是隻能分時複用,不能同時進行疊加使用。但是稍加改動就可以進行疊加使用了。只需把pfunc tmr_func;改爲pfunc tmr_func[STMR_CNT];再對每一組定時器進行管理即可。