4*4矩阵键盘

一、绪论

按键被广泛用于单片机控制,对于16个按键来说,假如还采用一个IO口控制一个按键的方式,那么单片机的IO口将会被占用的较多。所以在这里主要记录一下4*4矩阵键盘的实现方法。通过8个端口与单片机连接,4个IO口控制行,4个IO口控制列。

二、原理描述

这里我通过按行按列的方式确定每一次按下的按键具体是哪一个。

PA0-PA3控制行值,PA4-PA7控制列值

在这里插入图片描述

三、确定行值

1、将PA4-PA7配置为输出,PA0-PA3配置为输入
2、输出均置为下拉,即为0;输入均配置为上拉,即为1(有上拉电阻可以忽略配置模式)
3、当按下某个按键后,及该按键所连接的列置为0,例如按下S0,此时值为下图所示
在这里插入图片描述

四、确定列值

1、将PA0-PA3配置为输出,PA4-PA7配置为输入
2、输出均置为下拉,即为0;输入均配置为上拉,即为1
3、当按下某个按键后,及该按键所连接的列置为0,例如按下S0,此时值为下图所示
在这里插入图片描述

五、确定按键值

通过前面两步,0x70|0x08,可以确定此时S1的位置为:0x77
其余按键均可按此逻辑获得。
部分代码如下:
key.c

//确定行值
void Key_Init1(void){
	
	RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_Level_2;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	GPIO_SetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3);
	
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
 	 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_Level_2;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	GPIO_ResetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);
}
//确定列值
void Key_Init2(void){
	RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_Level_2;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	GPIO_ResetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3);
	
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_Level_2;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	GPIO_SetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);
}
//按键扫描
uint16_t Key_Scan(void){
	uint16_t row,col,res;
	Key_Init1();
	col=GPIO_ReadInputData(GPIOA);	
	col=col&0x0f;
	if(col!=0x0f)
	{
		delay10us(200);
		col=GPIO_ReadInputData(GPIOA);
		col=col&0x0f;
		if(col!=0x0f)
		{
			col=GPIO_ReadInputData(GPIOA);
			col=col&0x0f;//0x07
		}
		Key_Init2();
		row=GPIO_ReadInputData(GPIOA);
		row=row&0xf0;
		if(row!=0xf0)
		{
			delay10us(200);
			row=GPIO_ReadInputData(GPIOA);
			row=row&0xf0;
			if(row!=0xf0)
			{
				row=GPIO_ReadInputData(GPIOA);
				row=row&0xf0;//0x70
			}
			res=row|col;
		}
	}		
		return res;
}

key.h

#ifndef _MYKEY_H_
#define _MYKEY_H_
#include "stdint.h"
void Key_Init1(void);
void Key_Init2(void);
uint16_t Key_Scan(void);
#endif

main.c,核心代码展示

while(1)
{
	keyValue=Key_Scan();
	switch(keyValue)
	{
		case 0x77://写上你的按键功能代码
		break;
		case 0x7b:break;
		case 0x7d:break;
		case 0x7e:break;
			
		case 0xb7:break;
		case 0xbb:break;
		case 0xbd:break;
		case 0xbe:break;
		
		case 0xd7:break;
		case 0xdb:break;
		case 0xdd:break;
		case 0xde:break;
		
		case 0xe7:break;
		case 0xeb:break;
		case 0xed:break;
		case 0xee:break;
		default:
			break;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值