8*8矩阵键盘多键同时识别问题

2019-07-20 05:12发布

初学STM32,做个8*8矩阵键盘试验,编了个小程序,已经能识别同时按下或松开的任意单个键,
用GPIOF高8位为行,GPIOF低8位为列,对GPIOF的总键值进行异或,取得活动键值,并判断是按下还是松开;
64KEY.jpg
[url=]20 秒后保存[/url] [url=]保存数据[/url] | [url=]恢复数据[/url]    [url=]字数检查[/url] | [url=]清除内容[/url]    [url=]加大编辑框[/url] | [url=]缩小编辑框[/url]


附加选项



本版积分规则发布悬赏(求助)  保存草稿








HL.jpg
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
6条回答
sqxy123
1楼-- · 2019-07-20 08:24
源码如下:

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "key.h"
#include "stm32f4xx_gpio.h"


//ALIENTEK 探索者STM32F407开发板 实验3
//按键输入实验-库函数版本
//技术支持:www.openedv.com
//淘宝店铺:http://eboard.taobao.com
//广州市星翼电子科技有限公司   
//作者:正点原子 @alientek

//8*8矩阵按键输入识别,GPIOF高8位为行,GPIOF低8位为列


void Input_KEY_Init(void)
{
        GPIO_InitTypeDef  GPIO_InitStructure;
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);//使能GPIOF时钟
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|

GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|

GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15; //KEY对应引脚
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通输入模式
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;//下拉模式
        GPIO_Init(GPIOF, &GPIO_InitStructure);//初始化GPIOF
}

int Count1(unsigned char n)
{
    int sum=0;
    while(n)
    {
        n&=(n-1);
        sum++;
    }
    return sum;
}


int main(void)
{
       
        u16

Last_key=0,Current_key=0,key_bit=0,key_H8=0xff00,key_L8=0x00ff,Action_key=0;        
        int i,j;
       
       
       
        uart_init(115200);

        Input_KEY_Init();        //GPIOF的16位IO初始化,下拉输入
        delay_init(100);          //初始化延时函数
        while(1)
        {

                delay_ms(200);
                Current_key=GPIO_ReadInputData(GPIOF);                //得到当前总键值
           if(Current_key!=Last_key)
             {       
                        printf(" 位键值bit= ");
                        for(i=0x8000;i>=0x0001;i=i>>1)        //显示GPIOF的16位IO的各位数值
                        {
                                key_bit=GPIO_ReadInputDataBit(GPIOF,i);
                                printf("%d ",key_bit);
                        }
                        printf(" 当前总键值Current_key=%x ",Current_key);
               
                        key_H8=0xff00&Last_key;                //取得上次总键值的高8位;
                        key_L8=0x00ff&Last_key;                //取得上次总键值的低8位;
                        printf(" Last_key高8位=%x ",key_H8);
                        printf(" Last_key低8位=%x ",key_L8);
                       
                        Action_key=Current_key^Last_key;
                        printf(" Current_key^Last_key=%x ",Action_key);
               
                        if(        0==(0xff00&Action_key))        //判断是否同行
                        {       
                        Action_key=Action_key|key_H8;                //取回原行值
                        }
                        if(        0==(0x00ff&Action_key))        //判断是否同列
                        {       
                        Action_key=Action_key|key_L8;                //取回原列值
                        }       
                       
                i=Count1(Last_key);
                j=Count1(Current_key);
                if(j>i) //有键按下;
                {printf(" 按下按键=%x ",Action_key);        }
                if(j<i) //有键松开;
                {printf(" 松开按键=%x ",Action_key);        }

                Last_key=Current_key;
             }       
                       
        }

}






sqxy123
2楼-- · 2019-07-20 09:43
程序在开发板调试运行通过
操作系统
3楼-- · 2019-07-20 12:45
 精彩回答 2  元偷偷看……
sqxy123
4楼-- · 2019-07-20 15:27
操作系统 发表于 2017-9-9 09:23
应该是同时按下ADC,或者得到同时按下ABCD的结果吧.这个叫幻影键.又称鬼键..这个没有办法.硬件上决定了一定 ...

请教,我有个想法,有7个延迟芯片,把9到15行的输入分别延迟不同的时间,延迟时间大于防抖扫描周期,强制控制每次扫描只能得到同一行上的键,你看这样可以吗?
操作系统
5楼-- · 2019-07-20 19:38
随便怎么处理,都行不能.这是硬件决定的.软件没有办法
xiatianyun
6楼-- · 2019-07-20 20:02
 精彩回答 2  元偷偷看……

一周热门 更多>