【STM32嵌入式系统设计与开发---拓展】——1_10矩阵按键

这里写目录标题

1、矩阵按键


通过将4x4矩阵按键的每一行依次设为低电平,同时保持其它行为高电平,然后读取所有列的电平状态,可以检测到哪个按键被按下。如果某列变为低电平,说明对应行和列的按键被按下。这样逐行扫描即可确定按键的位置。


2、代码片段分析

c 复制代码
/*********************************************************************
 @Function  : 矩阵键盘行列读写操作
 @Parameter : ReadIo  :读输入的IO
							WirteIo :写输出的IO
 @Return    : 行列IO输出状态
**********************************************************************/
uint8_t GPIO_KEY_RW(uint16_t ReadIo,uint16_t WirteIo)
{
  uint16_t Wdata=0,Rdata=0;	
	/* 写操作 */
	KeyBordSetOut(KEY_ALL);               //设置IO
	if(WirteIo==0x0f00)
	   GPIO_SetBits(GPIOE,KEY_LINE);      //写行
	else 
     GPIO_ResetBits(GPIOE,KEY_LIST);    //写列		
     Wdata = GPIO_ReadOutputData(GPIOE);//读输出	
     Wdata &= WirteIo;                  //取有效区域
	
	/* 读操作 */
     KeyBordSetIn(ReadIo);              //设置IO 
     Rdata = GPIO_ReadInputData(GPIOE); //读输入
     Rdata &= ReadIo;                   //取有效区域
	
	/* 状态返回	*/
	   Rdata |= Wdata;                    //合并两次读取的数据
     return (uint8_t)(Rdata>>8);        //移位返回
}

初始化:

Wdata 和 Rdata 初始化为 0。

写操作:

检查 WirteIo 是否为 0x0f00(二进制:0000111100000000):

如果是,则设置 GPIOE 中对应 KEY_LINE 的位(具体位取决于 KEY_LINE 的定义)。

如果不是,则复位 GPIOE 中对应 KEY_LIST 的位(具体位取决于 KEY_LIST 的定义)。

读取 GPIOE 的输出数据到 Wdata。

Wdata 与 WirteIo 进行与操作,保留有效区域的数据。

读操作:

使用 ReadIo 设置IO方向。

读取 GPIOE 的输入数据到 Rdata。

Rdata 与 ReadIo 进行与操作,保留有效区域的数据。

状态返回:

将 Wdata 和 Rdata 进行或操作,合并两次读取的数据。

返回 Rdata 右移8位后的值。

假设按下第一个按键

假设按下的是第一个按键,具体的步骤如下:

初始化:

Wdata = 0

Rdata = 0

写操作:

WirteIo == 0x0f00 假设为真,则设置 GPIOE 对应 KEY_LINE 的位。

读取 GPIOE 输出数据:

假设 GPIOE 输出数据为 0000111100000000(二进制)。

Wdata &= WirteIo:

Wdata = 0000111100000000 & 0000111100000000 = 0000111100000000

读操作:

设置IO方向,具体操作取决于 KeyBordSetIn 函数。

读取 GPIOE 输入数据:

假设按下第一个按键时,GPIOE 输入数据为 0000000100000000(二进制)。

Rdata &= ReadIo:

Rdata = 0000000100000000 & ReadIo(假设 ReadIo 为 0000000100000000),结果 Rdata = 0000000100000000

状态返回:

Rdata |= Wdata:

Rdata = 0000000100000000 | 0000111100000000 = 0000111100000000

返回值:

将 Rdata 右移8位后返回:Rdata >> 8 = 00001111

所以函数返回值为 0x0F(二进制:00001111)


c 复制代码
/*********************************************************************
 @Function  : 矩阵键盘键值扫描
 @Parameter : N/A
 @Return    : 键值
**********************************************************************/
uint8_t KeyBoardScan(void)
{
	uint8_t KeyValue=0,Key=0;
	uint8_t a = 0;
	/* 检测键盘是否有按键按下,0x0f表示所有列都未按下 */
	if(GPIO_KEY_RW(KEY_LIST,KEY_LINE)!=0x0f)
	{
			/* 测试列状态 */
		  Key = GPIO_KEY_RW(KEY_LIST,KEY_LINE); // 读取列的状态

			/* 判断列状态并映射为按键值 */
			switch(Key)
			{
				case(0x1F):    // 第一列所有行都按下
						KeyValue = 1; // 对应键值为1
						break;
				case(0x2F):    // 第二列所有行都按下
						KeyValue = 2; // 对应键值为2
						break;
				case(0x4F):    // 第三列所有行都按下
						KeyValue = 3; // 对应键值为3
						break;
				case(0x8F):    // 第四列所有行都按下
						KeyValue = 4; // 对应键值为4
						break;
			}
			
			/* 测试行状态 */
			Key = GPIO_KEY_RW(KEY_LINE,KEY_LIST); // 读取行的状态
		
			/* 判断行状态并映射为按键值 */
			switch(Key)
			{
				case(0x0E):    // 第一行所有列都按下
						KeyValue = KeyValue; // 保持当前列的键值不变
						break;
				case(0x0D):    // 第二行所有列都按下
						KeyValue = KeyValue + 4; // 当前列的键值加4,对应第二行
						break;
				case(0x0B):    // 第三行所有列都按下
						KeyValue = KeyValue + 8; // 当前列的键值加8,对应第三行
						break;
				case(0x07):    // 第四行所有列都按下
						KeyValue = KeyValue + 12; // 当前列的键值加12,对应第四行
						break;
			}

			
			/* 按键松手检测 */
		  while((a < 50) && (Key != 0x00)) // 循环检测按键是否松手,最多检测50次
			{
					delay_ms(5);                          // 延时5毫秒
					Key = GPIO_KEY_RW(KEY_LINE,KEY_LIST); // 再次读取行的状态
					a += 1;                               // 计数器加1
			}
	}
	
	/* 返回键值 */
	return KeyValue;
}
相关推荐
IDIOT___IDIOT1 小时前
为什么要给单片机植入操作系统
单片机·嵌入式硬件
逼子格4 小时前
十三种物联网/通信模块综合对比——《数据手册--物联网/通信模块》
嵌入式硬件·物联网·音视频·硬件工程师·硬件测试·硬件笔试真题·通信模块
Wythzhfrey5 小时前
51单片机Day03---让一个LED灯闪烁
c语言·单片机·嵌入式硬件·c#·51单片机
双叶8366 小时前
(51单片机)串口通讯(串口通讯教程)(串口接收发送教程)
c语言·开发语言·c++·单片机·嵌入式硬件·microsoft·51单片机
琢磨先生David7 小时前
探索 OpenHarmony 开源硬件的学习路径:从入门到实战的全攻略
嵌入式硬件·开源·鸿蒙
美好的事情总会发生7 小时前
电容详解:定义、作用、分类与使用要点
嵌入式硬件·硬件工程·智能硬件
FreakStudio16 小时前
【电子DIY神器】通吃各种5线步进电机!I2C接口控制28BYJ-48五线四相步进电机
stm32·单片机·mcu·嵌入式·arm·技术栈·电子diy
学渣6765619 小时前
【GPIO8个函数解释】
stm32·单片机·嵌入式硬件
weixin_4465042219 小时前
通信协议详解(十):PSI5 —— 汽车安全传感器的“抗干扰狙击手”
嵌入式硬件·fpga
mcupro20 小时前
TQTT_KU5P开发板教程---文件的烧写与程序固化
嵌入式硬件·fpga开发