找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3019|回复: 3
打印 上一主题 下一主题
收起左侧

单片机矩阵键盘扫描误触发的问题

[复制链接]
跳转到指定楼层
楼主
本人新手
请 大家帮小弟看一下 为什么我写的这个矩阵键盘扫描函数 会误触发 像是没有消抖功能 小弟百思不得其解 请大家帮帮 谢谢了#define KeyPort P3

unsigned char KeyScan()                        //矩阵扫描,使用行列逐级扫描法
{
   unsigned char VAL;
   KeyPort=0xf0;//高四位置高,低四位拉低
   if(KeyPort!=0xf0)//表示有按键按下
   {
        Delay(10);  //去抖
        if(KeyPort!=0xf0)   //表示有按键按下
          {           
                Delay(5);
                if(KeyPort!=0xf0)
                {
                         KeyPort=0xfe; //检测第一行
                     if(KeyPort!=0xfe)
                          {
                          VAL=KeyPort&0xf0;
                            VAL+=0x0e;
                        while(KeyPort!=0xfe);
                        Delay(10);
                        while(KeyPort!=0xfe);
                               return VAL;
                         }
                }
        }


        return 0xff;
}


只检测了第一行,发现按键的时候,会有误触发
我想知道我这个逻辑哪里有问题
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:149988 发表于 2017-7-13 07:03 | 只看该作者

RE: 单片机矩阵键盘扫描误触发的问题

开发板配的矩阵键盘程序都非常好,讲解的都很详细,网上也有很多矩阵键盘的例子。拿过来仔细分析一下,真正弄懂其原理,再自我发挥,写出自己需要的矩阵键盘程序。你写的这段矩阵键盘程序,有点看不懂。开始键值KeyPort赋值0xf0,去抖、延时后KeyPort又赋值0xfe(KeyPort=0xfe; //检测第一行),如果一直有键按下KeyPort肯定不等于0xfe,但究竟是哪个键还是不清楚。经过VAL=KeyPort&0xf0; VAL+=0x0e;运算后,VAL=0xfe。这个VAL=0xfe是人为的,不是程序判断出来的。只要有键一直按下,KeyPort不会等于0xfe。 while(KeyPort!=0xfe);是成立的,仅此而已。
回复

使用道具 举报

板凳
ID:213173 发表于 2017-7-13 07:32 | 只看该作者
程序修改如下:
#define KeyPort P3
unsigned char keyscan()                                        //矩阵键盘扫描函数
{
        unsigned char temp1,temp2,VAL;                //临时变量
        static bit sign=0;                                        //按键自锁标志
        static unsigned char count=0;                //消抖计数变量
        KeyPort=0xf0;                                                //先给P3赋一个初值
        if(KeyPort!=0xf0)                                         //判断P3不等于所赋初值,说明有健按下
        {
                if(sign==0)                                                //如果按键自锁标志为0
                {
                        count++;                                        //消抖计数
                        if(count>=100)                                //消抖计数自>=100,估算主循环周期调整
                        {                                                        //摒弃Delay延时方式,提高运行效率
                                count=100;                                //防止溢出
                                sign=1;                                        //按键自锁标志置1,键不抬起,按其他键无效
                                temp1=KeyPort;                        //temp1保存高4位变化
                                KeyPort=0x0f;                        //再给P3赋值0x0f
                                temp2=KeyPort;                        //temp2保存低4位变化
                                VAL=temp2|temp1;                //VAL=高4位+低4位
                                return VAL;                                //返回VAL值
                        }
                }
        }
        else                                                                 //按键抬起
        {
                sign=0;                                                        //按键自锁标志清0
                count=0;                                                //消抖计数清0
        }
}
回复

使用道具 举报

地板
ID:164602 发表于 2017-7-13 08:30 | 只看该作者
程序问题吧。
我这里有一个例程,你看看。
/*******************************************************************************
* 函 数 名         : KeyDown
* 函数功能                   : 检测有按键按下并读取键值
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void KeyDown(void)
{
        char a=0;
        GPIO_KEY=0x0f;
        if(GPIO_KEY!=0x0f)//读取按键是否按下
        {
                Delay10ms();//延时10ms进行消抖
                if(GPIO_KEY!=0x0f)//再次检测键盘是否按下
                {
                       
                        //测试列
                        GPIO_KEY=0X0F;
                        switch(GPIO_KEY)
                        {
                                case(0X07):        KeyValue=0;break;
                                case(0X0b):        KeyValue=1;break;
                                case(0X0d): KeyValue=2;break;
                                case(0X0e):        KeyValue=3;break;
                        }
                        //测试行
                        GPIO_KEY=0XF0;
                        switch(GPIO_KEY)
                        {
                                case(0X70):        KeyValue=KeyValue;break;
                                case(0Xb0):        KeyValue=KeyValue+4;break;
                                case(0Xd0): KeyValue=KeyValue+8;break;
                                case(0Xe0):        KeyValue=KeyValue+12;break;
                        }
                        while((a<50)&&(GPIO_KEY!=0xf0))         //检测按键松手检测
                        {
                                Delay10ms();
                                a++;
                        }
                }
        }
}
对应电路如图,看看你的电路和它怎么样,才能移植。

1.jpg (25.29 KB, 下载次数: 37)

1.jpg
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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