ayb_ice 发表于 2013-11-7 09:06 
这个图对于标准51 GPIO(弱上拉)是错误的,是不能正常工作的,但对于GPIO有推挽输出的是正常的,此时下拉 ...
大神,如下是按键电路所附的程序。。我在里面没找到把P1口设置成推挽输出这个操作啊。。有时间的话能不能帮忙看一眼。。。#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){
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;
}
}
|