ZDBMS/code_drv/KeyScan.c

126 lines
4.6 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/********************************************************************************
Copyright (C), Sinowealth Electronic. Ltd.
Author: Sino
Version: V0.0
Date: 2020/04/26
History:
V2.0 2020/04/26 Preliminary
********************************************************************************/
#include "Main.h"
BOOL bKeyFlg;
U16 data uiKeyValidCnt;
U16 data uiKeyInvalidCnt;
U8 data ucKeyValue;
U8 data ucKeyOldValue;
U8 data ucKeyValueBK;
/*************************************************************************************************
* 函数名: ScanKey
* 参 数: 无
* 返回值: 无
* 描 述: 1. 短按时,按键必须弹起后,才能识别为短按按键。
2. 长按和长按持续,按键无需弹起,就能识别为长按按键或长按持续。
3. 按键有优先级,多个按键被同时按下时,仅处理第一个被按下的按键。
4.同一个按键一直被按着,先触发长按,后触发长按持续,长按和长按持续都会被触发。
5. bKeyFlg当检测到有效按键后置位1
6. ucKeyValue高4bit表示按键状态短按、长按、长按继续、长按结束低4bit表示键值
7. ucKeyValueBK 保存按键状态无按键、有按键1、有按键2
8. uiKeyValidCnt 按键按下滤波计数器
9. uiKeyInvalidCnt 按键弹起滤波计数器
*************************************************************************************************/
void KeyScan(void)
{
if(!bKeyFlg)
{
ucKeyValueBK = KEYVAL_NULL; //先默认无按键按下
#ifdef KEY_NUM1_DEF //1个按键
if(!KEY_1_IO_RD)
{
ucKeyValueBK = KEYVAL_1;
}
#endif
#ifdef KEY_NUM2_DEF //2个按键
if(!KEY_1_IO_RD)
{
ucKeyValueBK = KEYVAL_1; //按键按下后,获取新键值
}
else if(!KEY_2_IO_RD)
{
ucKeyValueBK = KEYVAL_2; //按键按下后,获取新键值
}
#endif
#ifdef KEY_NUM3_DEF //3个按键
if(!KEY_1_IO_RD)
{
ucKeyValueBK = KEYVAL_1;
}
else if(!KEY_2_IO_RD)
{
ucKeyValueBK = KEYVAL_2;
}
else if(!KEY_3_IO_RD)
{
ucKeyValueBK = KEYVAL_3;
}
#endif
if(ucKeyValueBK != ucKeyOldValue) //ucKeyValueBK中存放了新的键值如果新键值跟老键值不同
{
uiKeyInvalidCnt++; //按键弹起滤波计数器当按键第一次按下时会清0当按键弹起时会一直计数
if(uiKeyValidCnt >= KEY_S_TIME) //按键按下滤波计数器,当按键被按下后一直计数,按键弹起后停止计数
{ //按下又弹起且未触发长按时如果uiKeyValidCnt >= KEY_S_TIME则可能是短按
if(uiKeyInvalidCnt >= KEY_S_TIME) //按键弹起滤波计数器达到短按消抖时间,则认为是一次按下和弹起都消抖过的有效按键
{
if(uiKeyValidCnt >= KEY_L_TIME) //在此区分是短按,还是长按结束
{
ucKeyValue = ucKeyOldValue | KEY_STATE_LE; //按下的时间超过长按时间,认为是长按已经结束了。该状态目前未使用
}
else
{
ucKeyValue = ucKeyOldValue | KEY_STATE_S; //按下的时间没有超过长按时间,认为是一次有效的短按按键
}
bKeyFlg = 1; //短按有效,暂停按键检测,去处理按键事件
goto scanend;
}
// else
// {
// uiKeyValidCnt++; //该行应该删掉否则当KEY_S_TIME等于KEY_L_TIME的一半及以上时会把短按误识别为长按结束。
// }
}
else //每当按键按下的时间连短按消抖时间都不够时,认为是无效按键,重新初始化
{
goto scanend;
}
}
else //ucKeyValueBK中存放了新的键值新键值跟老键值相同说明是同一个按键。
{
if(ucKeyValueBK != KEYVAL_NULL) //继续处理被按下的按键
{
uiKeyInvalidCnt = 0; //清弹起计数器
uiKeyValidCnt++; //累加按下计数器
if(uiKeyValidCnt == KEY_L_TIME) //当按下时间达到长按滤波时间时,认为此按键为长按键
{
ucKeyValue = ucKeyOldValue | KEY_STATE_L;
bKeyFlg = 1;
}
else if(uiKeyValidCnt == KEY_LC_TIME) //当按下时间达到长按持续滤波时间时,认为此按键为长按持续
{
uiKeyValidCnt = KEY_L_TIME;
ucKeyValue = ucKeyOldValue | KEY_STATE_LC;
bKeyFlg = 1;
}
}
else //新键值是空键值,说明全部按键都释放了
{
ucKeyValue = KEYVAL_NULL; //全部按键都释放了,需要重新初始化检测寄存器
scanend:
uiKeyValidCnt = 0;
uiKeyInvalidCnt = 0;
ucKeyOldValue = ucKeyValueBK;
}
}
}
}