初始时KC0-KC3,KRO-KR4都为低电平,先让KRO-KR4为高电平,读KC0-KC3的值,有键按下的话,KC0-KC3<br />中一定会有一个为高电平,确定后,依次再让KRO-KR4为高电平,从而确定键值<br /><br /><br />#include <stdio.h><br />#include <absacc.h><br />#include <./Atmel/at89x52.h><br />extern void start_t2imer(void);<br />unsigned char scankey;<br />bit Timerout=0;<br />bit keypress;<br />#define KR0 P1_0<br />#define KR1 P1_1<br />#define KR2 P1_2<br />#define KR3 P1_3<br />#define KC0 P1_4<br />#define KC1 P1_5<br />#define KC2 P1_6<br />#define KC3 P1_7<br />#define KBD_PORT P1<br />#define FSM_INIT 0X00<br />#define FSM_WAIT_PRESS 0X01<br />#define FSM_VERFY1 0X02<br />#define FSM_VERFY2 0X03<br />#define FSM_WAIT_RELESE 0X04<br />#define KBD_VAL_VAILD 0X80<br />main(){<br /> unsigned char fsm_key=0;<br /> unsigned char kbd_col;<br /> unsigned char kbd_row;<br /> unsigned char key_val;<br /> IE=0X40;<br /> start_t2imer();<br /> EA=1; /* Enable interrupts */<br /> while(1){ /*10ms扫描一次键盘程序*/<br /> if(Timerout){<br /> Timerout=0;<br /> switch(fsm_key){<br /> case FSM_INIT: /*初始扫秒状态*/<br /> KR0=1;<br /> KR1=1;<br /> KR2=1;<br /> KR3=1;<br /> fsm_key=FSM_WAIT_PRESS;<br /> break;<br /> case FSM_WAIT_PRESS:<br /> if(keypress){<br /> key_val=0; /清除以前的键值/<br /> if(KC0){<br /> KC0=1;<br /> kbd_col=1;<br /> }<br /> else if(KC1){<br /> KC1=1;<br /> kbd_col=2;<br /> } <br /> else if(KC2){<br /> KC2=1;<br /> kbd_col=3;<br /> }<br /> else if(KC3){<br /> KC3=1;<br /> kbd_col=4;<br /> }<br /> else{ /*干挠信号的话就重回初始扫描状态*/<br /> fsm_key=FSM_INIT;<br /> }<br /><br /> kbd_row =KBD_PORT;<br /> kbd_row >>=4;<br /> if(kbd_row){<br /> if(KR0){<br /> kbd_row=0;<br /> fsm_key=FSM_VERFY1; /*转去抖动*/<br /> }<br /> else if(KR1){<br /> kbd_row=4;<br /> fsm_key=FSM_VERFY1;<br /> }<br /> else if(KR2){<br /> kbd_row=8;<br /> fsm_key=FSM_VERFY1;<br /> }<br /> else if(KR3){<br /> kbd_row=12;<br /> fsm_key=FSM_VERFY1;<br /> }<br /> else{<br /> fsm_key=FSM_INIT;<br /> }<br /> }<br /> else{<br /> fsm_key=FSM_INIT;<br /> }<br /> }<br /> break;<br /> case FSM_VERFY1: /*去抖动*/<br /> switch(kbd_row){<br /> case 0:<br /> if(KR0) fsm_key=FSM_VERFY2;<br /> else fsm_key=FSM_INIT;<br /> break;<br /> case 4:<br /> if(KR1) fsm_key=FSM_VERFY2;<br /> else fsm_key=FSM_INIT;<br /> break;<br /> case 8:<br /> if(KR2) fsm_key=FSM_VERFY2;<br /> else fsm_key=FSM_INIT;<br /> break;<br /> case 12:<br /> if(KR3) fsm_key=FSM_VERFY2;<br /> else fsm_key=FSM_INIT;<br /> break;<br /> default:<br /> fsm_key=FSM_INIT;<br /> break;<br /> }<br /> break;<br /> case FSM_VERFY2: /*去抖动计算键值*/<br /> switch(kbd_row){<br /> case 0:<br /> if(KR0) key_val=(kbd_row+kbd_col)|KBD_VAL_VAILD;<br /> break;<br /> case 4:<br /> if(KR1) key_val=(kbd_row+kbd_col)|KBD_VAL_VAILD;<br /> break;<br /> case 8:<br /> if(KR2) key_val=(kbd_row+kbd_col)|KBD_VAL_VAILD;<br /> break;<br /> case 12:<br /> if(KR3) key_val=(kbd_row+kbd_col)|KBD_VAL_VAILD;<br /> break;<br /> default: <br /> break;<br /> }<br /> KR0=1;<br /> KR1=1;<br /> KR2=1;<br /> KR3=1;<br /> fsm_key=FSM_WAIT_RELESE;<br /> break;<br /> case FSM_WAIT_RELESE: /*键盘释放*/<br /> if(!keypress){<br /> fsm_key=FSM_INIT;<br /> }<br /> break;<br /> default:<br /> fsm_key=FSM_INIT;<br /> break;<br /> }<br /> }<br /> }<br />}<br />void time2()interrupt 5 {//base 10 ms<br /> TF2=0;<br /> Timerout=1;<br /> scankey=KBD_PORT;<br /> if(scankey&0x0f){<br /> keypress=1; <br /> }<br /> else{<br /> keypress=0;<br /> }<br /><br />}<br />帮我解释一下程序,尤其始那个键值的计算不懂 |
|