打印
[程序源码]

按键扫描问题,都进来看看吧。

[复制链接]
2014|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
网上搜个跟人学学行不行?

大哥,我只是想找出问题。我知道扫描原理,我就是搞不懂为什么我的第一个按键和第六个按键反应很迟钝,其他的都很灵敏,不是硬件问题。

使用特权

评论回复
5
一个小黄人|  楼主 | 2016-8-11 10:12 | 只看该作者
icecut 发表于 2016-8-11 10:07
网上搜个跟人学学行不行?

您能给我看看嘛?

使用特权

评论回复
6
ayb_ice| | 2016-8-11 10:18 | 只看该作者
首先显示与扫描不要放在一起,其次不要死等,通过定时读取io状态,稍加处理就可获取按键状态,显示放在定时中断处理,从固定地方抓取要显示的数据

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
一个小黄人 + 1 很给力!
7
一个小黄人|  楼主 | 2016-8-11 10:23 | 只看该作者
ayb_ice 发表于 2016-8-11 10:18
首先显示与扫描不要放在一起,其次不要死等,通过定时读取io状态,稍加处理就可获取按键状态,显示放在定时 ...

谢谢您,您又类似的程序吗?您的不死等的意思是while语句中加个延时吗?

使用特权

评论回复
8
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;
        }

使用特权

评论回复
9
liu81tao2003| | 2016-8-11 11:25 | 只看该作者

使用特权

评论回复
10
icecut| | 2016-8-11 12:25 | 只看该作者
你问我,你就听我的.你让我听你的,你先问问你凭什么?
论坛免费提问问题,都这态度,高手们教的过来么?

使用特权

评论回复
11
ayb_ice| | 2016-8-11 13:29 | 只看该作者
一个小黄人 发表于 2016-8-11 10:23
谢谢您,您又类似的程序吗?您的不死等的意思是while语句中加个延时吗?

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

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
一个小黄人 + 1 很给力!
12
ayb_ice| | 2016-8-11 13:31 | 只看该作者
其实就是状态机去实现,什么状态下做什么,然后状态转换

使用特权

评论回复
13
一个小黄人|  楼主 | 2016-8-11 13:50 | 只看该作者
icecut 发表于 2016-8-11 12:25
你问我,你就听我的.你让我听你的,你先问问你凭什么?
论坛免费提问问题,都这态度,高手们教的过来么?
...

抱歉了,如果让您觉得我语气不对。

使用特权

评论回复
14
一个小黄人|  楼主 | 2016-8-11 13:57 | 只看该作者
ayb_ice 发表于 2016-8-11 13:29
首先显示可以在定时中断中完成,这样可以节省好多延时的时间,

显示加在中断吗?可是我的现实需要通过按键改变的,加在中断不会影响按键吗?

使用特权

评论回复
15
一个小黄人|  楼主 | 2016-8-11 13:58 | 只看该作者
JerryWu75 发表于 2016-8-11 11:23
如果显示的段不多,显示和按键在一起做也没有问题,但是不要在按键扫描程序里面死等.
例如以下的程序是一个6 ...

谢谢您的回复,我试试看。

使用特权

评论回复
16
ayb_ice| | 2016-8-11 14:12 | 只看该作者
一个小黄人 发表于 2016-8-11 13:57
显示加在中断吗?可是我的现实需要通过按键改变的,加在中断不会影响按键吗? ...

这有必然关系吗

使用特权

评论回复
17
zm880517| | 2016-8-11 15:04 | 只看该作者
扫描引脚输出低电平,不能马上就读取引脚,因为不上输出0然后外部电路就立刻变成0。中间应该延时一下

使用特权

评论回复
18
okppkk1| | 2016-8-11 21:34 | 只看该作者
需要经常点,才能有反应,说明你按键检测的频率太低了。比如2秒才扫一次。人按按键的时间最少都要100ms吧,那你如果循环检测按键,那也得100ms扫一次吧。也就是while(1)里的语句劲量保证100ms可以循环一次。这里系统时钟还有上升空间就可以加主频,不行就优化while(1)中的程序。判断按键有按下,一般是判断port口低电平,不想判断两次并且电路电源处理较好,建议考虑在port口加104电容硬件去抖。判断按下键就是去执行显示和其他程序。这里的显示和其他程序要多久时间,你都可以拿示波器抓一下。在不知道程序大概占用多久时间时,示波器是个好东西。如果你的显示和其他程序都很长,占用超过1秒或更多,你可以在程序中间分段再加判断,把按键的情况用flag,形式记录下来。等处理完你此次的现实和其他事情,再根据flag的情况去处理其他按键对应的事件。

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
一个小黄人 + 1 赞一个!
19
okppkk1| | 2016-8-11 21:39 | 只看该作者
刚才说判断按键应该多是沿触发,一般利用在中断中置flag最效率。

使用特权

评论回复
20
handlike| | 2016-8-12 11:51 | 只看该作者
做到定时器中断里20ms一次,多次判断键是否真的按下。显示部分放到主main()里面不不要放到扫描里面去。

使用特权

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

本版积分规则

8

主题

66

帖子

1

粉丝