[程序源码] 按键扫描问题,都进来看看吧。

[复制链接]
2658|21
 楼主| 一个小黄人 发表于 2016-8-11 08:46 | 显示全部楼层 |阅读模式
void key_scan1()//按键扫描1
{

        P1=0xfe;
        temp1=P1;
        temp1=temp1&0xfe;
        if(temp1!=0xfe)
        {       
                delay(2);
                temp1=P1;
                        if(temp1!=0xfe)
                                {
                                temp1=P1;
                                delay(2);
                               
                                        if(temp1 ==0xfc)//扫描这个按键的时候非常不灵敏,需要不停的点才能触发
                                        {
                                                displayone(20,table_segl[1]);
                                                 displayone(21,table_segh[1]);
                                                displayone(22,0x08);
                                                 displayone(23,0x00);
                                                temp1=P1;
                                        }
                                /*        else
                                        if(temp1==0xfa)
                                                turn();
                                                dis_time(i,j,m,n);
                                                }  */
                                        else
                                        if(temp1==0xf6)
                                        {
                                                displayone(20,table_segl[3]);
                                                 displayone(21,table_segh[3]);
                                                displayone(22,0x08);
                                                 displayone(23,0x00);
                                                temp1=P1;
                                        }
                                        else
                                        if(temp1==0xee)
                                                {
                                                displayone(20,table_segl[4]);
                                                 displayone(21,table_segh[4]);
                                                displayone(22,0x08);
                                                 displayone(23,0x00);
                                                temp1=P1;
                                                }
                                        else
                                        if(temp1==0xde)
                                                {
                                                displayone(20,table_segl[5]);
                                                 displayone(21,table_segh[5]);
                                                displayone(22,0x08);
                                                 displayone(23,0x00);
                                                temp1=P1;
                                                }       
                                        }
                                         
                                  
                                                        
                                  
        }                               
}
void key_scan2()//按键扫描2
{
P1=0xfd;
        temp1=P1;
        temp1=temp1&0xfd;
        if(temp1!=0xfd)
        {       
                delay(2);
                temp1=P1;
                        if(temp1!=0xfd)
                                {
                                temp1=P1;
                                delay(2);                               
                                        if(temp1==0xfc)//这个问题和上面的一样,扫描这个按键的时候非常不灵敏,需要不停的点才能触发
                                        {
                                        displayone(20,table_segl[6]);
                                         displayone(21,table_segh[6]);
                                        displayone(22,0x08);
                                         displayone(23,0x00);
                                        temp1=P1;
                                        }
                                        else
                                        if(temp1==0xf9)
                                        {
                                        displayone(20,table_segl[7]);
                                         displayone(21,table_segh[7]);
                                        displayone(22,0x08);
                                         displayone(23,0x00);
                                        temp1=P1;
                                        }
                                        else
                                        if(temp1==0xf5)
                                        {
                                        displayone(20,table_segl[8]);
                                         displayone(21,table_segh[8]);
                                        displayone(22,0x08);
                                         displayone(23,0x00);
                                        temp1=P1;
                                        }
                                        else
                                        if(temp1==0xed)
                                        {
                                        displayone(20,table_segl[9]);
                                         displayone(21,table_segh[9]);
                                        displayone(22,0x08);
                                         displayone(23,0x00);
                                        temp1=P1;
                                        }
                                        else
                                        if(temp1==0xdd)
                                        {
                                        displayone(20,table_segl[0]);
                                         displayone(21,table_segh[0]);
                                        displayone(22,table_segl[1]);
                                         displayone(23,table_segh[1]);
                                        temp1=P1;
                                        }
                                         
                                 }
                                                        
                                  
        }       
}
void  main ()
{
while(1)
   {
        key_scan1();
        key_scan2();
   }
}

 楼主| 一个小黄人 发表于 2016-8-11 08:46 | 显示全部楼层
icecut 发表于 2016-8-11 10:07 | 显示全部楼层
网上搜个跟人学学行不行?
 楼主| 一个小黄人 发表于 2016-8-11 10:12 | 显示全部楼层
icecut 发表于 2016-8-11 10:07
网上搜个跟人学学行不行?

大哥,我只是想找出问题。我知道扫描原理,我就是搞不懂为什么我的第一个按键和第六个按键反应很迟钝,其他的都很灵敏,不是硬件问题。
 楼主| 一个小黄人 发表于 2016-8-11 10:12 | 显示全部楼层
icecut 发表于 2016-8-11 10:07
网上搜个跟人学学行不行?

您能给我看看嘛?
ayb_ice 发表于 2016-8-11 10:18 来自手机 | 显示全部楼层
首先显示与扫描不要放在一起,其次不要死等,通过定时读取io状态,稍加处理就可获取按键状态,显示放在定时中断处理,从固定地方抓取要显示的数据

评分

参与人数 1威望 +1 收起 理由
一个小黄人 + 1 很给力!

查看全部评分

 楼主| 一个小黄人 发表于 2016-8-11 10:23 | 显示全部楼层
ayb_ice 发表于 2016-8-11 10:18
首先显示与扫描不要放在一起,其次不要死等,通过定时读取io状态,稍加处理就可获取按键状态,显示放在定时 ...

谢谢您,您又类似的程序吗?您的不死等的意思是while语句中加个延时吗?
JerryWu75 发表于 2016-8-11 11:23 | 显示全部楼层
本帖最后由 JerryWu75 于 2016-8-11 11:26 编辑

如果显示的段不多,显示和按键在一起做也没有问题,但是不要在按键扫描程序里面死等.
例如以下的程序是一个6段数码管(共阳极),和6个按键的扫描程序,每一个按键通过二极管接到一个数码管的com信号(按键脚1接二极管的阴极,二极管的阳极接到com),6个按键的脚2并联滤波下拉后接到CPU的KeyPort:
        if(ucDispScan==0){
                ucDispScan=1;
                if(KeyPort){
                        ucKeyBuf[ucKeyPtr]|=0x20;
                } else {
                        ucKeyBuf[ucKeyPtr]&=0xdf;
                }
                LedCom6Off;
                LedSegPort=ucDispBuf[0];
                LedCom1On;
        } else if(ucDispScan==1){
                ucDispScan=2;
                if(KeyPort){
                        ucKeyBuf[ucKeyPtr]|=0x01;
                } else {
                        ucKeyBuf[ucKeyPtr]&=0xfe;
                }
                LedCom1Off;
                LedSegPort=ucDispBuf[1];
                LedCom2On;
        } else if(ucDispScan==2){
                ucDispScan=3;
                if(KeyPort){
                        ucKeyBuf[ucKeyPtr]|=0x02;
                } else {
                        ucKeyBuf[ucKeyPtr]&=0xfd;
                }
                LedCom2Off;
                LedSegPort=ucDispBuf[2];
                LedCom3On;
        } else if(ucDispScan==3){
                ucDispScan=4;
                if(KeyPort){
                        ucKeyBuf[ucKeyPtr]|=0x04;
                } else {
                        ucKeyBuf[ucKeyPtr]&=0xfb;
                }
                LedCom3Off;
                LedSegPort=ucDispBuf[3];
                LedCom4On;
        } else if(ucDispScan==4){
                ucDispScan=5;
                if(KeyPort){
                        ucKeyBuf[ucKeyPtr]|=0x08;
                } else {
                        ucKeyBuf[ucKeyPtr]&=0xf7;
                }
                LedCom4Off;
                LedSegPort=ucDispBuf[4];
                LedCom5On;
        } else {
                ucDispScan=0;
                if(KeyPort){
                        ucKeyBuf[ucKeyPtr]|=0x10;
                } else {
                        ucKeyBuf[ucKeyPtr]&=0xef;
                }
                ucKeyPtr+=1;
                if(ucKeyPtr>2){
                        ucKeyPtr=0;
                        if(ucKeyBuf[0]!=ucKeyBuf[1]){
                                if(ucKeyBuf[0]!=ucKeyBuf[2]){
                                        if(ucKeyBuf[1]!=ucKeyBuf[2]){
                                                ucKeyBuf[0]=0x00;
                                        } else {
                                                ucKeyBuf[0]=ucKeyBuf[1];
                                        }
                                }
                        }
                    ucNewKey=ucKeyBuf[0];
            if((ucNewKey!=ucOldKey)&&(ucOldKey==No_Key)){
                                if(ucNewKey!=No_Key){
                                        ucCurKey=ucNewKey;
                                        bKBKeyFlags=0;
                                        ucKeyCount=ST10msDelay2s;  /* Delay 2s. */
                                }
                        } else if(ucOldKey!=No_Key){
                                if(ucNewKey!=No_Key){
                                        if(bKBKeyFlags){
                                                bKBKeyFlags=0;
                                                ucKeyCount=ST10msDelay1s; /* Delay 1s. */
                                                 ucCurKey=ucNewKey|0xc0;
                                        }
                                }
                        }
            ucOldKey=ucNewKey;
            if(ucNewKey==No_Key){
                                ucKeyCount=0;
                                bKBKeyFlags=0;
                        }
                }
                LedCom5Off;
                LedSegPort=ucDispBuf[5];
                LedCom6On;
        }
liu81tao2003 发表于 2016-8-11 11:25 | 显示全部楼层
icecut 发表于 2016-8-11 12:25 | 显示全部楼层
你问我,你就听我的.你让我听你的,你先问问你凭什么?
论坛免费提问问题,都这态度,高手们教的过来么?
ayb_ice 发表于 2016-8-11 13:29 来自手机 | 显示全部楼层
一个小黄人 发表于 2016-8-11 10:23
谢谢您,您又类似的程序吗?您的不死等的意思是while语句中加个延时吗?

首先显示可以在定时中断中完成,这样可以节省好多延时的时间,

评分

参与人数 1威望 +1 收起 理由
一个小黄人 + 1 很给力!

查看全部评分

ayb_ice 发表于 2016-8-11 13:31 来自手机 | 显示全部楼层
其实就是状态机去实现,什么状态下做什么,然后状态转换
 楼主| 一个小黄人 发表于 2016-8-11 13:50 | 显示全部楼层
icecut 发表于 2016-8-11 12:25
你问我,你就听我的.你让我听你的,你先问问你凭什么?
论坛免费提问问题,都这态度,高手们教的过来么?
...

抱歉了,如果让您觉得我语气不对。
 楼主| 一个小黄人 发表于 2016-8-11 13:57 | 显示全部楼层
ayb_ice 发表于 2016-8-11 13:29
首先显示可以在定时中断中完成,这样可以节省好多延时的时间,

显示加在中断吗?可是我的现实需要通过按键改变的,加在中断不会影响按键吗?
 楼主| 一个小黄人 发表于 2016-8-11 13:58 | 显示全部楼层
JerryWu75 发表于 2016-8-11 11:23
如果显示的段不多,显示和按键在一起做也没有问题,但是不要在按键扫描程序里面死等.
例如以下的程序是一个6 ...

谢谢您的回复,我试试看。
ayb_ice 发表于 2016-8-11 14:12 来自手机 | 显示全部楼层
一个小黄人 发表于 2016-8-11 13:57
显示加在中断吗?可是我的现实需要通过按键改变的,加在中断不会影响按键吗? ...

这有必然关系吗
zm880517 发表于 2016-8-11 15:04 | 显示全部楼层
扫描引脚输出低电平,不能马上就读取引脚,因为不上输出0然后外部电路就立刻变成0。中间应该延时一下
okppkk1 发表于 2016-8-11 21:34 来自手机 | 显示全部楼层
需要经常点,才能有反应,说明你按键检测的频率太低了。比如2秒才扫一次。人按按键的时间最少都要100ms吧,那你如果循环检测按键,那也得100ms扫一次吧。也就是while(1)里的语句劲量保证100ms可以循环一次。这里系统时钟还有上升空间就可以加主频,不行就优化while(1)中的程序。判断按键有按下,一般是判断port口低电平,不想判断两次并且电路电源处理较好,建议考虑在port口加104电容硬件去抖。判断按下键就是去执行显示和其他程序。这里的显示和其他程序要多久时间,你都可以拿示波器抓一下。在不知道程序大概占用多久时间时,示波器是个好东西。如果你的显示和其他程序都很长,占用超过1秒或更多,你可以在程序中间分段再加判断,把按键的情况用flag,形式记录下来。等处理完你此次的现实和其他事情,再根据flag的情况去处理其他按键对应的事件。

评分

参与人数 1威望 +1 收起 理由
一个小黄人 + 1 赞一个!

查看全部评分

okppkk1 发表于 2016-8-11 21:39 来自手机 | 显示全部楼层
刚才说判断按键应该多是沿触发,一般利用在中断中置flag最效率。
handlike 发表于 2016-8-12 11:51 | 显示全部楼层
做到定时器中断里20ms一次,多次判断键是否真的按下。显示部分放到主main()里面不不要放到扫描里面去。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

66

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部