【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;
}
相关推荐
qq_4597300333 分钟前
4-3 MCU中ARM存储器的作用
arm开发·单片机·嵌入式硬件
嵌入式科普3 小时前
嵌入式科普(24)从SPI和CAN通信重新理解“全双工”
c语言·stm32·can·spi·全双工·ra6m5
重生之我是数学王子4 小时前
点亮核心板小灯 STM32U575
stm32·单片机·嵌入式硬件
end_SJ4 小时前
初学stm32 --- 定时器中断
stm32·单片机·嵌入式硬件
南城花随雪。4 小时前
单片机:实现数码管动态显示(0~99999999)74hc138驱动(附带源码)
单片机·嵌入式硬件
南城花随雪。6 小时前
单片机:实现信号发生器(附带源码)
单片机·嵌入式硬件
灵槐梦8 小时前
【速成51单片机】2.点亮LED
c语言·开发语言·经验分享·笔记·单片机·51单片机
三月七(爱看动漫的程序员)8 小时前
HiQA: A Hierarchical Contextual Augmentation RAG for Multi-Documents QA---附录
人工智能·单片机·嵌入式硬件·物联网·机器学习·语言模型·自然语言处理
新晨单片机设计9 小时前
【087】基于51单片机智能宠物喂食器【Proteus仿真+Keil程序+报告+原理图】
嵌入式硬件·51单片机·proteus·宠物·ad原理图
大风起兮1210 小时前
STM32HAL库中RTC闹钟设置时分秒,年月日
stm32·嵌入式硬件