基于STM32F103C8T6的4*4矩阵键盘的行扫描法实现

概要:

        从网上找相关代码时,一些代码直接复制粘贴过来之后,可能没法使用,自己为了求效率只好继续从网上找。前一段时间终于避不开矩阵键盘了,于是自己就耐着性子写了一个适配STM32F103C8T6的4*4矩阵键盘函数库。

        我自己在编写这个4*4键盘库时力求简短,可能在细节方面上存在瑕疵,不过整体还能使用。

也许代码被压缩的体积转化为了STM32的算力消耗,但影响应该不算大?如果有大佬能指出改进的方案,这里不胜感激。

4*4矩阵键盘函数库:

1. 头文件:KeyBoard_4_4.h

#ifndef __KEYBOARD_4_4_H
#define __KEYBOARD_4_4_H
#include "stm32f10x.h"                  // Device header

//这个4*4矩阵键盘实现库具有以下特点:
//1、使用行扫描法对键盘进行扫描;
//2、部分按键同时按下不会相互冲突,具体无冲按键作者暂未分析,用户想利用此功能可以枚举尝试(推荐不使用);
//3、代码极简化。
void KeyBoard_4_4_Init(void);
u8 KeyBoard_4_4_Scan(void);

#endif

2. 源文件:KeyBoard_4_4.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"

//逐行扫描法。
//引脚定义:
//Row1~4:A0~A3
//Column1~4:A4~A7

uint16_t returnValue = 0x0000;

void KeyBoard_4_4_Init(void)
{	
	//Row
	//A0~A3引脚对应矩阵键盘第1~4行。
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	GPIO_InitTypeDef GPIO_InitStructure; 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
    //Column
	//A4~7引脚对应矩阵键盘第1~4列。
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
}

u8 KeyBoard_4_4_Scan(void)
{	
	static uint16_t temp;//中间量
	static uint8_t row,column;
	temp = 0x00F0;
	/*************Scan  Rows************************/
	for(row=0;row<4;row++)
	{
		GPIO_Write(GPIOA,(0x00FF & (~(0x0001<<row))));
		temp = GPIO_ReadInputData(GPIOA) & 0X00F0;		
		if( temp != 0x00F0)
		{
			Delay_ms(8);//消抖
			if(temp != 0xF0)//再次确认:的确有按键被按下
			{
				/*************Scan  Columns************************/
				for(column=0;column<4;column++)
				{
					if((temp & (0x0010 << column)) == 0x0000)
					{
						returnValue = 0x0000 | (0x0001 << (4 * row + column));//推荐 = 而不是 |= ,这里作者想实现多个按键同时按下的检测,但效果并不好。
						return (4 * row + column + 1);//如果想尝试个别键无冲的效果:两个操作:1、函数无返回值;2、操作上一句的注释中的不推荐的操作。
					}
				}
				break;
			}
		}
		returnValue = 0x0000;
	}
	return 0;
}

3. 说明:

        上面展示了函数库的内容,可以复制粘贴到自己工程。用户可以如此使用:

#include "stm32f10x.h"                  // Device header
#include "KeyBoard_4_4.h"


int main(void)
{
	KeyBoard_4_4_Init();

	while(1)
	{
		switch(KeyBoard_4_4_Scan())
		{
			case 1:
				break;
			case 2:
				break;
			case 3:
				break;
			case 4:
				break;
			case 5:		
				break;
			case 6:
				break;
			case 7:
				break;
			case 8:
				break;
			case 9:
				break;
			case 10:
				break;
			case 12:
				break;
			case 13:
				break;
			case 14:
				break;
			case 15:		
				break;
			case 16:		
		}
	}
}

文件提供:

已上传上述三个文件。如果该文章有帮到您,麻烦点个赞,这对我的创作热情很重要!

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
当使用STM32微控制器来实现矩阵按键扫描时,可以通过以下步骤来完成: 1. 配置GPIO引脚:首先,需要将矩阵按键的和列连接到STM32的GPIO引脚上。使用CubeMX或手动配置GPIO引脚的输入/输出模式和上拉/下拉电阻。 2. 设置扫描:将矩阵按键的设置为输出模式,并将其输出为低电平。这样可以逐扫描按键。 3. 设置列检测:将矩阵按键的列设置为输入模式,并启用上拉电阻。这样可以检测按键是否被按下。 4. 扫描按键状态:在一个循环中,逐设置为低电平,然后检测每一列的状态。如果某个按键被按下,相应的和列会形成一个连接,从而检测到按键按下。 5. 处理按键事件:根据检测到的按键状态,可以执相应的操作或触发事件。例如,可以在按键按下时发送一个信号或执特定的功能。 下面是一个简单的示例代码,用于演示STM32矩阵按键扫描: ```c #include "stm32f4xx.h" #define ROW_NUM 4 #define COL_NUM 4 GPIO_TypeDef* row_ports[ROW_NUM] = {GPIOA, GPIOA, GPIOA, GPIOA}; uint16_t row_pins[ROW_NUM] = {GPIO_PIN_0, GPIO_PIN_1, GPIO_PIN_2, GPIO_PIN_3}; GPIO_TypeDef* col_ports[COL_NUM] = {GPIOB, GPIOB, GPIOB, GPIOB}; uint16_t col_pins[COL_NUM] = {GPIO_PIN_0, GPIO_PIN_1, GPIO_PIN_2, GPIO_PIN_3}; void matrix_keypad_init() { // 配置引脚为输出模式 for (int i = 0; i < ROW_NUM; i++) { GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = row_pins[i]; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(row_ports[i], &GPIO_InitStruct); } // 配置列引脚为输入模式 for (int i = 0; i < COL_NUM; i++) { GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = col_pins[i]; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(col_ports[i], &GPIO_InitStruct); } } uint8_t matrix_keypad_scan() { uint8_t key = 0; // 逐扫描按键状态 for (int i = 0; i < ROW_NUM; i++) { // 设置当前为低电平 HAL_GPIO_WritePin(row_ports[i], row_pins[i], GPIO_PIN_RESET); // 检测每一列的状态 for (int j = 0; j < COL_NUM; j++) { if (HAL_GPIO_ReadPin(col_ports[j], col_pins[j]) == GPIO_PIN_RESET) { // 按键被按下 key = i * COL_NUM + j + 1; // 计算按键编号 break; } } // 恢复当前为高电平 HAL_GPIO_WritePin(row_ports[i], row_pins[i], GPIO_PIN_SET); if (key != 0) { break; } } return key; } int main(void) { // 初始化矩阵按键 matrix_keypad_init(); while (1) { // 扫描按键状态 uint8_t key = matrix_keypad_scan(); if (key != 0) { // 处理按键事件 // TODO: 根据按键编号执相应的操作 } } } ``` 请注意,以上代码仅为示例,具体的实现可能会根据具体的硬件和需求进调整。在实际应用中,您可能需要根据自己的需求进修改和扩展。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

见法

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值