矩阵键盘——基于stm32单片机

目录

基本原理

矩阵按键原理图

初始化

识别键码

GPIO_Write()函数和GPIO_ReadInputData()函数

读取列数

读取行数

返回键码


基本原理

了解矩阵键盘之前,应当要对基本按键的检测要有认识:如下图

图源up主  江协科技

 右边按键一端接低电平,一段接PB1。设置PB1为上拉输入,相当于按键两端分别置0和1(低电平和高电平)。按键未按下时,对PB1检测,PB1电平就为高(1)。那么当按键按下时,PB1与地导通,此时对PB1检测,PB1电平就为低(0)。

所以,通过检测原来高电平的引脚是否变低则可以判断按键是否按下。

矩阵按键原理图

 

初始化

这里我初始化是将高四位引脚设置为上拉输入,低四位引脚设置为推挽输出。

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
uint16_t keyz=0;

void Key_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE );
	
	GPIO_InitTypeDef GPIO_KEY0_3;
	GPIO_KEY0_3.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_KEY0_3.GPIO_Pin=GPIO_Pin_0 |GPIO_Pin_1 |GPIO_Pin_2 |GPIO_Pin_3 ;
	GPIO_KEY0_3.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init (GPIOA ,&GPIO_KEY0_3);
	
	GPIO_InitTypeDef GPIO_KEY1_4;
	GPIO_KEY1_4.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_KEY1_4.GPIO_Pin=GPIO_Pin_4 |GPIO_Pin_5 |GPIO_Pin_6 |GPIO_Pin_7 ;
	GPIO_KEY1_4.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init (GPIOA ,&GPIO_KEY1_4);
}	

识别键码

GPIO_Write()函数和GPIO_ReadInputData()函数

GPIO_Write()函数可以对多个引脚同时进行配置,此函数有两个参数,第一个为引脚分组,第二个为一个十六进制数。这个十六进制数就是按其对应的二进制对引脚电平进行配置。如GPIO_Write(GPIOA ,0xF0);为1111 0000,即对PA0-PA3引脚置低电平,对PA4-PA8引脚置高电平。

十六进制转换表

 GPIO_ReadInputData()函数输出的是十六进制表示的引脚状态。

读取列数

当按键未按下时使用 GPIO_ReadInputData()函数读取按键,读取值为0xF0,即1111 0000;

高四位代表 列 对应引脚状态,低四位代表 行 对应引脚状态。

如果当按键按下时使用 GPIO_ReadInputData()函数读取按键,此时按下按键 列数 对应的引脚为0,再进行Lie=~GPIO_ReadInputData (GPIOA ); Lie=Lie&0xF0;    则得到列数。

读取行数

将行对应引脚电位逐次拉高,当轮到 按下按键对应行数时 ,由于按键两端都为1,则(GPIO_ReadInputData (GPIOA )&0xF0)!=0xF0;否则(GPIO_ReadInputData (GPIOA )&0xF0)==0xF0;由此可得行数。

u16 Key_Scan(void)
{
	uint8_t Hang,Lie,k,i;
	
	GPIO_Write(GPIOA ,0xF0);					    //将A0-A3口和A4-7口电位分别置成低电位和高电位
	//0xF0 转换成二进制为 1111 0000;
	if((GPIO_ReadInputData(GPIOA)&0xF0)!=0xF0)      //判断按键是否按下
	{
		Delay_ms (40);                              //按键消抖
		if((GPIO_ReadInputData(GPIOA)&0xF0)!=0xF0)  //再次判断
		{
			
			Hang=GPIO_ReadInputData (GPIOA );	    //给Hang赋上初值,读取按键按下后得到的代码,假设为1011 0000 (0xB0)
			Lie=~Hang;								//对Hang按位取反,即0100 1111
			Lie=Lie&0xF0;										 					//0100 1111 &1111 0000得到0100 0000 即为列数
			//得到列数
			for(i=0;i<4 && ((Hang&0xF0)!=0xF0);i++) //逐次将行拉高,判断列数中原来变低的位是否变高
			{																					//读到之前检测到为低的列变高则推出
				GPIO_Write (GPIOA ,0xF0|(0x01<<i));	//进行行扫描,逐次将行口线拉高,列保持为按下的状态
				Hang=GPIO_ReadInputData (GPIOA );	//读取IO口,用以判断是否扫描到行坐标			
			}
			Hang&=0x0F;
			//得到行值
			k=Hang|Lie;                             //行列相加则得到键码
			
			GPIO_Write (GPIOA ,0xF0);				//A0-A3拉低,A4-A7拉高,此处用来将行状态初始化为未按下时的状态		
			while((GPIO_ReadInputData(GPIOA)&0xF0)!=0xF0)//判释放
			{
				Delay_ms (40);						//后延消抖。时间需要长一点
			}
			return k;						
            //返回键码
		}
		
	}
	return (0);						                //无键按下,返回0
}

返回键码

u16 Key_Get(void)
{
	keyz =Key_Scan ();
	uint16_t Keyx=0;
	if (keyz!=0)
	{		
		switch(keyz)
		{
			case 0x81:Keyx=1;break;
			case 0x82:Keyx=2;break;
			case 0x84:Keyx=3;break;
			case 0x88:Keyx=4;break;
			case 0x41:Keyx=5;break;
			case 0x42:Keyx=6;break;
			case 0x44:Keyx=7;break;
			case 0x48:Keyx=8;break;
			case 0x21:Keyx=9;break;
			case 0x22:Keyx=10;break;
			case 0x24:Keyx=11;break;
			case 0x28:Keyx=12;break;
			case 0x11:Keyx=13;break;
			case 0x12:Keyx=14;break;
			case 0x14:Keyx=15;break;
			case 0x18:Keyx=16;break;
			default:break;
		}
	}
	return Keyx;
	
}

实例:单数遇到双数按键分别亮两个不同的灯mat key · 灵槐梦/stm32 - 码云 - 开源中国 (gitee.com)

更新,对于行判断的解释: 

  • 37
    点赞
  • 104
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
ct107d单片机是一种常见的单片机类型,广泛应用于各种电子设备中。蓝桥杯是中国著名的计算机及信息技术竞赛,矩阵键盘是一种常见的输入设备。下面我将介绍ct107d单片机如何与蓝桥杯矩阵键盘配合使用。 首先,ct107d单片机具有输入输出接口,可以与外部设备进行数据交互。蓝桥杯矩阵键盘通常采用矩阵排列的按钮形式,可以通过多个引脚与单片机相连。我们需要在单片机上配置对应的引脚,使其与蓝桥杯矩阵键盘的按键相对应。 然后,我们需要编写程序来读取输入的按键信息。在ct107d单片机上,可以使用GPIO口中断来实现按键的检测功能。当按键被按下时,引脚电平发生变化,触发GPIO口中断,单片机会执行相应的中断服务程序。我们可以在中断服务程序中读取按键的状态,并根据不同按键进行不同的处理。 在程序设计过程中,我们可以利用矩阵键盘的特性,将按键映射为矩阵的行和列。通过循环扫描的方式,逐一检测矩阵中的每个按键,并根据按键的状态进行相应的操作。例如,当按键按下时,可以执行一些特定的功能,如发送数据、改变显示内容等。 总结起来,ct107d单片机与蓝桥杯矩阵键盘的配合使用,需要在单片机上配置引脚连接,编写相应的程序来读取按键信息,并根据按键状态进行相应的处理。这样,就能够实现方便的按键输入功能,在蓝桥杯竞赛及其他实际应用中发挥作用。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值