#include "Key.h" /*------------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------*/ /*-----按键服务函数调用周期。单位ms--------*/ #define KEY_CALL_CYCLE 10U /*-----------------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------------*/ typedef struct { uint16_t u16KeyShortPressTime; /*¶Ì°´¼ì²âʱ¼ä*/ uint16_t u16KeyLongPressTime; /*³¤°´¼ì²âʱ¼ä*/ uint16_t u16KeySuperLongPressTime; /*³¬³¤°´¼ì²âʱ¼ä*/ uint16_t u16KeyLoosenTime; /*ËÉ¿ª¼ì²âʱ¼ä*/ uint16_t u16KeyValidOFFTime; /*ÓÐЧOFF¼ì²âʱ¼ä*/ uint16_t u16KeyValidONTime; /*ÓÐЧON¼ì²âʱ¼ä*/ } Key_Parameter_st_t; typedef struct { Key_Real_Status_en_t enKeyTypeLast; uint16_t u16KeyInvalidTimeCount; uint16_t u16KeyValidTimeCount; uint16_t u16KeyFirstIGNTimeRecord; Key_IGN_en_t enKeyIGNFirstStatus; Key_IGN_en_t enKeyIGNStatusLast; uint8_t u8KeyIGNChangeFlag; uint16_t u16KeyIGNTimeCount; } Key_Ctr_st_t; /*------------------------------------------------------------------------------------------*/ #pragma ghs section bss = ".myNonInitArea" static Key_Parameter_st_t stKeyParameter; #pragma ghs section bss = default static Key_Ctr_st_t stKeyCtrVariate[KEY_NUM_MAX]; // static Key_IGN_en_t enKeyIGNFirstStatus = KEY_IG_INVALID; // static Key_IGN_en_t enKeyIGNStatusLast = KEY_IG_INVALID; // static uint8_t u8KeyIGNChangeFlag = 0U; // static uint16_t u16KeyIGNTimeCount; /*-----------------------------------------------------------------------------------------*/ static void Key_Process(Key_Num_en_t enKeyIndex); void Key_Service(void); void Key_Init(void); Key_Set_en_t Key_Parameter_Set_Short_Press_Time(uint16_t u16Time); Key_Set_en_t Key_Parameter_Set_Long_Press_Time(uint16_t u16Time); Key_Set_en_t Key_Parameter_Set_Super_Long_Press_Time(uint16_t u16Time); Key_Set_en_t Key_Parameter_Set_OFF_Press_Time(uint16_t u16Time); Key_Set_en_t Key_Parameter_Set_ON_Press_Time(uint16_t u16Time); /*-----------------------------------------------------*/ static void Key_Process(Key_Num_en_t enKeyIndex) { if (enKeyIndex < KEY_NUM_MAX) { /*Key_Real_Status_en_t enKeyRealType = (*stKeyAttribute[enKeyIndex].penKeyRealStatus);*/ Key_Real_Status_en_t enKeyRealType = KEY_CAN_NONE; Key_IGN_en_t enKeyIGNRealStatus = Key_Get_IGN_Status(); if (stKeyAttribute[enKeyIndex].pfnKeyReadStatusCallBack != 0U) { enKeyRealType = stKeyAttribute[enKeyIndex].pfnKeyReadStatusCallBack(); } /*CAN°´¼ü*/ if (stKeyAttribute[enKeyIndex].enKeyType == KEY_NO_DEBOUNCE_RISE) { if (enKeyRealType <= KEY_CAN_LONG_PRESS_NOT_RELEASE) { if (stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack != 0U) { if ((stKeyCtrVariate[enKeyIndex].enKeyTypeLast == KEY_CAN_NONE) && (enKeyRealType == KEY_CAN_SHORT_PRESS)) { stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_SHORT_PRESS); } else if ((stKeyCtrVariate[enKeyIndex].enKeyTypeLast == KEY_CAN_NONE) && (enKeyRealType == KEY_CAN_LONG_PRESS)) { stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_LONG_PRESS); } else if ((stKeyCtrVariate[enKeyIndex].enKeyTypeLast == KEY_CAN_NONE) && (enKeyRealType == KEY_CAN_LONG_PRESS_NOT_RELEASE)) { stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_SUPER_LONG_PRESS); } else { stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_NONE); } } stKeyCtrVariate[enKeyIndex].enKeyTypeLast = enKeyRealType; } else { stKeyCtrVariate[enKeyIndex].enKeyTypeLast = KEY_CAN_NONE; } } else if (stKeyAttribute[enKeyIndex].enKeyType == KEY_NO_DEBOUNCE_FALL) { if (enKeyRealType <= KEY_CAN_LONG_PRESS_NOT_RELEASE) { if (stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack != 0U) { if ((stKeyCtrVariate[enKeyIndex].enKeyTypeLast == KEY_CAN_SHORT_PRESS) && (enKeyRealType == KEY_CAN_NONE)) { stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_SHORT_PRESS); } else if ((stKeyCtrVariate[enKeyIndex].enKeyTypeLast == KEY_CAN_LONG_PRESS) && (enKeyRealType == KEY_CAN_NONE)) { stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_LONG_PRESS); } else if ((stKeyCtrVariate[enKeyIndex].enKeyTypeLast == KEY_CAN_LONG_PRESS_NOT_RELEASE) && (enKeyRealType == KEY_CAN_NONE)) { stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_SUPER_LONG_PRESS); } else { stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_NONE); } } stKeyCtrVariate[enKeyIndex].enKeyTypeLast = enKeyRealType; } else { stKeyCtrVariate[enKeyIndex].enKeyTypeLast = KEY_CAN_NONE; } } /*Ó²Ïß°´¼ü*/ else if (stKeyAttribute[enKeyIndex].enKeyType == KEY_NEED_DEBOUNCE_NORMAL) { if (enKeyRealType == KEY_LINE_LOOSEN) /*空闲*/ { if (stKeyCtrVariate[enKeyIndex].u16KeyInvalidTimeCount <= stKeyParameter.u16KeyLoosenTime) { stKeyCtrVariate[enKeyIndex].u16KeyInvalidTimeCount += KEY_CALL_CYCLE; } else { stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount = 0U; stKeyCtrVariate[enKeyIndex].enKeyTypeLast = KEY_LINE_LOOSEN; stKeyCtrVariate[enKeyIndex].u16KeyFirstIGNTimeRecord = 0U; stKeyCtrVariate[enKeyIndex].enKeyIGNFirstStatus = KEY_IG_INVALID; stKeyCtrVariate[enKeyIndex].enKeyIGNStatusLast = KEY_IG_INVALID; stKeyCtrVariate[enKeyIndex].u8KeyIGNChangeFlag = 0U; stKeyCtrVariate[enKeyIndex].u16KeyIGNTimeCount = 0U; } if ((stKeyCtrVariate[enKeyIndex].u16KeyInvalidTimeCount >= stKeyParameter.u16KeyLoosenTime) && (stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount >= stKeyParameter.u16KeyShortPressTime) && (stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount < stKeyParameter.u16KeyLongPressTime)) { stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount = 0U; /* call back */ if (stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack != 0U) { stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_SHORT_PRESS); } } } else if (enKeyRealType == KEY_LINE_PRESS) /*按键按下*/ { if (stKeyCtrVariate[enKeyIndex].enKeyTypeLast != enKeyRealType) { stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount = 0U; stKeyCtrVariate[enKeyIndex].u16KeyFirstIGNTimeRecord = 0U; stKeyCtrVariate[enKeyIndex].enKeyTypeLast = enKeyRealType; stKeyCtrVariate[enKeyIndex].u16KeyIGNTimeCount = 0U; stKeyCtrVariate[enKeyIndex].enKeyIGNFirstStatus = enKeyIGNRealStatus; stKeyCtrVariate[enKeyIndex].enKeyIGNStatusLast = enKeyIGNRealStatus; } else { if (stKeyCtrVariate[enKeyIndex].enKeyIGNStatusLast != enKeyIGNRealStatus) { stKeyCtrVariate[enKeyIndex].enKeyIGNStatusLast = enKeyIGNRealStatus; if (stKeyCtrVariate[enKeyIndex].enKeyIGNFirstStatus != enKeyIGNRealStatus) { stKeyCtrVariate[enKeyIndex].u16KeyFirstIGNTimeRecord = stKeyCtrVariate[enKeyIndex].u16KeyIGNTimeCount; } stKeyCtrVariate[enKeyIndex].u16KeyIGNTimeCount = 0U; } else { if (stKeyCtrVariate[enKeyIndex].u16KeyIGNTimeCount < 0xFFF0U) { stKeyCtrVariate[enKeyIndex].u16KeyIGNTimeCount += KEY_CALL_CYCLE; } } if (stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount < 0xFFF0U) { stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount += KEY_CALL_CYCLE; } if (stKeyCtrVariate[enKeyIndex].enKeyIGNFirstStatus != enKeyIGNRealStatus) { stKeyCtrVariate[enKeyIndex].u8KeyIGNChangeFlag = 1U; } if (stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount >= stKeyParameter.u16KeyShortPressTime) { // stKeyCtrVariate[enKeyIndex].u16KeyInvalidTimeCount = 0U; } stKeyCtrVariate[enKeyIndex].u16KeyInvalidTimeCount = 0U; if (stKeyCtrVariate[enKeyIndex].u8KeyIGNChangeFlag == 0U) { if (stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount >= stKeyParameter.u16KeySuperLongPressTime) { if (stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack != 0U) { stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_SUPER_LONG_PRESS); } } else if (stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount >= stKeyParameter.u16KeyLongPressTime) { if (stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack != 0U) { stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_LONG_PRESS); } } } else { if (stKeyCtrVariate[enKeyIndex].enKeyIGNFirstStatus == KEY_IG_OFF) { if (enKeyIGNRealStatus == KEY_IG_ON) { if ((stKeyCtrVariate[enKeyIndex].u16KeyFirstIGNTimeRecord >= stKeyParameter.u16KeyValidOFFTime) && (stKeyCtrVariate[enKeyIndex].u16KeyIGNTimeCount >= stKeyParameter.u16KeyValidONTime)) { if (stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack != 0U) { stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_OFF_TO_ON); } stKeyCtrVariate[enKeyIndex].u16KeyFirstIGNTimeRecord = 0U; } } } else if (stKeyCtrVariate[enKeyIndex].enKeyIGNFirstStatus == KEY_IG_ON) { if (enKeyIGNRealStatus == KEY_IG_OFF) { if ((stKeyCtrVariate[enKeyIndex].u16KeyFirstIGNTimeRecord >= stKeyParameter.u16KeyValidONTime) && (stKeyCtrVariate[enKeyIndex].u16KeyIGNTimeCount >= stKeyParameter.u16KeyValidOFFTime)) { if (stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack != 0U) { stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_ON_TO_OFF); } stKeyCtrVariate[enKeyIndex].u16KeyFirstIGNTimeRecord = 0U; } } } } } } else { /*ERROR*/ stKeyCtrVariate[enKeyIndex].u16KeyInvalidTimeCount = 0U; stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount = 0U; stKeyCtrVariate[enKeyIndex].enKeyTypeLast = (Key_Real_Status_en_t)0U; } } else { } } } /*10ms调用一次*/ void Key_Service(void) { uint8_t i = 0U; for (i = 0U; i < KEY_NUM_MAX; i++) { Key_Process((Key_Num_en_t)i); /*Key_Num_en_t*/ } } /*首次上电时调用一次即可*/ void Key_Init(void) { uint8_t i = 0U; for (i = 0U; i < KEY_NUM_MAX; i++) { stKeyCtrVariate[i].enKeyTypeLast = KEY_CAN_NONE; stKeyCtrVariate[i].u16KeyInvalidTimeCount = 0U; stKeyCtrVariate[i].u16KeyValidTimeCount = 0U; stKeyCtrVariate[i].u16KeyFirstIGNTimeRecord = 0U; stKeyCtrVariate[i].enKeyIGNFirstStatus = KEY_IG_INVALID; stKeyCtrVariate[i].enKeyIGNStatusLast = KEY_IG_INVALID; stKeyCtrVariate[i].u8KeyIGNChangeFlag = 0U; stKeyCtrVariate[i].u16KeyIGNTimeCount = 0U; } /*按键动作时间*/ /*342 4.1 短按/长按操作的判断标准(判定时间):短按;40ms以上,未到800ms,长按;800ms以上*/ stKeyParameter.u16KeyLoosenTime = 100U; stKeyParameter.u16KeyShortPressTime = 40U; stKeyParameter.u16KeyLongPressTime = 1000U; stKeyParameter.u16KeySuperLongPressTime = 10000U; stKeyParameter.u16KeyValidOFFTime = 200U; /*按键动作时间*/ stKeyParameter.u16KeyValidONTime = 1000U; } /*对于硬线按键而言,判断短按的时间参数*/ Key_Set_en_t Key_Parameter_Set_Short_Press_Time(uint16_t u16Time) { Key_Set_en_t enKeySetResult = KEY_SET_OK; if (u16Time < stKeyParameter.u16KeyLoosenTime) { enKeySetResult = KEY_SET_ERROR; } else if (u16Time > stKeyParameter.u16KeyLongPressTime) { enKeySetResult = KEY_SET_ERROR; } else { stKeyParameter.u16KeyShortPressTime = u16Time; } return enKeySetResult; } /*对于硬线按键而言,判断长按的时间参数*/ Key_Set_en_t Key_Parameter_Set_Long_Press_Time(uint16_t u16Time) { Key_Set_en_t enKeySetResult = KEY_SET_OK; if (u16Time < stKeyParameter.u16KeyShortPressTime) { enKeySetResult = KEY_SET_ERROR; } else if (u16Time > stKeyParameter.u16KeySuperLongPressTime) { enKeySetResult = KEY_SET_ERROR; } else { stKeyParameter.u16KeyLongPressTime = u16Time; } return enKeySetResult; } /*对于硬线按键而言,判断超长按的时间参数*/ Key_Set_en_t Key_Parameter_Set_Super_Long_Press_Time(uint16_t u16Time) { Key_Set_en_t enKeySetResult = KEY_SET_OK; if (u16Time < stKeyParameter.u16KeyLongPressTime) { enKeySetResult = KEY_SET_ERROR; } else { stKeyParameter.u16KeySuperLongPressTime = u16Time; } return enKeySetResult; }