STM32F407ZGT6矩阵按键

STM32F407ZGT6矩阵按键

矩阵按键

单片机用来控制按键时,为节省IO口的使用,常常将按键搞成矩阵按键,这里用的是5个IO,搞为2*3=6个按键,IO为G0,G1,G2,G3,G4 ,可自行更改。使用多个IO口原理相同

在这里插入图片描述

大概思路

  1. 初始化IO,将行IO设置为推挽输出,列IO设置为上拉输入(初始化为高电平)
  2. 将行IO设置输出低电平0
  3. 检测列IO是否为1,如果不是,则有按键按下(注意消抖)
  4. 有按键按下时,行 列 转变,将列IO设置为推挽输出,行IO设置为上拉输入。列IO输出低电平0,检测行IO哪个为低电平即可确定哪个按键按下
  5. 检测按键是否松开
  6. 返回哪个按键按下

代码

头文件没有的记得删除

#include "key.h"
#include "delay.h" 
#include <led.h>
#include "oled.h"

extern u8 KeyValue;

u8 KEY_Init(void)
{
	
	GPIO_InitTypeDef  GPIO_InitStructure;
	u8 cord_h=0XFF,cord_l=0XFF;  // h为行,l为列
        u8 Val = 0xFF;
	      u8 k1;
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);//使能时钟
	/*行线推挽输出 */
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
        GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1;
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_2MHz;
        GPIO_Init(GPIOG,&GPIO_InitStructure);

	/* 列线上拉输入 */
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN;
        GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;
        GPIO_Init(GPIOG,&GPIO_InitStructure);
	
	/*行线输出低电平 */
        GPIO_WriteBit(GPIOG, GPIO_Pin_0|GPIO_Pin_1, Bit_RESET);
        delay_us(100);

/* 读列线值,将各位数值(0或1)放到 cord_l低3位*/
        cord_l&=(u8)((GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_4)<<2)|
                     (GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_2)<<1)|
                     (GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_3)<<0));
        if(cord_l!=0X07) //低三位不为1时有按键按下
        {
            delay_ms(10);       //消抖
            cord_l&=(u8)((GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_4)<<2)|
                         (GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_2)<<1)|
                         (GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_3)<<0));
					if(cord_l!=0X07)
            {
                    /* 确认按下,行 列 转变 */

                    /* 列线输出*/
                    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
                    GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;

                    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;
                    GPIO_Init(GPIOG,&GPIO_InitStructure);
							
							/* 行线输入 */                   
                    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN;
                    GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;

                    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1;
                    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_2MHz;
                    GPIO_Init(GPIOG,&GPIO_InitStructure);

                    /* 输出低电平 */
                    GPIO_WriteBit(GPIOG, GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4, Bit_RESET);
                    delay_ms(2);
                    /*读入行线值,放到cord_h的高四位的后两位*/
                    cord_h&=(u8)((GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_1)<<5)| 
                                 (GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_0)<<4));
                    
                    Val=(cord_h|cord_l); // 两数相或,判断Val数值即可知道哪个按键按下,看下面图片
                    //判断按键是否松开
                    k1=(u8)((GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_1)<<5)| 
                            (GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_0)<<4)|
                            (GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_4)<<2)|
                            (GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_2)<<1)|
														(GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_3)<<0)
														);
														while(k1!=0x30)
														{
															k1=(u8)((GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_1)<<5)| 
                            (GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_0)<<4)|
                            (GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_4)<<2)|
                            (GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_2)<<1)|
														(GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_3)<<0)
														);
														}
										 return Val;
					    }

					}
				return Val;
				}					


void KEY_Scan(u8 a)    //读按键返回值(Val)
{	 
		  
	switch (a)      //case  里面的数值已有改动,不一定对,需自行计算
	{
		case(0x13):KeyValue=1;OLED_ShowNum(0,0,KeyValue,4,2);break;
		case(0x15):KeyValue=2;OLED_ShowNum(0,0,KeyValue,4,2);break;
		case(0x16):KeyValue=3;OLED_ShowNum(0,0,KeyValue,4,2);break;
		case(0x23):KeyValue=4;OLED_ShowNum(0,0,KeyValue,4,2);break;
		case(0x25):KeyValue=5;OLED_ShowNum(0,0,KeyValue,4,2);break;
		case(0x26):KeyValue=6;OLED_ShowNum(0,0,KeyValue,4,2);break;
		default : break;//无按键按下
	}  
	
	
}


在这里插入图片描述

注意

用时需改变IO及case里面的数值

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值