http://space.**/upload/2008/8/27/710028f4-5f75-4e01-a4c2-061f5042fce8.jpg
如图,利用单片机的AD口进行按键扫描,利用不同按键按下时的电压不同以区分是哪个键按下。
这样做的好处是:节省单片机的I/O口,只要用一个I/O,就可以接多个开关,如果开关多了,电阻可以细分。
缺点是不支持组合键。且按键有一定的优先级,越靠近I/O口的按键优先级越高,在图中KEY1>KEY2>KEY3。
//pic16f883,10bitAD,ccs编译环境
#define KeyScan() Get_Adc16(3)
int16 KeyCurrent=0,KeyOld=0,KeyPress=0; int8 KeyDown=0,KeyUp=0,KeyLas=0,KeyCount=0;
void ADKeyScan() { KeyCurrent=KeyScan(); //获取当前键值
//前后两次差值越过40,便认为发生了改变 if((KeyCurrent>KeyOld)?(KeyCurrent-KeyOld):(KeyOld-KeyCurrent)>40)
{ KeyOld=KeyCurrent; //保存新键值。 KeyCount="0"; return; } else { KeyCount++; if(KeyCount>=10) //2ms的时间片,延时20ms
{ KeyCount=10; //停止计数 KeyPress=0;
if(KeyLast!=0 && KeyOld<=0x3d0) return; //等待弹起
if(KeyOld<=0x050 && !(KeyDown&0x01)) KeyPress|=0x01; if(KeyOld<=0x220 && KeyOld>=0x1e0) KeyPress|=0x02; if(KeyOld<=0x2c0 && KeyOld>=0x280) KeyPress|=0x04;
KeyDown|=(KeyPress)&(~KeyLast); //按下的键
KeyUp|=(~KeyPress)&(KeyLast); //弹起的键
KeyLast=KeyPress; } } }
操作:
ADKeyScan(); if(KeyDown&0x01) { Accu_Mode_Flag=~Accu_Mode_Flag; SoundStart_Flag=TRUE; KeyDown&=0xfe; }
以上是我的一些看法,欢迎路过的留下看法,也欢迎指出不足。
|