发布网友 发布时间:2022-04-23 14:54
共1个回答
热心网友 时间:2023-10-06 11:10
只有更好,没有最好。只有更有效,没有最有效。适合当前项目需要的程序就是合适的程序。针对51单片机,没有一个按键程序是包打天下的。通常的按键扫描程序大致为:
扫描按键 ==>按键去抖(如果去抖过程中按键值变化了就去抖失败,重新扫描按键) ==>得到有效键 ==》可能需要针对长按或重复按键要求做不同处理 ==>等待按键松开追问"可能需要针对长按或重复按键要求做不同处理",这个处理不太懂,能提供参考程序么?
追答KEY_EVENT AdcKeyEventGet()
{
static BYTE PreKeyIndex = -1;
BYTEKeyIndex;
KEY_EVENTevent = IN_KEY_NONE;
if (!IsTimeOut(&AdcKeyScanTimer))
{
return IN_KEY_NONE;
}
TimeOutSet(&AdcKeyScanTimer, ADC_KEY_SCAN_TIME);
KeyIndex = GetAdcKeyIndex();
switch(AdcKeyState)
{
case ADC_KEY_STATE_IDLE:
if(KeyIndex == -1)
{
return IN_KEY_NONE;
}
PreKeyIndex = KeyIndex;
TimeOutSet(&AdcKeyWaitTimer, ADC_KEY_JTTER_TIME);
AdcKeyState = ADC_KEY_STATE_JITTER;
case ADC_KEY_STATE_JITTER:
if(PreKeyIndex != KeyIndex)
{
AdcKeyState = ADC_KEY_STATE_IDLE;
}
else if(IsTimeOut(&AdcKeyWaitTimer))
{
TimeOutSet(&AdcKeyWaitTimer, ADC_KEY_CP_TIME);
AdcKeyState = ADC_KEY_STATE_PRESS_DOWN;
}
break;
case ADC_KEY_STATE_PRESS_DOWN:
if(PreKeyIndex != KeyIndex)
{
AdcKeyState = ADC_KEY_STATE_IDLE;
return AdcKeyEvent[PreKeyIndex][0];
}
else if(IsTimeOut(&AdcKeyWaitTimer))
{
//DBG(("ADC KEY CPS(PreKeyIndex:%bd)!\n", PreKeyIndex));
TimeOutSet(&AdcKeyWaitTimer, ADC_KEY_CPH_TIME);
AdcKeyState = ADC_KEY_STATE_CP;
return AdcKeyEvent[PreKeyIndex][1];
}
break;
case ADC_KEY_STATE_CP:
if(PreKeyIndex != KeyIndex)
{
AdcKeyState = ADC_KEY_STATE_IDLE;
return AdcKeyEvent[PreKeyIndex][3];
}
else if(IsTimeOut(&AdcKeyWaitTimer))
{
//DBG(("ADC KEY CPH!\n"));
TimeOutSet(&AdcKeyWaitTimer, ADC_KEY_CPH_TIME);
return AdcKeyEvent[PreKeyIndex][2];
}
break;
default:
AdcKeyState = ADC_KEY_STATE_IDLE;
break;
}
return IN_KEY_NONE;
}