Stm32CubeMX+Proteus仿真入门
第 八 章
本章节资料下载链接:
我用夸克网盘分享了「第8章 矩阵按键扫描」,点击链接即可保存。打开「夸克APP」,无需下载在线播放视频,畅享原画5倍速,支持电视投屏。
链接:https://pan.quark.cn/s/9c45185b7d5f
**1、**矩阵按键
1.1 矩阵按键介绍
本篇讲解4*4矩阵按键的应用,矩阵按键的好处是相对于独立按键可以节省引脚。在需要多个按键的系统中方便应用。矩阵键盘也少不了按键消抖的环节,本章实验中采用的是行列扫描法来检测哪个按键按下。
1.2 硬件设计
4*4 矩阵按键引出的8根控制线直接连接到stm32单片机的PB8-PB15口上。电路中的PB08连接矩阵键盘的第1行,PB12连接矩阵键盘第1列。使用数码管显示按下按键的值,数码管部分同第10章。
PB8PB11连接4行,PB12PB15连接四列,每行每列都有一个按键连接,当某个按键被按下,它所对应的行和列就会被接通。比如说,我们将四列设置成上拉输入状态,四行设置成推挽输出,这个时候读PB12BB15的引脚状态应该全是高电平,然后我们按下了F按键,此时我们把每一列对应的引脚挨个输出低电平,再读PB12PB15的引脚状态,就会发现PB15的引脚变为低电平了(因为F按键是连接PB15引脚),就可以定位到是哪一行的按键被按下。之后再根据是在哪一列扫描时发生变化的,就可以定位出按键所在列。
1.3 代码工程配置
复制5章工程,在数码管基础上增加矩阵按键。
stm32cubemx配置
PB8PB11设置为推挽输出,PB12PB15设置为上拉输入。
推挽输出:
上拉输入:
配置完成点生成代码
新增矩阵按键部分代码到key.c和key.h。增加到工程文件操作如4章
#include "key.h"#include "system.h"#include "main.h"/******************************************************************************* *函数名:KEY_L_SCAN *功 能:按键列扫描 *返回值:1~4,对应1~4列按键位置 如果为1,代表没有按键被按下,如果为0,代表有按键被按下*******************************************************************************/u8 KEY_L_SCAN(void){ //读出列扫描状态 u8 key_line[1]={0xff}; //定义一个数组,存放列扫描状态 key_line[0] = HAL_GPIO_ReadPin(GPIOB,L1_Pin)<<3; key_line[0] = key_line[0] | (HAL_GPIO_ReadPin(GPIOB,L2_Pin)<<2); key_line[0] = key_line[0] | (HAL_GPIO_ReadPin(GPIOB,L3_Pin)<<1); key_line[0] = key_line[0] | (HAL_GPIO_ReadPin(GPIOB,L4_Pin)); if(key_line[0] != 0x0f) //不是1111,代表肯定有一个0列 { HAL_Delay(1); //消抖 if(key_line[0] != 0x0f) //0111 1011 1101 1110 { //printf("key_line_DATA = 0x%xrn",key_line[0]); switch(key_line[0]) { case 0x07: //0111 判断为该列第1列的按键按下 return 1; case 0x0b: //1011 判断为该列第2列的按键按下 return 2; case 0x0d: //1101 判断为该列第3列的按键按下 return 3; case 0x0e: //1110 判断为该列第4列的按键按下 return 4; default : return 0; } } else return 0; } else return 0;} /*** *函数名:KEY_SCAN *功 能:4*4按键扫描 *返回值:0~16,对应16个按键 */u8 KEY_SCAN(void){ char Key_Num=0; //1-16对应的按键数 char key_row_num=0; //列扫描结果记录ROW ROL KEY_H1_OUT_LOW; //行 if( (key_row_num=KEY_L_SCAN()) != 0 ) { while(KEY_L_SCAN() != 0); //消抖 Key_Num = 0 + key_row_num; } KEY_H1_OUT_HIGH; KEY_H2_OUT_LOW; if( (key_row_num=KEY_L_SCAN()) != 0 ) { while(KEY_L_SCAN() != 0); Key_Num = 4 + key_row_num; } KEY_H2_OUT_HIGH; KEY_H3_OUT_LOW; if( (key_row_num=KEY_L_SCAN()) != 0 ) { while(KEY_L_SCAN() != 0); Key_Num = 8 + key_row_num; } KEY_H3_OUT_HIGH; KEY_H4_OUT_LOW; if( (key_row_num=KEY_L_SCAN()) != 0 ) { while(KEY_L_SCAN() != 0); Key_Num = 12 + key_row_num; } KEY_H4_OUT_HIGH; return Key_Num;}
新增代码到key.h
#ifndef _key_H#define _key_H #include "system.h" //使用位操作定义#define KEY1 PAin(15)#define KEY2 PAin(14)#define KEY3 PAin(13)#define KEY4 PAin(12) #define LED1 PAout(0) #define LED2 PAout(1) //定义各个按键值 #define KEY1_PRESS 1#define KEY2_PRESS 2#define KEY3_PRESS 3#define KEY4_PRESS 4 #define KEY_H1_OUT_LOW HAL_GPIO_WritePin(GPIOB,H1_Pin,GPIO_PIN_RESET)#define KEY_H2_OUT_LOW HAL_GPIO_WritePin(GPIOB,H2_Pin,GPIO_PIN_RESET)#define KEY_H3_OUT_LOW HAL_GPIO_WritePin(GPIOB,H3_Pin,GPIO_PIN_RESET)#define KEY_H4_OUT_LOW HAL_GPIO_WritePin(GPIOB,H4_Pin,GPIO_PIN_RESET) #define KEY_H1_OUT_HIGH HAL_GPIO_WritePin(GPIOB,H1_Pin,GPIO_PIN_SET)#define KEY_H2_OUT_HIGH HAL_GPIO_WritePin(GPIOB,H2_Pin,GPIO_PIN_SET)#define KEY_H3_OUT_HIGH HAL_GPIO_WritePin(GPIOB,H3_Pin,GPIO_PIN_SET)#define KEY_H4_OUT_HIGH HAL_GPIO_WritePin(GPIOB,H4_Pin,GPIO_PIN_SET) u8 KEY_Scan(u8 mode); u8 KEY_SCAN(void);u8 KEY_ROW_SCAN(void);#endif
main函数处理
增加变量声明:
/* USER CODE BEGIN 1 */ u8 smgbuf[8]; int num = 87654321; u8 qwan,bwan,swan,wan,qian,bai,shi,ge=0; /* USER CODE END 1 */
增加代码:
/* USER CODE BEGIN WHILE */ qwan=num/10000000%10; bwan=num%10000000/1000000; swan=num%1000000/100000; wan=num%100000/10000; qian=num%10000/1000; bai=num%1000/100; shi=num%100/10; /*num先求余得到十位个位 再求整得到十位 数码管显示十位*/ ge=num%10; /*num求余 数码管显示个位*/ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ num=KEY_SCAN()-1; if(num>=0){ qwan=num; bwan=num; swan=num; wan=num; qian=num; bai=num; shi=num; /*num先求余得到十位个位 再求整得到十位 数码管显示十位*/ ge=num; /*num求余 数码管显示个位*/ // memset(smgbuf, 0, sizeof(smgbuf)); } smgbuf[0]=gsmg_code[qwan]; smgbuf[1]=gsmg_code[bwan]; smgbuf[2]=gsmg_code[swan]; smgbuf[3]=gsmg_code[wan]; smgbuf[4]=gsmg_code[qian]; smgbuf[5]=gsmg_code[bai]; smgbuf[6]=gsmg_code[shi]; smgbuf[7]=gsmg_code[ge]; SMG_Display(smgbuf,1); } /* USER CODE END 3 */
实验现象:
按下矩阵按键显示对应的数字或者字母
131