📄 hw_adckey.c
字号:
/******************************************************************/
/* Copyright (C) 2007 ROCK-CHIPS FUZHOU . All Rights Reserved. */
/*******************************************************************
File : hw_adckey.c
Desc : ADC Keyboard接口函数的实现
Author : huangxinyu
Date : 2007-09-20
Notes :
$Log: hw_adckey.c,v $
Revision 1.5 2008/06/25 06:24:02 HSL
修改按键检测流程,按键检测统一集中在 RockKeyScanning 函数里面.
Revision 1.4 2008/06/23 09:54:05 HSL
增加 AD按键的支持,修改按键消息发送和长按检测接口.
Revision 1.3 2008/06/19 04:43:32 Administrator
代码整理!
Revision 1.2 2008/06/12 10:17:59 HSL
根据新的按键检测流程修改驱动部分接口.
Revision 1.1.1.1 2008/05/07 04:15:08 Administrator
no message
Revision 1.1.1.1 2008/03/06 13:29:05 Lingzhaojun
no message
Revision 1.1 2007/11/26 14:29:40 Huangxinyu
改变adckey目录
*********************************************************************/
#include "include.h"
#include "hw_include.h"
#include "hwapi_adc.h"
#include "hw_adckey.h"
#include "hwapi_keyboard.h"
#include <stdlib.h>
#if ( ADKEY_SUPPORT )
INT16U gKeyScanAdValue = ADV_KEYMAX; /* AD按键采样值 */
INT16U gKeyDownMsgSend;
INT16U gKeyScanIndex; //AD 值 对应的 AD 数组的索引.
/*
1. 定义 按键的 AD 值和相对应的 扫描码,便于程序处理.两者需要一一对应.
2. skeyAdcValue 的值必须从小到大顺序排列.
3. 通过两个表格是为了兼容 AD值 和扫描码 不对应的情况,比如 ADV_KEYUP 的AD值最小
但是其扫描码 KEY_SCAN_UP 却不是 0(即不是ADV_KEYUP 在 skeyAdcValue里的对应下标).
如果两者一一对应,这可以省略数组 skeyAdcScanCode , 直接利用 gKeyScanIndex 作为
按键的扫描码.
*/
static INT16U skeyAdcValue[] =
{
ADV_KEYUP , ADV_KEYDOWN , ADV_KEYFFD ,
ADV_KEYFFW , ADV_KEYRETURN , ADV_KEYMENU ,ADV_KEYPLAY
};
static INT16U skeyAdcScanCode[] =
{
KEY_SCAN_UP , KEY_SCAN_DN , KEY_SCAN_FFD ,
KEY_SCAN_FFW , KEY_SCAN_RETURN , KEY_SCAN_MENU ,KEY_SCAN_PLAY
};
/**************************************************************************
* 函数描述: AD按键硬件检测
* 入口参数: adcValue -- AD key的采样值
* 出口参数: 无
* 返回值: 无
* 注释: 此函数被RockAdcScanning调用
* AD Key同一时刻只能有一个按键按下
* Log :
*080624 huangsl 因为 AD按键可能只作为附属按键,并且按键扫描 都集中在 RockKeyScanning 函数里面,
因此,此处需要增加一个返回键表示是否存在按键 按下.
***************************************************************************/
INT32U ADKeyScanning(unsigned short adcValue)
{
INT32U haveKeyPress = 0;
//检测到有按键.
if (adcValue < ADV_KEYFREE)
{
#if 1
//过滤第一次按键.AD 采集稳定时间大概是 200 ns,下一个周期再读取数据
//可保证 AD 值已经稳定下来.如果不丢弃第一个值,可能存在 用户刚刚按下按键
//马上定时器到了,读取该通道的值,此时 AD 可能处于不稳定状态.
if (gKeyScanAdValue == ADV_KEYMAX)
{
gKeyScanAdValue = ADV_KEYFREE;
return haveKeyPress;
}
#endif
// 上次按下按键后只能检测弹起,不再检测按下,否则会不断发送相同的按下消息
// AD 按键 不能同时检测到多个键按下,因此,同一时间只能支持一个按键按下.
if (gKeyDownMsgSend)
{
haveKeyPress = 0x02;
goto KeyScanInvalidExit;
}
gKeyScanIndex = 0;
//080623,huangsl,通过 AD值和 参考值查找 AD扫描码,
// 由于AD按键存在一定误差,因此,比较的是 SHIFT之后的值.
while (gKeyScanIndex < ARRSIZE(skeyAdcValue) &&
abs(adcValue - skeyAdcValue[ gKeyScanIndex ]) > ADV_KEYSHIFT )
gKeyScanIndex++;
//如果误差大于该 AD 值对应的范围,认为无效.
if ( gKeyScanIndex == ARRSIZE(skeyAdcValue) )
{
gKeyScanAdValue = ADV_KEYMAX;
return haveKeyPress;
}
//否则检测到按键 按下,发送消息.
RockKeySendKeyMsg(1 , skeyAdcScanCode[gKeyScanIndex] );
gKeyDownMsgSend = 1;
haveKeyPress = 0x02;
gKeyScanAdValue = adcValue; //保留本次采样值.
}
else
{
if (gKeyDownMsgSend == 1)
{
RockKeySendKeyMsg(0 , skeyAdcScanCode[gKeyScanIndex] );
gKeyDownMsgSend = 0;
gKeyScanAdValue = ADV_KEYMAX;
}
}
KeyScanInvalidExit:
/*
说明:如果只具有AD按键 而没有其他 按键(IO),则需要 增加 RockKeyScanning 函数,并且在该函数里面
调用 RockKeyTimerCallback 函数,具体可以参考 hw_matrixkey.c里面的 RockKeyScanning函数.
*/
//RockKeyTimerCallback(haveKeyPress );
return haveKeyPress;
}
#endif // ADKEY_SUPPORT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -