找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3323|回复: 8
收起左侧

按键延程序能否改进?

[复制链接]
ID:140568 发表于 2016-10-3 13:06 | 显示全部楼层 |阅读模式
#include<reg51.h>
unsigned char code seg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//êyÂë1üÏÔê¾·û
sbit k1=P3^2;
sbit k2=P3^6;
bit keysta=1;/
void main(){
                bit backup=1;/
                unsigned char cnt=0;//°′¼üμļÆêyμÄ′Îêy
                TMOD=0X01;
                TH0=0XF8;
                TL0=0XCD;
                ET0=1;
                TR0=1;
                EA=1;
                P2=seg[cnt];
                while(1){
                                if(keysta!=backup){
                                        if(backup==0){
                                                cnt++;
                                                if(cnt>=10){
                                                        cnt=0;
                                                }
                                                P2=seg[cnt];
                                        }
                                        backup=keysta;
                        }
        }
}
void tm()interrupt 1
{
        static unsigned char keybuf=0xff;
        TH0=0XF8;
        TL0=0XCD;
        keybuf=(keybuf<<1)| k1;
        if(keybuf==0xfe){
                keysta=0;
        }
        else if(keybuf==0xff){
                keysta=1;
        }
}
               
如果我是二个按键是不是要:
1.增加backup的数量;
2.增加keybuf=(keybuf<<1)| k2;
这样觉得很不智能。并且也繁琐。

回复

使用道具 举报

ID:123289 发表于 2016-10-3 15:55 | 显示全部楼层
程序不加注释,不是好习惯,别人不好读。
回复

使用道具 举报

ID:140568 发表于 2016-10-3 18:16 | 显示全部楼层
yzwzfyz 发表于 2016-10-3 15:55
程序不加注释,不是好习惯,别人不好读。

我本来加注释的,可是一复制来这里就是乱码!可恶啊~
回复

使用道具 举报

ID:140568 发表于 2016-10-3 18:17 | 显示全部楼层
yzwzfyz 发表于 2016-10-3 15:55
程序不加注释,不是好习惯,别人不好读。

#include <reg52.h>

sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;
sbit KEY1 = P2^4;
sbit KEY2 = P2^5;
sbit KEY3 = P2^6;
sbit KEY4 = P2^7;

unsigned char code LedChar[] = { //数码管显示字符转换表
    0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
    0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
};

void delay();
void main(){
    bit keybuf = 1; //按键值暂存,临时保存按键的扫描值
    bit backup = 1; //按键值备份,保存前一次的扫描值
    unsigned char cnt = 0; //按键计数,记录按键按下的次数
   
    ENLED = 0;  //选择数码管 DS1 进行显示
    ADDR3 = 1;
    ADDR2 = 0;
    ADDR1 = 0;
    ADDR0 = 0;
    P2 = 0xF7;  //P2.3 置 0,即 KeyOut1 输出低电平
    P0 = LedChar[cnt];  //显示按键次数初值

    while (1){
        keybuf = KEY4;  //把当前扫描值暂存
        if (keybuf != backup){  //当前值与前次值不相等说明此时按键有动作
            delay();  //延时大约 10ms
            if (keybuf == KEY4){  //判断扫描值有没有发生改变,即按键抖动
                if (backup == 0){  //如果前次值为 0,则说明当前是弹起动作
                    cnt++;  //按键次数+1
                    //只用 1 个数码管显示,所以加到 10 就清零重新开始
                    if (cnt >= 10){
                       cnt = 0;
                    }
                    P0 = LedChar[cnt]; //计数值显示到数码管上
                }
                backup = keybuf; //更新备份为当前值,以备进行下次比较
            }
        }
    }
}
/* 软件延时函数,延时约 10ms */
void delay(){
    unsigned int i = 1000;
    while (i--);
}
回复

使用道具 举报

ID:140568 发表于 2016-10-3 18:19 | 显示全部楼层
yzwzfyz 发表于 2016-10-3 15:55
程序不加注释,不是好习惯,别人不好读。

我想要添加为二个按键我的思路就是上面的这样!对比就采用数组的形式。unsigned char keysta[2]={1,1};可以不?
回复

使用道具 举报

ID:123289 发表于 2016-10-8 01:35 | 显示全部楼层
基本思路正确。有改进的地方。
回复

使用道具 举报

ID:123289 发表于 2016-10-8 01:38 | 显示全部楼层
先说不好的地方:
1、硬件延时防弹动,浪费CPU资源,延时时间也不机动。可以用中断处理。
2、单键处理,不“经济”,可以一次性全部处理。
回复

使用道具 举报

ID:123289 发表于 2016-10-8 02:38 | 显示全部楼层
键有效判定原则:
方法:有效时,置键有效B_INPUT=1标记,表求按键有效;再置B_KEYPUSHED=1,表示有键已按下。
下列状况无效:
1、本次采样值与上次键值不同。
2、本次采样值与上次键值相同,但相同的时间不足(如30ms)。
3、无按键(虽然永远相同)
4、按下未松开B_KEYPUSHED=1。
回复

使用道具 举报

ID:123289 发表于 2016-10-8 02:39 | 显示全部楼层
技巧:
1、将各键放于同一个口,如P1(不要P1放一个键,P2放一个键),这样可以一次采样8个键,而无需一一采样、识别、处理。
2、采样是键值存入20H-2FH单元中(51系列,比如22H,22H.0至22H.7共对应8个键,这样各键可直接寻址),且以BYTE存入,这样,一次性可以处理8个键值。不要分放在不同的BYTE中!
3、上次的采样键值,也用BYTE对应保存(位对位对齐,比如32H,每位对应一个键)。
4、本次采样与上次采样是否相同,只要22H XOR 32H 即可判定出来(所有8个键),=0同,<>0至少有一个不同(作弹动处理)。
5、用中断防止弹动,如5ms中断一次,每次中断就采样一次,计时弹动一次。
6、弹动用计次的方式,例如,对“本次采样与上次采样相同”计次,不同就清0(弹动中),相同+1(计时5ms),计满6次(即30ms无弹动)可认为按键已稳定OK。
7、用一个BITE(如:B_KEYOK),统一表示所有的按键OK。
8、当按键已稳定OK后,置B_KEYOK=1,表示有键成功。而键值必定在22H中,检查22H中各个位的0或1,即可知道是哪个键按下了,甚至可以判定多键齐按。
9、主程序中(使用键值的程序)只在B_KEYOK=1处理键值(B_KEYOK=0,则键无效,无需一一检查各个键),在完成键处理程序后,清B_KEYOK=0,即可。
10、当然无按键情况下的稳定,需要排除(这也是个稳定状态)。
11、更高级技巧:
    增加长按计数器,通过计数值的多少,可以区分出长按的键(并可机动地改变长按判定时间);用于做长按连+/-加、快速+/-。
    增加已按标记,可处理按住不放,防止按长了,被误处理多次;
    ……
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表