STM32矩阵键盘——行列扫描编码模式

不同于之前一篇,这篇就是走常规路子的方法了,

KEY.C

#include "Key.h"

/********************************配置IO为上拉输入********************************************/
#define configInputPullUp(port, pin, GPIO_InitStruct) { \
/*        HAL_GPIO_WritePin(port, pin, GPIO_PIN_RESET); */ \
        (GPIO_InitStruct)->Pin = pin ; \
        (GPIO_InitStruct)->Mode = GPIO_MODE_INPUT ; \
        (GPIO_InitStruct)->Pull = GPIO_PULLUP ; \
        (GPIO_InitStruct)->Speed = GPIO_SPEED_FREQ_LOW; \
        HAL_GPIO_Init(port, GPIO_InitStruct) ; \
}

/********************************配置IO为推挽输出低电平********************************************/
#define configOutputLow(port, pin, GPIO_InitStruct) { \
        (GPIO_InitStruct)->Pin = pin ; \
        (GPIO_InitStruct)->Mode = GPIO_MODE_OUTPUT_PP ; \
        (GPIO_InitStruct)->Pull = GPIO_NOPULL ; \
        (GPIO_InitStruct)->Speed = GPIO_SPEED_FREQ_LOW; \
        HAL_GPIO_Init(port, GPIO_InitStruct) ; \
        HAL_GPIO_WritePin(port, pin, GPIO_PIN_RESET);  \
}


void rowScanningEnter()
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	configInputPullUp(ROW3_GPIO_Port,ROW3_Pin,&GPIO_InitStruct);
	configInputPullUp(ROW2_GPIO_Port,ROW2_Pin,&GPIO_InitStruct);
	configInputPullUp(ROW1_GPIO_Port,ROW1_Pin,&GPIO_InitStruct);
	configInputPullUp(ROW0_GPIO_Port,ROW0_Pin,&GPIO_InitStruct);
	
	configOutputLow(COL3_GPIO_Port,COL3_Pin,&GPIO_InitStruct);
	configOutputLow(COL2_GPIO_Port,COL2_Pin,&GPIO_InitStruct);
	configOutputLow(COL1_GPIO_Port,COL1_Pin,&GPIO_InitStruct);
	configOutputLow(COL0_GPIO_Port,COL0_Pin,&GPIO_InitStruct);
}


void colScanningEnter()
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	configOutputLow(ROW3_GPIO_Port,ROW3_Pin,&GPIO_InitStruct);
	configOutputLow(ROW2_GPIO_Port,ROW2_Pin,&GPIO_InitStruct);
	configOutputLow(ROW1_GPIO_Port,ROW1_Pin,&GPIO_InitStruct);
	configOutputLow(ROW0_GPIO_Port,ROW0_Pin,&GPIO_InitStruct);
	
	configInputPullUp(COL3_GPIO_Port,COL3_Pin,&GPIO_InitStruct);
	configInputPullUp(COL2_GPIO_Port,COL2_Pin,&GPIO_InitStruct);
	configInputPullUp(COL1_GPIO_Port,COL1_Pin,&GPIO_InitStruct);
	configInputPullUp(COL0_GPIO_Port,COL0_Pin,&GPIO_InitStruct);

}


u8 KEY_SCAN(void)
{
	u8 Key_ROW = 0,Key_COL = 0,Key_Read = 0;
	u8 key;
	rowScanningEnter();
	Key_ROW = (u8)( (((u8)DETECT_R0) << 3) |
									(((u8)DETECT_R1) << 2) |
									(((u8)DETECT_R2) << 1) |
									((u8)DETECT_R3) );
	Key_ROW&=0x0f;
	if(Key_ROW != 0x0f)
	{
		HAL_Delay(10);
		Key_ROW = (u8)( (((u8)DETECT_R0) << 3) |
										(((u8)DETECT_R1) << 2) |
										(((u8)DETECT_R2) << 1) |
										((u8)DETECT_R3) );
		Key_ROW&=0x0f;
		if(Key_ROW != 0x0f)
		{
			colScanningEnter();
			Key_COL = (u8)( (((u8)DETECT_C0) << 3) |
											(((u8)DETECT_C1) << 2) |
											(((u8)DETECT_C2) << 1) |
											((u8)DETECT_C3) );
			Key_Read = (Key_ROW << 4) | Key_COL;
			
			switch(Key_Read)
			{
				//第1行
				case 0x77: key = 1; break;
				case 0x7b: key = 2; break;
				case 0x7d: key = 3; break;
				case 0x7e: key = 4; break;
				//第2行
				case 0xb7: key = 5; break;
				case 0xbb: key = 6; break;
				case 0xbd: key = 7; break;
				case 0xbe: key = 8; break;
				//第3行 
				case 0xd7: key = 9; break;
				case 0xdb: key = 10; break;
				case 0xdd: key = 11; break;
				case 0xde: key = 12; break;
				//第4行
				case 0xe7: key = 13; break;
				case 0xeb: key = 14; break;
				case 0xed: key = 15; break;
				case 0xee: key = 16; break;
				default : break;
			}
			while(Key_COL != 0x0f) //检测到按键松开了
			{
				Key_COL = (u8)( (((u8)DETECT_C0) << 3) |
											(((u8)DETECT_C1) << 2) |
											(((u8)DETECT_C2) << 1) |
											((u8)DETECT_C3) );
			}
			return key;
		}
	}
	return 0;
}



KEY.H

#ifndef __KEY_H__
#define __KEY_H__

#include "main.h"
#include "gpio.h"


#define DETECT_R0  HAL_GPIO_ReadPin(ROW0_GPIO_Port,ROW0_Pin) 
#define DETECT_R1  HAL_GPIO_ReadPin(ROW1_GPIO_Port,ROW1_Pin) 
#define DETECT_R2  HAL_GPIO_ReadPin(ROW2_GPIO_Port,ROW2_Pin) 
#define DETECT_R3  HAL_GPIO_ReadPin(ROW3_GPIO_Port,ROW3_Pin) 

#define DETECT_C0  HAL_GPIO_ReadPin(COL0_GPIO_Port,COL0_Pin) 
#define DETECT_C1  HAL_GPIO_ReadPin(COL1_GPIO_Port,COL1_Pin) 
#define DETECT_C2  HAL_GPIO_ReadPin(COL2_GPIO_Port,COL2_Pin) 
#define DETECT_C3  HAL_GPIO_ReadPin(COL3_GPIO_Port,COL3_Pin) 


u8 KEY_SCAN(void);



#endif


在main中加这个即可。

Key_Value =	KEY_SCAN();
	if(Key_Value!=0)
		printf("%d \r\n",Key_Value);

bug调试

1.不要手碰到矩阵键盘底部,否则一通混乱
2.按键消抖部分
最开始是这样的

rowScanningEnter();
	Key_ROW = (u8)( (((u8)DETECT_R0) << 3) |
									(((u8)DETECT_R1) << 2) |
									(((u8)DETECT_R2) << 1) |
									((u8)DETECT_R3) );
	Key_ROW&=0x0f;
	if(Key_ROW != 0x0f)
	{
		HAL_Delay(10);
	问题就出在这里,延时之后再去判断没有用啊,因为
	值没有改变,还是那些,只有再次取值才以实现消抖的功能
		if(Key_ROW != 0x0f)
		{
			colScanningEnter();
			Key_COL = (u8)( (((u8)DETECT_C0) << 3) |
											(((u8)DETECT_C1) << 2) |
											(((u8)DETECT_C2) << 1) |
											((u8)DETECT_C3) );
			Key_Read = (Key_ROW << 4) | Key_COL;
			printf("aaaa:%x\r\n",Key_Read);
rowScanningEnter();
	Key_ROW = (u8)( (((u8)DETECT_R0) << 3) |
									(((u8)DETECT_R1) << 2) |
									(((u8)DETECT_R2) << 1) |
									((u8)DETECT_R3) );
	Key_ROW&=0x0f;
	if(Key_ROW != 0x0f)
	{
		HAL_Delay(10);
		Key_ROW = (u8)( (((u8)DETECT_R0) << 3) |
										(((u8)DETECT_R1) << 2) |
										(((u8)DETECT_R2) << 1) |
										((u8)DETECT_R3) );
		Key_ROW&=0x0f;
		if(Key_ROW != 0x0f)
		{
			colScanningEnter();
			Key_COL = (u8)( (((u8)DETECT_C0) << 3) |
											(((u8)DETECT_C1) << 2) |
											(((u8)DETECT_C2) << 1) |
											((u8)DETECT_C3) );
			Key_Read = (Key_ROW << 4) | Key_COL;
			printf("aaaa:%x\r\n",Key_Read);

3.跟上一篇的方法一样的问题是,都不能检测按键同时按下,比如同时按两个,你能在行读取的值中有两个0,列读取的值中,两个0,而且还不固定,这样就无法读取。

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的 STM32 矩阵键盘扫描程序示例: ```c #include "stm32f10x.h" // 矩阵键盘的行和列 #define ROW_NUM 4 #define COL_NUM 4 // 矩阵键盘的行和列对应的 GPIO 端口和引脚 #define ROW_GPIO GPIOA #define COL_GPIO GPIOB #define ROW_PIN(x) (GPIO_Pin_0 << (x)) #define COL_PIN(x) (GPIO_Pin_0 << (x)) // 矩阵键盘的按键值 const uint8_t KEY_VALUE[ROW_NUM][COL_NUM] = { {'1', '2', '3', 'A'}, {'4', '5', '6', 'B'}, {'7', '8', '9', 'C'}, {'*', '0', '#', 'D'} }; // 矩阵键盘扫描函数 void scan_key(void) { uint8_t row, col; char key_value; // 初始化矩阵键盘的行为输出,列为输入 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; for (row = 0; row < ROW_NUM; row++) { GPIO_InitStructure.GPIO_Pin = ROW_PIN(row); GPIO_Init(ROW_GPIO, &GPIO_InitStructure); } GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; for (col = 0; col < COL_NUM; col++) { GPIO_InitStructure.GPIO_Pin = COL_PIN(col); GPIO_Init(COL_GPIO, &GPIO_InitStructure); } // 扫描行 for (row = 0; row < ROW_NUM; row++) { GPIO_ResetBits(ROW_GPIO, ROW_PIN(row)); // 检测列 for (col = 0; col < COL_NUM; col++) { if (GPIO_ReadInputDataBit(COL_GPIO, COL_PIN(col)) == RESET) { key_value = KEY_VALUE[row][col]; // 处理按键值 } } GPIO_SetBits(ROW_GPIO, ROW_PIN(row)); } } int main(void) { while (1) { scan_key(); } } ``` 该程序的原理是通过依次将矩阵键盘的每一行拉低,并检测每一列的输入来确定按下的按键。在实际应用中,可以将该程序集成到其他应用程序中,以实现对矩阵键盘的输入响应。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值