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