打印

帮我看看!!

[复制链接]
1089|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zl040901|  楼主 | 2008-5-25 13:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
初始时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;
    }

}
帮我解释一下程序,尤其始那个键值的计算不懂

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

16

主题

61

帖子

0

粉丝