• 方案介绍
  • 相关推荐
申请入驻 产业图谱

第8章?Stm32CubeMX+Proteus仿真入门?--矩阵按键扫描

04/10 13:38
131
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

 

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 */

实验现象:

按下矩阵按键显示对应的数字或者字母

相关推荐