- /************************************************************************************************************
- * 文 件 名 : bsp_Key.c
- * 负 责 人 : lll
- * 创建日期 : 2017年11月28日
- * 文件描述 : 按键扫描与按键事件处理
- * 版权说明 : Copyright (c) 2008-2017 xx xx xx xx 技术有限公司
- * 其 他 :
- * 修改日志 :
- **************************************************************************************************************/
- #include <stdio.h>
- #include <stdlib.h>
- #include "bsp_Vacuum260.h"
- #include "bsp_Key.h"
- #include "bsp_LED.h"
- #include "bsp_74hc595.h"
- typedef struct
- {
- void (*KeyEventFunc)(void);
- UINT16 LongTime; /* 长按键生效时间,0表示非长按键 */
- UINT8 ReentryTime; /* 长按键重复生效时间,0表示键值不重复生效 */
- UINT8 FiltTime; /* 去抖滤波时间 */
- UINT8 KeyVal; /* 按键起始键值,每个按键有三个键值,enum定义依次为“按下”“弹起”“长按” */
-
- }KeyElem_TypeDef;
- // 按键元素表
- KeyElem_TypeDef const KeyElem[KEY_QTY] = {
- { Key_StopKey, 600, 0, 4, KEY_0_DOWN },
- { Key_VacuumTimeSet, 0, 0, 4, KEY_1_DOWN },
- { Key_SealTimeSet, 0, 0, 4, KEY_2_DOWN },
- { Key_DigitInc, 150, 20, 4, KEY_3_DOWN },
- { Key_DigitDec, 150, 20, 4, KEY_4_DOWN },
- { Key_HeatLevelSet, 0, 0, 4, KEY_5_DOWN },
- { Key_SealTimeMaxInc, 150, 20, 4, KEY_6_DOWN }, // KEY_0和KEY_3组合
- { Key_SealTimeMaxDec, 150, 20, 4, KEY_7_DOWN } // KEY_0和KEY_4组合
- };
- KeyMode_TypeDef KeyMode;
- KeyMsg_TypeDef KeyMsg;
- KeyQueue_TypeDef KeyQueue; /* 键值循环队列结构变量 */
- QelemType KeyCode[KEY_QTY]; /* 循环队列键值数组 */
- persistent KeyVar_TypeDef KeyVar[KEY_QTY]; /* 按键扫描结构变量 */
-
- persistent volatile UINT8 KeysState;
- persistent volatile UINT8 Key_SetPoint;
- persistent volatile UINT8 *gParamPtr; /* 读写参数缓存区指针 */
- extern UINT8 ByteMod( UINT8 dividend, UINT8 divisor );
- extern UINT8 ByteDiv( UINT8 dividend, UINT8 divisor );
- /***********************************************************************************************************
- * [url=home.php?mod=space&uid=247401]@brief[/url] 按键参数初始化
- ************************************************************************************************************/
- void Key_Init(void)
- {
- UINT8 i;
-
- KeyQueue.Buf = KeyCode;
- KeyQueue.rear = 0;
- KeyQueue.front = 0;
-
- for( i = 0; i < KEY_QTY; i++ )
- {
- KeyVar[i].KeyGet = FALSE;
- KeyVar[i].KeyState = KEY_UP;
- KeyVar[i].FiltCnt = 0;
- KeyVar[i].LongCnt = 0;
- KeyVar[i].ReentryCnt = 0;
- }
- Key_SetPoint = NO;
- KeyMode.bMode = 0; //0=直接加减方式,1=位选加减方式
- }
- /**************************************************************************************************************
- * @brief 按键队列压入键值
- * @param _KeyCode
- **************************************************************************************************************/
- void Key_QueueIn( UINT8 _KeyCode )
- {
- KeyQueue.Buf[KeyQueue.rear] = _KeyCode;
- if( ++KeyQueue.rear >= KEY_QTY )
- {
- KeyQueue.rear = 0;
- }
- }
- /**************************************************************************************************************
- * @brief 按键队列弹出键值
- * [url=home.php?mod=space&uid=266161]@return[/url] 键值
- **************************************************************************************************************/
- UINT8 Key_QueueOut( void )
- {
- UINT8 ret;
- if( KeyQueue.front == KeyQueue.rear )
- {
- return KEY_NONE;
- }
- else
- {
- ret = KeyQueue.Buf[KeyQueue.front];
- if( ++KeyQueue.front >= KEY_QTY )
- {
- KeyQueue.front = 0;
- }
- return ret;
- }
- }
- /**************************************************************************************************************
- * @brief 按键扫描,获取按键ID
- * 矩阵式扫描,RB7,RB6 为扫描读取口;RB2,RB1,RB0通过NPN三极管反向后作为键盘的扫描口。
- * @Param pPORTx:键盘扫描所在端口指针
- * pKeyID: 按键ID顺序存放数组指针
- * [url=home.php?mod=space&uid=536309]@NOTE[/url] 按键引脚硬件分布
- * 矩阵式扫描,RB7,RB6 为扫描读取口;RB2,RB1,RB0通过NPN三极管反向后作为键盘的扫描口。
- *
- * RB0_____。_____|_____________|____________
- * |0 |3
- * RB1_____。_____|_____________|____________
- * |1 |4
- * RB2_____。_____|_____________|____________
- * |2 |5
- * RB6____________| |
- * |
- * RB7__________________________|
- **************************************************************************************************************/
- /* 根据硬件情况,扫描从低位左移,检测从高位右移,因此按键ID表的排列顺序是3,0,4,1, 5,2 */
- const UINT8 KeyID_Table[3][2] = { { 3, 0 },{ 4, 1 },{ 5, 2 } };
- /* 按键扫描后,按键ID按0-N的排列顺序存入数组 */
- UINT8 KeyID[KEY_QTY] = { 0 ,1, 2, 3, 4, 5, 6, 7 };
- static void GetKeyID( PORT_TypeDef *pPORTx, UINT8 *pKeyID )
- {
- UINT8 idx, i, j;
- for( i = 0; i < KEY_QTY; i++ )
- {
- pKeyID[i] = 255; /* 255表示按键未按下 */
- }
- for( i = 0; i < 3; i++ ) /* 扫描所有按键 */
- {
- *pPORTx &= ~KEY_SCAN_PINS_SET;
- NOP();
- NOP();
- *pPORTx |= 1 << i;
- NOP();
- NOP();
- for ( j = 0; j < 2; j++ )
- {
- if( ( *pPORTx & ( 0x80 >> j ) ) == 0 )
- {
- idx = KeyID_Table[i][j];
- pKeyID[idx] = KeyID_Table[i][j]; /* 按键ID按0-N的顺序存入 数组 */
- }
- }
- }
- }
- /**************************************************************************************************************
- * @brief 单个按键扫描
- * 完成按键去抖,获取按键“按下”“弹起”“长按”三个键值,并将键值压入队列。
- * @Param idx:按键索引,表示扫描哪一个按键
- * KeyID:
- **************************************************************************************************************/
- static void GetKeyValue( UINT8 idx, UINT8 keyID )
- {
- KeyVar_TypeDef *pKeyVar;
- KeyElem_TypeDef const *pKeyElem;
-
- pKeyVar = &KeyVar[idx];
- pKeyElem = &KeyElem[idx];
-
- if( keyID != 255 )
- {
- if( pKeyVar->FiltCnt < pKeyElem->FiltTime )
- {
- pKeyVar->FiltCnt = KeyElem->FiltTime;
- }
- if( pKeyVar->FiltCnt < 2 * KeyElem->FiltTime )
- {
- pKeyVar->FiltCnt++;
- }
- else
- {
- /* 如果长按时间设置大于0,说明是长按键 */
- if( pKeyElem->LongTime > 0 )
- {
- if( pKeyVar->LongCnt < pKeyElem->LongTime )
- {
- if( ++pKeyVar->LongCnt == pKeyElem->LongTime )
- {
- pKeyVar->KeyState = LONG_DOWN;
- Key_QueueIn( pKeyElem->KeyVal + 2 ); /* 获取当前按键“长按”键值,一次按下只获取一次 */
- }
- }
- else
- {
- /* 如果键值重复生效时间设置大于0,说明需要重复获取键值 */
- if( pKeyElem->ReentryTime > 0 )
- {
- if( ++pKeyVar->ReentryCnt > pKeyElem->ReentryTime )
- {
- pKeyVar->ReentryCnt = 0;
- pKeyVar->KeyState = KEY_DOWN;
- Key_QueueIn( pKeyElem->KeyVal ); /* 长按键重复获取“按下”键值 */
- }
- }
-
- }
- }
- if( pKeyVar->KeyGet == FALSE ) /* 非长按键一次按下只获取一次“按下”键值 */
- {
- pKeyVar->KeyGet = TRUE;
- pKeyVar->KeyState = KEY_DOWN;
- Key_QueueIn( pKeyElem->KeyVal ); /* 当前按键“按下”键值压入按键队列 */
- }
- }
- }
- else/* 判断按键释放 */
- {
- if( pKeyVar->FiltCnt > KeyElem->FiltTime )
- {
- pKeyVar->FiltCnt = KeyElem->FiltTime;
- }
- if( pKeyVar->FiltCnt > 0 )
- {
- pKeyVar->FiltCnt--;
- }
- else
- {
- if( pKeyVar->KeyGet == TRUE ) /* 当前按键“弹起”键值只获取一次 */
- {
- pKeyVar->KeyGet = FALSE;
- Key_QueueIn( pKeyElem->KeyVal + 1 ); /* 当前按键“弹起”键值压入按键队列 */
- }
- pKeyVar->LongCnt = 0;
- pKeyVar->ReentryCnt = 0;
- pKeyVar->KeyState = KEY_UP;
- }
- }
- }
- /**************************************************************************************************************
- * @brief 按键扫描函数
- * 矩阵式扫描,RB7,RB6 为扫描读取口;RB2,RB1,RB0反向后作为键盘的行扫描。
- * @note RB2,RB1,RB0反向后也是数码管和 LED的位驱动口,因此键盘扫描前要先保存
- * 扫描端口的位值,扫描结束后还原。
- * @Param *PORTx 键盘扫描所在端口
- **************************************************************************************************************/
- void KeyScan( PORT_TypeDef *pPORTx )
- {
- UINT8 i;
- UINT8 PortKeep;
- C595_Pin_OE = 1; /* 关闭 74ls595 三态缓冲输出 */
- PortKeep = *pPORTx; /* 保存扫描端口 */
-
- GetKeyID( pPORTx, KeyID ); /* 获取按键ID */
-
- *pPORTx = PortKeep; /* 还原 PORT 口 */
- C595_Pin_OE = 0; /* 允许 74595 三态缓冲输出 */
-
- // 组合键ID
- if( ( KeyID[0] != 255 ) && ( KeyID[3] != 255 ) )
- {
- KeyID[6] = 6;
- KeyID[3] = 255;
- }
- if( ( KeyID[0] != 255 ) && ( KeyID[4] != 255 ) )
- {
- KeyID[7] = 7;
- KeyID[4] = 255;
- }
- KeysState = 0;
- for( i = 0; i < KEY_QTY; i++ )
- {
- GetKeyValue( i, KeyID[i] );
- KeysState |= KeyVar[i].KeyState;
- }
- }
- /*************************************************************************************************************
- * @brief 按键事件处理函数
- * 采用状态机判断键值,根据键值调用相应的按键事件函数,键值由按键队列弹出。
- *************************************************************************************************************/
- void KeyEventFunc( void )
- {
- switch( Key_QueueOut( ) ){
- case KEY_0_DOWN:
- KeyElem[0].KeyEventFunc();
- break;
- case KEY_0_LONG:
- Key_SetPoint = SET_SEAL_MAX;
- DispBuffer[DPYCC_C1_TENS] = Segment[ ByteDiv( ParamBuf[P_SEAL_MAX_IDX], 10 ) ] | 0x80;
- DispBuffer[DPYCC_C2_UNIT] = Segment[ ByteMod( ParamBuf[P_SEAL_MAX_IDX], 10 ) ];
- BeepCtrl = SIGNAL;
- break;
- case KEY_0_UP:
- if( Key_SetPoint == SET_SEAL_MAX )
- {
- KeyMsg.EnterKey = YES;
- Key_SetPoint = NONE;
- }
- break;
- case KEY_1_DOWN:
- KeyElem[1].KeyEventFunc();
- break;
- case KEY_2_DOWN:
- KeyElem[2].KeyEventFunc();
- break;
- case KEY_3_DOWN:
- KeyElem[3].KeyEventFunc();
- break;
- case KEY_4_DOWN:
- KeyElem[4].KeyEventFunc();
- break;
- case KEY_5_DOWN:
- KeyElem[5].KeyEventFunc();
- break;
- case KEY_6_DOWN:
- KeyElem[6].KeyEventFunc();
- break;
- case KEY_7_DOWN:
- KeyElem[7].KeyEventFunc();
- break;
- default:
- break;
- }
- }