打印
[程序源码]

网上找的一种新型按键扫描方法。

[复制链接]
1740|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
一个小黄人|  楼主 | 2016-8-18 08:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
# include <reg51.h>

#define uin16 unsigned int
#define uchar8 unsigned char

#define Key_beep 0x10
#define Model 0x20
#define Plus 0x40

sbit beep=P2^3;  //蜂鸣器

uchar8 Trg,Cont,KeyGet;

volatile uchar8 intrcnt;


/******************中断初始化******/
void Timer0Init()
{       
    TMOD=0x01;//设置定时器0为工作方式1
        TH0=(65536-1000)/256;
        TL0=(65536-1000)%256;
        EA=1;//开总中断
        ET0=1;//开定时器0中断
        TR0=1;//启动定时器0

}

void KeyRead()
{
       
        KeyGet=P3^0xff;
        Trg = KeyGet & (KeyGet^Cont);
        Cont = KeyGet;       
}

void Keyproc1()
{
        if(Trg&Key_beep)
                {
                        beep=0;
                }       
}

void Timer0() interrupt 1
{
        TH0=(65536-1000)/256;
        TL0=(65536-1000)%256;
        intrcnt++;       
}

void main ()
{       
               
        while(1)//20ms刷新一次
                 
                {       
               
                KeyRead();
               
                Keyproc1();
                        while(1)    //
                        {
                                if(intrcnt>20)
                                        {
                                                intrcnt=0;
                                                break;
                                        }
                        }       
                       
                }
}


本人小白,最近在努力学习单片机。前面就是看郭天祥的视频,用了他的按键扫描的方法,发现在很多情况下,他的方法不好用。于是在网上看别人发的新型按键扫描方法,但是扫进去,发现不能用,求大神解答下,谢谢。


相关帖子

沙发
一个小黄人|  楼主 | 2016-8-18 09:05 | 只看该作者
void main ()
{       
        Timer0Init();       
        while(1)
                 
                {       
               
                KeyRead();
               
                Keyproc1();
                        while(1)
                        {
                                if(intrcnt>20)
                                        {
                                                intrcnt=0;
                                                break;
                                        }
                        }       
                       
                }
}

主函数是这样的,我没复制到。就是不能20ms刷新..........

使用特权

评论回复
板凳
popeye021| | 2016-8-18 09:59 | 只看该作者
本帖最后由 popeye021 于 2016-8-18 10:03 编辑
一个小黄人 发表于 2016-8-18 09:05
void main ()
{        
        Timer0Init();        

我记得按键扫描部分还有一个release的计算的。你这个扫描貌似不全吧?


使用特权

评论回复
地板
datouyuan| | 2016-8-18 10:01 | 只看该作者
这个按键处理很不错.20ms刷新是通过最里面的while(1)实现的.
他的main()只是演示了一下用法.实际工程不能这样用.

"不能20ms刷新"可能是由于你定时中断没配置好.

看别人的代码首先要理解,才好拿来做自己的.


使用特权

评论回复
5
changle11sdo5| | 2016-8-18 10:01 | 只看该作者
郭天祥视频看了半集,直接扔了

使用特权

评论回复
6
popeye021| | 2016-8-18 10:06 | 只看该作者
changle11sdo5 发表于 2016-8-18 10:01
郭天祥视频看了半集,直接扔了

扫描里面加一行
Release = KeyGet ^ Trg ^ Cont;
加在 Cont = KeyGet; 之前。
判断Release,来判断按键有效。
定时器有没有正常工作?

使用特权

评论回复
7
datouyuan| | 2016-8-18 10:07 | 只看该作者
void KeyRead();//作用是得到松手按键的键值.
void Keyproc1();//按键控制蜂鸣器的处理

我这样注释,是不是明白了?

使用特权

评论回复
8
一个小黄人|  楼主 | 2016-8-18 10:21 | 只看该作者
popeye021 发表于 2016-8-18 09:59
我记得按键扫描部分还有一个release的计算的。你这个扫描貌似不全吧?

你程序吗?我在论坛找的别人的,他没有注释,我看了老帮天....

使用特权

评论回复
9
一个小黄人|  楼主 | 2016-8-18 10:27 | 只看该作者
popeye021 发表于 2016-8-18 10:06
扫描里面加一行
Release = KeyGet ^ Trg ^ Cont;
加在 Cont = KeyGet; 之前。

定时器正常工作了,这个Release的作用是什么啊?

使用特权

评论回复
10
ningling_21| | 2016-8-18 10:49 | 只看该作者
判断按键是否释放

使用特权

评论回复
11
popeye021| | 2016-8-18 11:22 | 只看该作者
一个小黄人 发表于 2016-8-18 10:27
定时器正常工作了,这个Release的作用是什么啊?

Release表明按键释放,就是获得了一次完成的按键事件。
后面判断按键是否有效,是判断Release这个变量,不是判断Trg

使用特权

评论回复
12
一个小黄人|  楼主 | 2016-8-18 11:25 | 只看该作者
ningling_21 发表于 2016-8-18 10:49
判断按键是否释放

判断按键按下,Cont不是就可以了吗???发过按键松开,Cont就变成OX00了

使用特权

评论回复
13
coody| | 2016-8-18 13:34 | 只看该作者
没觉得新型啊,简单的处理,我上世纪90年代初就这样用了。
不过,实际代码要完善一下,比如3次采样处理,避免干扰。

使用特权

评论回复
14
yklstudent| | 2016-8-18 13:41 | 只看该作者
Menu_Status InfraredKey_Read(void)
{
    Menu_Status key_return_value = menu_nokey;
    static uint8_t Trg = 0;
    static uint8_t Release = 0;
    static uint8_t Cont = 0;
    uint8_t key_value = 0;
    uint8_t read_value = 0;
    key_value = BUTTON_PORT & 0x0F;
    key_value = ~key_value;
    read_value = (key_value | 0xF0) ^ 0xFF;
    Trg = read_value & (read_value ^ Cont);
    Release = (read_value ^ Trg ^ Cont);
    Cont = read_value;
    switch( Release )
    {
        case 0x01:
        {
            key_return_value = menu_key01; break;
        }
        case 0x02:
        {
            key_return_value = menu_key02; break;
        }
        case 0x03:
        {
            key_return_value = menu_key03; break;
        }
        case 0x04:
        {
            key_return_value = menu_key04; break;
        }
        case 0x05:
        {
            key_return_value = menu_key05; break;
        }
        case 0x06:
        {
            key_return_value = menu_key06; break;
        }
        case 0x07:
        {
            key_return_value = menu_key07; break;
        }
        case 0x08:
        {
            key_return_value = menu_key08; break;
        }
        case 0x09:
        {
            key_return_value = menu_key09; break;
        }
        case 0x0a:
        {
            key_return_value = menu_key10; break;
        }
        case 0x0b:
        {
            key_return_value = menu_key11; break;
        }
        case 0x0c:
        {
            key_return_value = menu_key12; break;
        }
        case 0x0d:
        {
            key_return_value = menu_key13; break;
        }
        case 0x0e:
        {
            key_return_value = menu_key14; break;
        }
        case 0x0f:
        {
            key_return_value = menu_key15; break;
        }
        default:
            break;
    }
    return (key_return_value);
}

使用特权

评论回复
15
popeye021| | 2016-8-18 13:43 | 只看该作者
一个小黄人 发表于 2016-8-18 11:25
判断按键按下,Cont不是就可以了吗???发过按键松开,Cont就变成OX00了

Cont是用来判断长按的,看我之前的回复

使用特权

评论回复
16
一个小黄人|  楼主 | 2016-8-18 14:43 | 只看该作者
popeye021 发表于 2016-8-18 13:43
Cont是用来判断长按的,看我之前的回复

我是真心有点笨,我能问下您,这个release在实际运用中的作用吗?谢谢了

使用特权

评论回复
17
popeye021| | 2016-8-18 14:56 | 只看该作者
本帖最后由 popeye021 于 2016-8-18 14:57 编辑
一个小黄人 发表于 2016-8-18 14:43
我是真心有点笨,我能问下您,这个release在实际运用中的作用吗?谢谢了

release有置位,表明有按键按下,并且释放了,这就是一次完整的按键操作。
再根据相应位判断是哪个按键。上面已经有人给出了release应用的代码了,好好看一下。

使用特权

评论回复
评分
参与人数 1威望 +2 收起 理由
一个小黄人 + 2 很给力!
18
yunfei_han| | 2016-8-19 08:36 | 只看该作者
都是从按键、流水灯开始学的

使用特权

评论回复
19
king101king| | 2016-8-20 15:13 | 只看该作者
网上找一下状态机的方式

使用特权

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

本版积分规则

8

主题

66

帖子

1

粉丝