超时事件时间戳

基于STM32F103

步骤:

1、定时器的1ms初始化

 1 //1ms TIMER IRQ 
 2 void Drv_timeout_Init(void)
 3 {
 4     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
 5     NVIC_InitTypeDef NVIC_InitStructure;
 6     RCC_APB1PeriphClockCmd(mBT_timer_Rcc, ENABLE);                      //时钟使能
 7     
 8     TIM_TimeBaseStructure.TIM_Period = mBT_timer_arr;                //设置在下一个更新事件装入活动的自动重装载寄存器周期的值    
 9     TIM_TimeBaseStructure.TIM_Prescaler =mBT_timer_psc;           //设置用来作为TIMx时钟频率除数的预分频值
10     TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;             //设置时钟分割:TDTS = Tck_tim
11     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;         //TIM向上计数模式
12     TIM_TimeBaseInit(mBT_timer_TIM, &TIM_TimeBaseStructure);            //根据指定的参数初始化TIMx的时间基数单位
13  
14     TIM_ITConfig(mBT_timer_TIM,TIM_IT_Update,ENABLE );                  //使能指定的TIM3中断,允许更新中断
15 
16     //中断优先级NVIC设置
17     NVIC_InitStructure.NVIC_IRQChannel = mBT_timer_IRQ;                 //TIM3中断
18     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;           //先占优先级0级
19     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;                 //从优先级3级
20     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                     //IRQ通道被使能
21     NVIC_Init(&NVIC_InitStructure);                                     //初始化NVIC寄存器
22     TIM_Cmd(mBT_timer_TIM, ENABLE);                                     //使能TIMx                     
23 }
24 
25 //定时器中断服务程序
26 void TIM5_IRQHandler()   
27 {   
28     if (TIM_GetITStatus(mBT_timer_TIM, TIM_IT_Update) != RESET)  //检查TIM更新中断发生与否
29     {       
30         Drv_Tmr_1MsTOut_Manage();
31         TIM_ClearITPendingBit(mBT_timer_TIM, TIM_IT_Update );  //清除TIMx更新中断标志 
32     }
33 }

2、结构体初始化

 1 typedef void (*T_TmrOutCallBack)(void);
 2 
 3 typedef enum emTmrOutEvt{
 4 E_TmrOutEvt_BtWkUpCheck, // 超时事件类型,蓝牙唤醒超时
 5 E_TmrOutEvt_BtCmdRsp, // 超时事件类型,蓝牙命令应答交互超时
 6 E_TmrOutEvt_MaxLmt, // 超时事件类型,最大阈值设定
 7 }E_TmrOutEvt;
 8 
 9 //E_TmrOutEvt_BtCmdRsp类超时
10 typedef struct stBt836B_CmdRspTOutRes{
11 BOOL bIsProcDone; // 超时主体是否处理完毕标志位
12 BOOL bIsTOut; // 超时标志位
13 }T_Bt836B_CmdRspTOutRes;
14 
15 typedef struct stTmrOutRes{
16 BOOL bTimeOutFlag;
17 BOOL bUpdateFlag; // 更新标志位
18 UINT16 usUpdateTimeValue; // 待更新的超时数值
19 UINT16 usCurTimeCounter; // 当前定时器计数器
20 T_TmrOutCallBack ptTmrOutProcCallBack; // 超时后回调处理接口
21 BOOL *pbIsNrmlExit; // 主体正常退出超时处理标记位指针
22 }T_TmrOutRes;

3、注册函数及超时类型资源

 1 //local 
 2 T_TmrOutRes atTmrOutRes[E_TmrOutEvt_MaxLmt];
 3 
 4 #if CVIEW("E_TmrOutEvt_BtCmdRsp类")
 5 
 6 T_Bt836B_CmdRspTOutRes tBt836B_CmdRspTOutRes;
 7 
 8 void Bt836B_CmdRspTOut_TOutEvtProc(void)
 9 {
10     tBt836B_CmdRspTOutRes.bIsTOut = TRUE;//已经超时了
11     //LedBilnk();
12     printf("Bt836B_CmdRspTOut_TOutEvtProc
");
13 }
14 
15 void Bt836B_CmdRspTOut_TOutRes_Init(void)
16 {
17     tBt836B_CmdRspTOutRes.bIsProcDone = FALSE;
18     tBt836B_CmdRspTOutRes.bIsTOut = FALSE;
19 }
20 
21 #endif  /*E_TmrOutEvt_BtCmdRsp类*/
22 
23 // E_TmrOutEvt eTmrOutEvt,超时事件类型
24 // UINT16 usTimeOutValue,超时时间窗
25 // T_TmrOutCallBack pfTmrOutProcCallBack,超时后回调处理接口,允许在主体模块中添加简单超时后的处理操作
26 // BOOL *pbIsNrmlExit,主体正常退出超时处理标记位指针,用以在超时管理模块中自主结束超时处理逻辑
27 void Drv_Tmr_1MsTOut_Register(
28     E_TmrOutEvt eTmrOutEvt, UINT16 usTimeOutValue, T_TmrOutCallBack TmrOutProcCallBack, BOOL *pbIsNrmlExit)
29 {
30     // 同步当前超时时间
31     //while(FALSE == atTmrOutRes[eTmrOutEvt].bTimeOutFlag && 0 != atTmrOutRes[eTmrOutEvt].usCurTimeCounter);
32     while( 0 != atTmrOutRes[eTmrOutEvt].usCurTimeCounter);
33     atTmrOutRes[eTmrOutEvt].usUpdateTimeValue = usTimeOutValue;
34     atTmrOutRes[eTmrOutEvt].ptTmrOutProcCallBack = TmrOutProcCallBack;
35     atTmrOutRes[eTmrOutEvt].bUpdateFlag = TRUE;
36     atTmrOutRes[eTmrOutEvt].bTimeOutFlag = FALSE;
37     atTmrOutRes[eTmrOutEvt].pbIsNrmlExit = pbIsNrmlExit;
38 }

4、超时管理

 1 void Drv_Tmr_1MsTOut_Manage(void)
 2 {
 3     UINT8 i=0;
 4     for(i=0; i<E_TmrOutEvt_MaxLmt; i++){
 5         
 6         // 第一次更新超时计数器
 7         if(TRUE == atTmrOutRes[i].bUpdateFlag){
 8             atTmrOutRes[i].bUpdateFlag = FALSE;
 9             atTmrOutRes[i].usCurTimeCounter = atTmrOutRes[i].usUpdateTimeValue;
10             //printf("bUpdateFlag
");
11         }
12         
13         // 此处进行超时处理逻辑
14         if(0 != atTmrOutRes[i].usCurTimeCounter){
15             
16             // 此处判断主体是否正常结束超时流程,并终止超时模块内的超时处理逻辑
17             if(NULL != atTmrOutRes[i].pbIsNrmlExit & (TRUE == *atTmrOutRes[i].pbIsNrmlExit) ){
18                 //printf("pbIsNrmlExit
");
19                 atTmrOutRes[i].usCurTimeCounter = 0; continue;
20                 
21             }
22             
23             atTmrOutRes[i].usCurTimeCounter--;
24             
25             if(0 == atTmrOutRes[i].usCurTimeCounter){
26                 if(NULL != atTmrOutRes[i].ptTmrOutProcCallBack){
27                     //printf("ptTmr
");
28                     atTmrOutRes[i].ptTmrOutProcCallBack();
29                     atTmrOutRes[i].bTimeOutFlag = TRUE;
30                 }
31             }
32         }
33     }
34 }

5、demo

1void Bt836B_CmdRspTOutDemo(void)
{
    Drv_Bt836B_SendCmd();
    
    // 初始化主体超时标志位缓存
    Bt836B_CmdRspTOutDemo_TOutRes_Init();
    // 初始化主体超时处理模块资源
    Drv_Tmr_1MsTOut_Register(E_TmrOutEvt_BtCmdRsp, 1000, Bt836B_CmdRspTOutDemo_TOutEvtProc, &tBt836B_CmdRspTOutDemoRes.bIsProcDone);
    // 主体超时处理等待逻辑
    while(FALSE == tBt836B_CmdRspTOutDemoRes.bIsTOut){
        // 此处接收到Rsp以后通过bIsProcDone标志位告知超时模块终止倒计时处理
        if(TRUE == Drv_Bt836B_GetRsp()){ tBt836B_CmdRspTOutDemoRes.bIsProcDone = TRUE; break;}
    }
    // 异常超时流程
    if(TRUE == tBt836B_CmdRspTOutDemoRes.bIsTOut){
        // ......
    }
}
 
2// 初始化主体超时标志位缓存
    Bt836B_CmdRspTOut_TOutRes_Init();
    
    // 初始化主体超时处理模块资源
    Drv_Tmr_1MsTOut_Register(E_TmrOutEvt_BtCmdRsp, 100, Bt836B_CmdRspTOut_TOutEvtProc, &tBt836B_CmdRspTOutRes.bIsProcDone);        
    USART2_printf("AT+ADDR
"); 

    // 主体超时处理等待逻辑
    //g_bBT_RSP_message_dispatcher_OK_Clear();
    while(FALSE == tBt836B_CmdRspTOutRes.bIsTOut){
        // 此处接收到Rsp以后通过bIsProcDone标志位告知超时模块终止倒计时处理
        if(TRUE == g_bBT_RSP_message_dispatcher_OK_Get())
        {
            Rsp_paresize=BT_836B_AT_GET("ADDR")->AT_GET_RunRsp(&ptRsp->aucRsp[0],Rsp_paresize); 
            tBt836B_CmdRspTOutRes.bIsProcDone = TRUE; 
            break;
        }
    }  
    // 异常超时流程
    if(TRUE == tBt836B_CmdRspTOutRes.bIsTOut){
        //printf("异常超时流程
");
    }
    return usRspParaLen;

总结:

原文地址:https://www.cnblogs.com/linxw-blog/p/14281025.html