zoukankan      html  css  js  c++  java
  • 超时事件时间戳

    基于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;

    总结:

  • 相关阅读:
    畅通工程续 dijkstra
    能量项链 区间dp
    机器人军团
    skiing
    数论知识
    灯泡游戏
    60. 第k个排列
    17. 电话号码的字母组合
    101. 对称二叉树
    144. 二叉树的前序遍历
  • 原文地址:https://www.cnblogs.com/linxw-blog/p/14281025.html
Copyright © 2011-2022 走看看