OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2771|回复: 2

矩阵键盘读取不正常的问题

[复制链接]

76

主题

187

帖子

0

精华

高级会员

Rank: 4

积分
597
金钱
597
注册时间
2014-10-15
在线时间
138 小时
发表于 2020-6-18 11:02:30 | 显示全部楼层 |阅读模式
1金钱
我写了个矩阵键盘程序,有点问题,有时按下一个按键,返回两次键值,有时返回0(没有检测到按键)
我调试,返回键值,通过网口发送到网络调试助手。
原理图:
5.jpg
程序:
void KEY_Init(void)
{

GPIO_InitTypeDef  GPIO_InitStructure;
       
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE);         //使能PA,PD端口时钟
       
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;                                 //LED0-->PA.8 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //IO口速度为50MHz
GPIO_Init(GPIOE, &GPIO_InitStructure);                                         //根据设定参数初始化GPIOA.8

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 ;                                 //LED0-->PA.8 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;                  //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //IO口速度为50MHz
GPIO_Init(GPIOE, &GPIO_InitStructure);                                         //根据设定参数初始化GPIOA.8
       
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;                             //LED1-->PD.2 端口配置, 推挽输出
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;                  //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //IO口速度为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure);                                           //推挽输出 ,IO口速度为50MHz
       

}
void Hang_Output(void)
{
        GPIO_InitTypeDef  GPIO_InitStructure;
       
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE);         //使能PA,PD端口时钟
       


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 ;                                 //LED0-->PA.8 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //IO口速度为50MHz
GPIO_Init(GPIOE, &GPIO_InitStructure);                                         //根据设定参数初始化GPIOA.8
       
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;                             //LED1-->PD.2 端口配置, 推挽输出
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //IO口速度为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure);                                           //推挽输出 ,IO口速度为50MHz
       
}
void Hang_Input(void)
{
        GPIO_InitTypeDef  GPIO_InitStructure;
       
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE);         //使能PA,PD端口时钟
       


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 ;                                 //LED0-->PA.8 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;                  //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //IO口速度为50MHz
GPIO_Init(GPIOE, &GPIO_InitStructure);                                         //根据设定参数初始化GPIOA.8
       
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;                             //LED1-->PD.2 端口配置, 推挽输出
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;                  //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //IO口速度为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure);                                           //推挽输出 ,IO口速度为50MHz
       
}
void Lie_Input(void)
{
        GPIO_InitTypeDef  GPIO_InitStructure;
       
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);         //使能PA,PD端口时钟
       
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;                                 //LED0-->PA.8 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;                  //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //IO口速度为50MHz
GPIO_Init(GPIOE, &GPIO_InitStructure);                                         //根据设定参数初始化GPIOA.8
}


void Lie_Output(void)
{
        GPIO_InitTypeDef  GPIO_InitStructure;
       
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);         //使能PA,PD端口时钟
       
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;                                 //LED0-->PA.8 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //IO口速度为50MHz
GPIO_Init(GPIOE, &GPIO_InitStructure);                                         //根据设定参数初始化GPIOA.8
}
unsigned char GetKey(void)
{
       
        unsigned char keyvalue = 0;
        uint16_t hangvalue=0,lievalue=0;
       
// 第1回合第1步
        KEY_Init();
        delay_us(20);
        GPIO_ResetBits(GPIOE,GPIO_Pin_6 | GPIO_Pin_5 | GPIO_Pin_4 | GPIO_Pin_3);                                                  //PE.6,5,4,3 输出低
       
       
       
        hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0380)>>4);
        if (hangvalue != 0x3f)// 从IO口输入,读IO口
        {
        // 读出的不是0x0f说明有按键被按下
        // 第1回合第2步:读出端口从读出值来判断是哪一行
                delay_ms(20);
                GPIO_ResetBits(GPIOE,GPIO_Pin_6 | GPIO_Pin_5 | GPIO_Pin_4 | GPIO_Pin_3);                                                  //PE.6,5,4,3 输出低
               
               
                hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0380)>>4);
                if (hangvalue != 0x3f)// 从IO口输入,读IO口
                {
                        Hang_Output();
                        Lie_Input();
                        delay_us(20);
                // 第一回合中算出行号
                        switch (hangvalue)
                        {
                                case 0x1F:
                                               
                                                GPIO_ResetBits(GPIOB,GPIO_Pin_9);
                                                GPIO_SetBits(GPIOB,GPIO_Pin_8);
                                                GPIO_SetBits(GPIOB,GPIO_Pin_7);
                                                GPIO_SetBits(GPIOE,GPIO_Pin_2);
                                                GPIO_SetBits(GPIOE,GPIO_Pin_1);
                                                GPIO_SetBits(GPIOE,GPIO_Pin_0);
                                                lievalue=((GPIO_ReadInputData(GPIOE)&0x78)>>3);
                                                switch(lievalue)
                                                {
                                                        case 0x07:
                                                                keyvalue=4;
                                                                break;
                                                        case 0x0b:
                                                                keyvalue=9;
                                                                break;
                                                        case 0x0d:
                                                                keyvalue=14;
                                                                break;
                                                        case 0x0e:
                                                                keyvalue=20;
                                                                break;
                                                        default :
                                                                break;
                                                }
                                        break;
                                case 0x2F:
                                                GPIO_SetBits(GPIOB,GPIO_Pin_9);
                                                GPIO_ResetBits(GPIOB,GPIO_Pin_8);
                                                GPIO_SetBits(GPIOB,GPIO_Pin_7);
                                                GPIO_SetBits(GPIOE,GPIO_Pin_2);
                                                GPIO_SetBits(GPIOE,GPIO_Pin_1);
                                                GPIO_SetBits(GPIOE,GPIO_Pin_0);
                                                lievalue=((GPIO_ReadInputData(GPIOE)&0x78)>>3);
                                                switch(lievalue)
                                                {
                                                        case 0x07:
                                                                keyvalue=5;
                                                                break;
                                                        case 0x0b:
                                                                keyvalue=10;
                                                                break;
                                                        case 0x0d:
                                                                keyvalue=15;
                                                                break;
                                                        case 0x0e:
                                                                keyvalue=21;
                                                                break;
                                                        default :
                                                                break;
                                                }
                                        break;
                                case 0x37:
                                                GPIO_SetBits(GPIOB,GPIO_Pin_9);
                                                GPIO_SetBits(GPIOB,GPIO_Pin_8);
                                                GPIO_ResetBits(GPIOB,GPIO_Pin_7);
                                                GPIO_SetBits(GPIOE,GPIO_Pin_2);
                                                GPIO_SetBits(GPIOE,GPIO_Pin_1);
                                                GPIO_SetBits(GPIOE,GPIO_Pin_0);
                                                lievalue=((GPIO_ReadInputData(GPIOE)&0x78)>>3);
                                                switch(lievalue)
                                                {
                                                       
                                                        case 0x0d:
                                                                keyvalue=16;
                                                                break;
                                                        case 0x0e:
                                                                keyvalue=22;
                                                                break;
                                                        default :
                                                                break;
                                                }
                                        break;
                                case 0x3B:
                                                GPIO_SetBits(GPIOB,GPIO_Pin_9);
                                                GPIO_SetBits(GPIOB,GPIO_Pin_8);
                                                GPIO_SetBits(GPIOB,GPIO_Pin_7);
                                                GPIO_ResetBits(GPIOE,GPIO_Pin_2);
                                                GPIO_SetBits(GPIOE,GPIO_Pin_1);
                                                GPIO_SetBits(GPIOE,GPIO_Pin_0);
                                                lievalue=((GPIO_ReadInputData(GPIOE)&0x78)>>3);
                                                switch(lievalue)
                                                {
                                                        case 0x07:
                                                                keyvalue=1;
                                                                break;
                                                        case 0x0b:
                                                                keyvalue=6;
                                                                break;
                                                        case 0x0d:
                                                                keyvalue=11;
                                                                break;
                                                        case 0x0e:
                                                                keyvalue=17;
                                                                break;
                                                        default :
                                                                break;
                                                }
                                        break;
                                case 0x3D:
                                                GPIO_SetBits(GPIOB,GPIO_Pin_9);
                                                GPIO_SetBits(GPIOB,GPIO_Pin_8);
                                                GPIO_SetBits(GPIOB,GPIO_Pin_7);
                                                GPIO_SetBits(GPIOE,GPIO_Pin_2);
                                                GPIO_ResetBits(GPIOE,GPIO_Pin_1);
                                                GPIO_SetBits(GPIOE,GPIO_Pin_0);
                                                lievalue=((GPIO_ReadInputData(GPIOE)&0x78)>>3);
                                                switch(lievalue)
                                                {
                                                        case 0x07:
                                                                keyvalue=2;
                                                                break;
                                                        case 0x0b:
                                                                keyvalue=7;
                                                                break;
                                                        case 0x0d:
                                                                keyvalue=12;
                                                                break;
                                                        case 0x0e:
                                                                keyvalue=18;
                                                                break;
                                                        default :
                                                                break;
                                                }
                                        break;
                                case 0x3E:
                                                GPIO_SetBits(GPIOB,GPIO_Pin_9);
                                                GPIO_SetBits(GPIOB,GPIO_Pin_8);
                                                GPIO_SetBits(GPIOB,GPIO_Pin_7);
                                                GPIO_SetBits(GPIOE,GPIO_Pin_2);
                                                GPIO_SetBits(GPIOE,GPIO_Pin_1);
                                                GPIO_ResetBits(GPIOE,GPIO_Pin_0);
                                                lievalue=((GPIO_ReadInputData(GPIOE)&0x78)>>3);
                                                switch(lievalue)
                                                {
                                                        case 0x07:
                                                                keyvalue=3;
                                                                break;
                                                        case 0x0b:
                                                                keyvalue=8;
                                                                break;
                                                        case 0x0d:
                                                                keyvalue=13;
                                                                break;
                                                        case 0x0e:
                                                                keyvalue=19;
                                                                break;
                                                        default :
                                                                break;
                                                }
                                        break;
                                default: break;
                               
                        }
                        Hang_Input();
                        Lie_Output();
                        delay_us(20);
                        GPIO_ResetBits(GPIOE,GPIO_Pin_6 );                                                  //PE.6,5,4,3 输出低
                        GPIO_SetBits(GPIOE, GPIO_Pin_5 );
                        GPIO_SetBits(GPIOE, GPIO_Pin_4 );
                        GPIO_SetBits(GPIOE, GPIO_Pin_3 );
                        hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0300)>>5);
                        while (hangvalue != 0x1f)
                        {
                               
                                hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0300)>>5);
                        }
                        GPIO_SetBits(GPIOE,GPIO_Pin_6 );                                                  //PE.6,5,4,3 输出低
                        GPIO_ResetBits(GPIOE, GPIO_Pin_5 );
                        GPIO_SetBits(GPIOE, GPIO_Pin_4 );
                        GPIO_SetBits(GPIOE, GPIO_Pin_3 );
                       
                        hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0300)>>5);
                        while (hangvalue != 0x1f)
                        {
                               
                                hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0300)>>5);
                        }
                        GPIO_SetBits(GPIOE,GPIO_Pin_6 );                                                  //PE.6,5,4,3 输出低
                        GPIO_SetBits(GPIOE, GPIO_Pin_5 );
                        GPIO_ResetBits(GPIOE, GPIO_Pin_4 );
                        GPIO_SetBits(GPIOE, GPIO_Pin_3 );
                       
                        hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0380)>>4);
                        while (hangvalue != 0x3f)
                        {
                               
                                hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0380)>>4);
                        }
                        GPIO_SetBits(GPIOE,GPIO_Pin_6 );                                                  //PE.6,5,4,3 输出低
                        GPIO_SetBits(GPIOE, GPIO_Pin_5 );
                        GPIO_SetBits(GPIOE, GPIO_Pin_4 );
                        GPIO_ResetBits(GPIOE, GPIO_Pin_3 );
                       
                        hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0380)>>4);
                        while (hangvalue != 0x3f)
                        {
                               
                                hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0380)>>4);
                        }
                        return keyvalue;
                }
                return 0;
        }
        return 0;
}
大神看看,哪里有问题?谢谢!






正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

12

主题

3399

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8679
金钱
8679
注册时间
2020-5-11
在线时间
4159 小时
发表于 2020-6-18 11:31:20 | 显示全部楼层
本帖最后由 LcwSwust 于 2020-6-18 11:34 编辑

。。。。。。。。。。。。。。。。。。再回答一次:你的思路是:所有行(行和列好像是反的)置低,检测列线有变低就进行下一步,检测是哪一行;
问题在于如果进行下一步前按键放开了,case不成立keyvalue就为0。
按键还是要注意加消抖的,比如检测到多次keyvalue为0才认为它真的是0.


专治疑难杂症
回复

使用道具 举报

76

主题

187

帖子

0

精华

高级会员

Rank: 4

积分
597
金钱
597
注册时间
2014-10-15
在线时间
138 小时
 楼主| 发表于 2020-6-18 11:47:48 | 显示全部楼层
LcwSwust 发表于 2020-6-18 11:31
。。。。。。。。。。。。。。。。。。再回答一次:你的思路是:所有行(行和列好像是反的)置低,检测 ...

一开始keyvalue赋初值0了。
加延时消抖了
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-17 08:27

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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