矩阵键盘扫描

矩阵键盘扫描一般采取行列扫描法。比如先拉低所有列线,拉高行线,之后读取行线状态,如果行线有一行为低,则假设有按键按下,此时再延时20毫秒左右后判 断行线的某一行是否仍然为低,若为低则确认有键按下。这时可以进行按键键值判断,即判别在哪一行哪一列有按键按下。判断的方法是通过拉高列线,依次置行线 的某一行为低,读取列线值。如果列线有一列为低,则表示按键发生在该行,进而可以通过读取到的列线值确定在哪一列,从而确定按键发生在具体的行和列。为了 防止按键按下后一直有按键被读取,需要在程序中设定在按键被释放后才能读取具体的键值来避免这一问题。 ia%IS9  
代码如下: G7"2;47L  
e-U|K9Dg  
#include<reg52.h> B*(Kv;  
#include<stdio.h> GR.fnO5+  
#define KEY_PORT P2        //矩阵键盘端口,其中P2.0-P2.3为列线,P2.4-P2.7为行线 }38C+ijC  
typedef unsigned char uchar; l1g9�rt $  
typedef unsigned int uint; q#:`Q| /$  
void serial_init(void)                       //串口初始化函数 $@69?oq%  
{ A(|p$/:'  
   TMOD = 0x20;                              //T1工作方式1,用于设定波特率 pkeoI,  
   TH1  = 0xF3;                              //波特率4800Bps,12MHz晶振 (#!z ;ad)b  
   TL1  = 0xF3; ZQk twu  
   PCON |= 0x80;                             //SMOD = 1,波特率加倍 %/QZ/5bmH  
   SCON = 0x50;                              //允许发送接收 E=4D .6R  
   ES   = 0;                                 //禁止串口中断 N|mVdzp  
   TI   = 1; )8 `Zft*  
   TR1  = 1; Y[PY~Hl8h  
} dd }-}J{  
jm<*`N/ VQ  
uchar key_scan(void)            //键盘扫描函数,有键按下则返回1,否则返回0 M7%jq}-+h  
{ M??Ac-S  
    uchar keyPressed = 0; Fv[}iItWj  
    KEY_PORT = 0xF0;                    //置低列线,以读取行线判断是不是有键按下 i2YOmR@1*  
    keyPressed = KEY_PORT & 0xF0;        //读取行线值 oyHfD  
    if(keyPressed == 0xF0)              //无键按下 ?L59A[D%  
        return 0; gVpZ8Yls  
    else }P<&vUl>  
        return 1;                        //有键按下 [&XB*>4K  
} ^l^/}~  
uchar key_assert(void)        //键值判断函数,第半字节存列号,高半字节存行号 *W<  
{ i[Q%lwp  
    uchar keyvalue;    //按键键值存储变量,高四位代表行线位置,低四位代表列线位置 'b0Q~GFQ_  
    KEY_PORT = 0xEF;//拉低第一行 m/>r�GaE  
    if((keyvalue = KEY_PORT & 0x0F) != 0x0F) //第一行的键被按下,确认在哪一列 3BC6Q#/l  
    {     w)  
        while((KEY_PORT & 0x0F) != 0x0F);         //等待按键释放 {'nM<HeO  
        return keyvalue | 0xE0; O7S�I"Plax  
    }         h Pv}uE  
    KEY_PORT = 0xDF;                         //拉低第二行 Do edGr�zs  
    if((keyvalue = KEY_PORT & 0x0F) != 0x0F) //第二行的键被按下 #29v/sQ  
    {     _{bB>  
        while((KEY_PORT & 0x0F) != 0x0F);         //等待按键释放 1Ec^~ ^  
        return (keyvalue | 0xD0); V='�zJ 6@Z  
    } ?A(Uu`Ti  
    KEY_PORT = 0xBF;                         //拉低第三行 nL*"2) gw  
    if((keyvalue = KEY_PORT & 0x0F) != 0x0F) //第三行的键被按下 Lu#a*$`$/  
    {     }8@B3? ~  
        while((KEY_PORT & 0x0F) != 0x0F);         //等待按键释放 9*/:/Ma|  
        return (keyvalue | 0xB0); S`5/|FC  
    } B'/+/dp=  
    KEY_PORT = 0x7F;                         //拉低第四行 (+7|$.  
    if((keyvalue = KEY_PORT & 0x0F) != 0x0F) //第四行的键被按下 neGBDy/  
    {     J rGzmOU  
        while((KEY_PORT & 0x0F) != 0x0F);         //等待按键释放 =' 2Na$1v  
        return (keyvalue | 0x70);             w g~*d|pl  
    } ygg 2B  
} HblL2#91]  
void Hardware_Delay_1ms(void)            //硬件定时器延时1ms函数 ~[$;  
{ nw}hf  
   TMOD &=0xF0; OdO9wGR  
   TMOD |=0x01;  //T0——16位定时器器模 yf*M2,  
84|-zA  
   TH0 = 0xFC; 9>SRRB6a  
   TL0 =0x18;    //64536 &vbAU_Jf  
   2C`(h%No  
   TF0=0;        //清除定时器溢出标志 ?(kJ^HaB  
   TR0=1;         //启动定时器     edqM&Nk8  
   while(TF0==0);//等待计数完成 2_%$HM|  
   TR0=0;         //停止定时器 9!L/3V) *  
} ]@4!O~/*Q  
void Delay_Nms(uint N)                    //延时N毫秒函数 tN"VnuO;  
{ T>UBb  
    uint j; 8M{84[F  
    for(j=N;j>0;j--) +34k�0@j  
     Hardware_Delay_1ms();     H&??5n/u  
} W7_y'aI%L  
void main(void) I#(fZ6;D  
{ , :V?pj  
    uchar key_value = 0;    //键值 /-osQaR(  
    serial_init(); '/WN*ch>  
    while(1) fxA@cF  
    { $gg/4Vu  
        if(key_scan()) F}($9uQh"  
        { 5,6dBtXGV>  
            Delay_Nms(20);   //延时20ms,去抖 aU`*N`  
            if(key_scan())   //确实有键按下,读取键值 aZ`,#dOr  
                key_value = key_assert();  //读取P2值做判断 e`6~;hz.&  
            P1 = key_value;     //通过LED显示键值 {~Vu{ita#  
            switch(key_value)//通过串口打印哪个按键被按下信息 RhbDd  
            { 5{W[b`l  
                case 0xEE: hN*SBH9  
                    printf("Key 1 pressed!/n"); paS6xOD  
                    break; #r:^6/!XA  
                case 0xED: ;JD`b0h  
                    printf("Key 2 pressed!/n"); r3 NOpV  
                    break; &9ha3hYBh  
                case 0xEB: FQT 0%ZO  
                    printf("Key 3 pressed!/n"); yk !9B //  
                    break; s,&exb,@  
                case 0xE7: D,f R~-  
                    printf("Key 4 pressed!/n"); Z^]0:&46  
                    break; K;{e{P  
                case 0xDE: |a-z5$&  
                    printf("Key 5 pressed!/n"); q:.FB7#  
                    break; L}L`fmS^<  
                case 0xDD: f}]1/~d  
                    printf("Key 6 pressed!/n"); )l,2s}AuJ  
                    break; }"Q@m`fJ  
                case 0xDB: y^SaQ2+  
                    printf("Key 7 pressed!/n"); =Ld.g]=  
                    break; gTg]6K%Q0  
                case 0xD7: rI(2?[hj  
                    printf("Key 8 pressed!/n"); @S,; f'T  
                    break; 1No*e7"  
                case 0xBE: u]*c5 +2@6  
                    printf("Key 9 pressed!/n"); 6fjtWh#J  
                    break; SBPmhD `z  
                case 0xBD: "Wni|iY  
                    printf("Key 10 pressed!/n"); 6_5!_G$X  
                    break; #V;l}C&-Y!  
                case 0xBB: % Hnz�:'  
                    printf("Key 11 pressed!/n"); 2ViFwx<I])  
                    break; mDm^)L  
                case 0xB7: <j>RiQt3/  
                    printf("Key 12 pressed!/n"); 5 J&_g(  
                    break; ,P%>_=aJ  
                case 0x7E: YQ0ix|1dy>  
                    printf("Key 13 pressed!/n"); N -:k%b  
                    break; 51r D-$^z  
                case 0x7D: ]sA2MKqC  
                    printf("Key 14 pressed!/n"); }@7OMYzk  
                    break; eY|>$Lk  
                case 0x7B: kBq)>rT j_  
                    printf("Key 15 pressed!/n"); i@V~.]f  
                    break; j�-OdAD4Go  
                case 0x77: SiJb@|R  
                    printf("Key 16 pressed!/n"); X9b.Odl  
                    break; L4&/s/{$wm  
            } cQ7#;Dfy  
        } ^hILV  
    } UiMhPFg6  
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

岛上码农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值