1. 程式人生 > >stm32滴答定時器構建多組軟體定時器

stm32滴答定時器構建多組軟體定時器

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];再對每一組定時器進行管理即可。