打印
[STM32]

矩阵键盘的问题

[复制链接]
1021|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
我写了个矩阵键盘的程序,效果不太好。
原理图:

代码:
//初始化PA8和PD2为输出口.并使能这两个口的时钟                    
//LED IO初始化
void KEY_Init(void)
{

GPIO_InitTypeDef  GPIO_InitStructure;
       
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE);         //使能PB,PE端口时钟
       
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;                                 
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;                  //开漏输出

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //IO口速度为50MHz
GPIO_Init(GPIOE, &GPIO_InitStructure);                                         

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 ;                                 
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;                  //浮空输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //IO口速度为50MHz
GPIO_Init(GPIOE, &GPIO_InitStructure);                                         
       
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;                             
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;                  //浮空输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //IO口速度为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure);                                            
       

}

unsigned char GetKey(void)
{
       
        unsigned char keyvalue = 0;
        uint16_t hangvalue=0;
       

        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)        // 读出的不是0x3f说明有按键被按下
        {
       
       
                delay_ms(20);                                //延时消抖
                hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0380)>>4);
                if (hangvalue != 0x3f)        // 读出的不是0x3f说明有按键被按下
                {
                        GPIO_ResetBits(GPIOE,GPIO_Pin_6);                                                  //PE.6输出低
                        GPIO_SetBits(GPIOE,GPIO_Pin_5 | GPIO_Pin_4 | GPIO_Pin_3);                                         
                       
                       
                        hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0300)>>5);
                        //hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0380)>>4);
                       
               
                        switch (hangvalue)
                        {
                                case 0x0F:

                                                                keyvalue=4;

                                        break;
                                case 0x17:
                                               
                                                                keyvalue=5;
               
                                        break;
                                case 0x1b:
                                                                keyvalue=1;
                                        break;
                                case 0x1d:
                                               
                                               
                                                                keyvalue=2;
                                                               
                                        break;
                                case 0x1e:
                                               
                                               
                                                                keyvalue=3;
                                                               
                                        break;
                               
                                default: break;
                               
                        }
                       
                if(keyvalue==0)
                {
                        GPIO_ResetBits(GPIOE, GPIO_Pin_5 );
                        GPIO_SetBits(GPIOE,GPIO_Pin_6 | GPIO_Pin_4 | GPIO_Pin_3);
                       
                       
                        hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0300)>>5);
                       
                       
                        switch (hangvalue)
                        {
                                case 0x0F:
                                               
                                               
                                               
                                                                keyvalue=9;
                                                       
                                        break;
                                case 0x17:
                                               
                                               
                                                                keyvalue=10;
                                       
                                        break;
                                case 0x1b:
                                               
                                               
                                                                keyvalue=6;
                                               
                                        break;
                                case 0x1d:
                                               
                                               
                                                                keyvalue=7;
                                       
                                        break;
                                case 0x1e:
                                               
                                               
                                                                keyvalue=8;
                                               
                                        break;
                               
                                       
                                default: break;
                               
                        }
                }
       
        if(keyvalue==0)
        {
                GPIO_ResetBits(GPIOE, GPIO_Pin_4 );
                GPIO_SetBits(GPIOE,GPIO_Pin_6 | GPIO_Pin_3 | GPIO_Pin_5);
               
               
                hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0380)>>4);
       
               
               
                // 第一回合中算出行号
                        switch (hangvalue)
                        {
                                case 0x1F:
                                               
                                               
                                       
                                                                keyvalue=14;
                                       
                                        break;
                                case 0x2F:
                                               
                                               
                                                                keyvalue=15;
                               
                                        break;
                                case 0x37:
                                               
                                               
                                                                keyvalue=16;
                                       
                                        break;
                                case 0x3B:
                                               
                                               
                                                                keyvalue=11;
                                       
                                        break;
                                case 0x3D:
                                               
                                               
                                                                keyvalue=12;
                                               
                                        break;
                                case 0x3E:
                                               
                                               
                                                                keyvalue=13;
                               
                                        break;
                                default: break;
                               
                        }
                }       
                if(keyvalue==0)
                {
                        GPIO_SetBits(GPIOE,GPIO_Pin_6 | GPIO_Pin_4 | GPIO_Pin_5);
                        GPIO_ResetBits(GPIOE, GPIO_Pin_3 );
                       
                        hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0380)>>4);
               
                        switch (hangvalue)
                        {
                                case 0x1F:
                                               
                                               
                                               
                                                                keyvalue=20;
                                       
                                        break;
                                case 0x2F:
                                               
                                               
                                                                keyvalue=21;
                                       
                                        break;
                                case 0x37:
                                               
                                               
                                                                keyvalue=22;
                                               
                                        break;
                                case 0x3B:
                                               
                                               
                                                                keyvalue=17;
                                       
                                        break;
                                case 0x3D:
                                               
                                                                keyvalue=18;
                                       
                                        break;
                                case 0x3E:
                                               
                                               
                                                                keyvalue=19;
                                               
                                        break;
                                default: break;
                               
                        }
                }
                        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);
                        while (hangvalue != 0x3f)
                        {
                               
                                hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0380)>>4);
                        }
                       
                        return keyvalue;
                }
                return 0;
        }
        return 0;
}

有的按键检测不准:
按键1,2,3,4,5,是1,2,3,4,5
按键6,7,8,9,10,是1,2,3,9,10
按键11,12,13,14,15是1,2,3,14,15.
按键16,17,18,19,20是16,1,2,3,20
请问高手,哪里有错?谢谢!

使用特权

评论回复

相关帖子

沙发
wandersky| | 2020-7-9 11:54 | 只看该作者
本帖最后由 wandersky 于 2020-7-9 11:55 编辑

GPIO_ResetBits(GPIOE,GPIO_Pin_6);                                                  //PE.6输出低
GPIO_SetBits(GPIOE,GPIO_Pin_5 | GPIO_Pin_4 | GPIO_Pin_3);

这后面加延迟, delay_ms(1);

应该可以解决
或者把GPIO_Mode_IN_FLOATING浮动输入改为普通输入,应该也行

使用特权

评论回复
板凳
比神乐|  楼主 | 2020-7-9 13:36 | 只看该作者
wandersky 发表于 2020-7-9 11:54
GPIO_ResetBits(GPIOE,GPIO_Pin_6);                                                  //PE.6输出低
GPIO ...

谢谢!好了。
不过普通输入是什么意思?上拉输入吗?

使用特权

评论回复
地板
ZHMSGE| | 2020-7-10 10:19 | 只看该作者
用AD口不好吗?

使用特权

评论回复
5
比神乐|  楼主 | 2020-7-10 10:50 | 只看该作者

板子已经设计好啦,不过没听说矩阵键盘用AD口的

使用特权

评论回复
评论
ZHMSGE 2020-7-13 09:45 回复TA
没说矩阵键盘用AD 口,按键接成分压式,用AD口检测电压 
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

438

主题

3433

帖子

7

粉丝