打印

闲着无聊,发个简单的4*4矩阵按键扫描

[复制链接]
3780|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
sysdriver|  楼主 | 2011-10-10 20:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
sysdriver|  楼主 | 2011-10-10 21:02 | 只看该作者
/******************************************/
#include <reg52.h>
#define uchar unsigned char

//mcu=at89s52
//keyboard= 4*4, output pin= P2[7,4], input pin= P2[3,0]

bit bdata        b_key_scan;        //'1'-> can scan the key
bit bdata        b_key_debounce;        //'1'-> key has debounce
bit bdata        b_key_release;        //'0'-> key has release

uchar keyscan(void);
/******************************************/

void main(void)
{
        uchar r_temp_key;

        TMOD = 0x01;
        TH0 = (65536-10000)/256;        //timer0 = 10ms
        TL0 = (65536-10000)%256;
        ET0 = 1;
        TR0 = 1;

        b_key_scan = 0;
        b_key_debounce = 0;
        b_key_release = 0;

        EA = 1;

        while(1)
        {
                r_temp_key = keyscan();
                switch (r_temp_key)
                {
                        case 0xee:
                                //key1
                                break;
                        case 0xed:
                                //key2
                                break;
                        case 0xeb:
                                //key3
                                break;
                        case 0xe7:
                                //key4
                                break;
                        case 0xde:
                                //key5
                                break;
                        case 0xdd:
                                //key6
                                break;
                        case 0xdb:
                                //key7
                                break;
                        case 0xd7:
                                //key8
                                break;
                        case 0xbe:
                                //key9
                                break;
                        case 0xbd:
                                //key10
                                break;
                        case 0xbb:
                                //key11
                                break;
                        case 0xb7:
                                //key12
                                break;
                        case 0x7e:
                                //key13
                                break;
                        case 0x7d:
                                //key14
                                break;
                        case 0x7b:
                                //key15
                                break;
                        case 0x77:
                                //key16
                                break;
                        default:
                                break;
                }
        }
}

void T0_ISR(void) interrupt 1
{
        TH0 = (65536-10000)/256;
        TL0 = (65536-10000)%256;
        b_key_scan = 1;
}

/******************************************/

uchar keyscan(void)
{
        static uchar r_key_pre;        //last key value
        uchar r_key_row;        //store the key row
        uchar r_temp_p2;        //p2 temp value

        if(b_key_scan==0) return 0;
        b_key_scan = 0;

        r_key_row = (0xfe << 4);
        while(r_key_row !=0)
        {
                P2 = r_key_row & 0xf0;

                r_temp_p2 = P2;
                r_temp_p2 &= 0x0f;
                r_temp_p2 |= (r_key_row & 0xf0);
                if((r_temp_p2 & 0x0f) != 0x0f)
                {//have one key
                        if(b_key_release==1)
                        {//last key have not release
                                b_key_debounce = 0;
                                return 0;
                        }
                        if(b_key_debounce==0)
                        {//set debounce
                                r_key_pre = r_temp_p2;
                                b_key_debounce = 1;
                                return 0;
                        }

                        b_key_debounce = 0;
                        //compare twice key value
                        if(r_key_pre != r_temp_p2) return 0;

                        b_key_release = 1;        //set key not release
                        return r_temp_p2;
                }
                r_key_row <<= 1;
        }

        //scan all none key, release key
        b_key_release = 0;
        return 0;
}

/******************************************/

使用特权

评论回复
板凳
sysdriver|  楼主 | 2011-10-10 21:07 | 只看该作者
这是我经常用的一个按键扫描,基本上没有出过问题的
差不多都是半路return,从时间复杂度来说,效率还是挺高的,嵌套的if不多,空间也用不了多少。
变量基本上很少,即使加上连击,保持等,在此结构上也好加。

使用特权

评论回复
地板
pan420| | 2011-10-10 23:18 | 只看该作者
好复杂。。应该加多点解释。。头晕了

使用特权

评论回复
5
流行音乐| | 2011-10-10 23:23 | 只看该作者
我认为,比较完美的按键程序应该有如下功能:
1:按键去抖。
2:当多个按键同时按下时,除了矩形三键冲突之外,能识别出所有被按下的按键。(注:硬件可以解决矩形三键冲突)
3:支持按键重发,当多个按键同时按下时重发最后一个按下的按键(矩形三键冲突除外)。
4:按键先进先出队列。
5:其它附加功能,例如按键弹起事件、组合按键等。
简单的说,就是能达到电脑键盘的效果。

使用特权

评论回复
6
流行音乐| | 2011-10-10 23:42 | 只看该作者
楼主的程序不错,抛弃了很多教科书上采用的循环死等按键的方法。

使用特权

评论回复
7
ayb_ice| | 2011-10-11 08:12 | 只看该作者
"switch (r_temp_key)"
这条语句最好改为
if(r_temp_key){
    switch (r_temp_key){

    }
}
否则基本是在做"无用功"

使用特权

评论回复
8
sysdriver|  楼主 | 2011-10-11 08:45 | 只看该作者
4# pan420
一定要很多解释才能看懂的程序不是好程序,看不明白的说明不是用心看

使用特权

评论回复
9
sysdriver|  楼主 | 2011-10-11 08:48 | 只看该作者
5# 流行音乐
很少有看到这么完美的单片机按键扫描,很少有这样的项目用到这些功能吧,一般都是根据需要来写按键扫描的。这些功能在此结构上实现也是可以的,只不过需要加多更多变量和更多的判断,还有加上定时器等等。

使用特权

评论回复
10
sysdriver|  楼主 | 2011-10-11 08:51 | 只看该作者
7# ayb_ice
是的,如果加上这句,可以减少超级循环的一丁点时间,但也增加了一丁点空间,看实际需要了。

使用特权

评论回复
11
caogen111| | 2011-10-11 17:03 | 只看该作者
tetegtuwgthgwvf

使用特权

评论回复
12
e掾木| | 2011-10-11 17:33 | 只看该作者
LZ的开源精神值得嘉奖,让还在使用delay(ms )死等的初学者学到了东西。
我以为一个完美的键盘程序是,尽可能剥离硬件封装成接口形式,跨MCU能够在2 - 30分钟内配置好就为你的程序服务。对外仅仅开放几个函数: 有限时间内获取键值Keyval  KeyFetchKey( int16u timeout ); 清空缓冲区void vKeyFlushKey( void ); 端口初始化KeyInitPorts( )。

使用特权

评论回复
13
wlyuncc| | 2011-10-11 23:59 | 只看该作者
我就知道你这个初级工干的好事。
凡事都有规矩的

使用特权

评论回复
14
sysdriver|  楼主 | 2011-10-12 09:15 | 只看该作者
我就知道你这个初级工干的好事。
凡事都有规矩的
wlyuncc 发表于 2011-10-11 23:59

是不是喝醉了不知道说什么

使用特权

评论回复
15
风再起时| | 2011-10-16 09:34 | 只看该作者
、、、、

使用特权

评论回复
16
lidaji0| | 2011-11-29 23:11 | 只看该作者
感谢分享,学习呢

使用特权

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

本版积分规则

5

主题

687

帖子

0

粉丝