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