datasheet

基于 STM32F407 使用 4*4 矩阵键盘

2019-08-16来源: eefocus关键字:STM32F407  4*4  矩阵键盘

写在前面:

这是我第一次开始写博客,可能写的不是很好,也请大家谅解。

本人现在大三,以前在学习过程中遇到过各种各样的问题,关于51单片机,STM32单片机,最近在学习ARM11的Tiny6410

以后还会更新一些C/C++/Qt等等方面的东西

关于写博客这件事,其实 一直想写博客记录下来,但是因为某些原因(懒),so , 没有写。现在开始,以后遇到单片机上或者编程上遇到的问题,

并且自己很好地解决了,我就会在这里记录下来。

希望通过博客记录我的学习历程并希望我所解决问题的过程能够帮到需要的人,一起加油吧!!!


我是在STM32F407开发板上使用的4*4 矩阵键盘

下面是我所使用的开发板

在这里插入图片描述

在这里插入图片描述

1、首先介绍一下4*4矩阵键盘扫描原理


 呃。。。。。就不介绍了,[矩阵键盘原理描述](http://www.51hei.com/mcu/3815.html),这个写的挺好的

2、Cube配置


在这里插入图片描述

  矩阵键盘从下到上依次接到STM32F407zg单片机的PD0~7引脚  ,其中,矩阵键盘下面的四个排针对应的是键盘的行(ROW)

  上面四个对应列(COL)   这里我画了一张图来说明我所使用的

键盘原理示意

    PD0-3依次对应3-0行  PD4-7依次对应0-3列   这张图里可以看到我画了两个箭头,下面就给大家说一下我的配置

   

    配置PD0~3为推挽输出   PD4~7为下拉输入,下图是我在STM32CubeMX 5.1.0中配置的

在这里插入图片描述

    上面的箭头,横向的表示是单片机输出给键盘的,竖向的是表示送给单片机的,也就是单片机配置的输入引脚

    用来读取PD4~7的电平


3、程序编写


 因为PD4~7为上拉输入,所以是处在一种高阻态(可以暂时理解为高电平,就是四列都为1)

 我以扫描第一行为例讲解 

在这里插入图片描述

在这里插入图片描述

    上述是软件实现部分, GPIO->IDR和0xf7相与, 若是0xe7  则二进制位1110 0111,说明PD4变为了0,所以第一列的按键

    s1按下


note:PD7对应二进制的最高位,PD0对应二进制的最低位


    后面以此类推


注意注意注意(重要的事情说三遍):在程序编写完后,可能出现有些行未扫描,有些行的按键按下没有通过串口返回信息

我的解决方法是,在每一行的扫描之前,将行所对应的引脚清空


在这里插入图片描述

这样就不会有问题了


4、贴上完整程序:


#include "keypad.h"


#include "stdint.h"

#include "stm32f4xx_hal.h"




uint16_t Key_scan(void)

{

uint16_t Key_val = 0;           // 按键扫描返回键值,初始化为0

                                // 强调一下: 这里必须付一个初值0 否则串口打印出错

uint16_t temp;

    

/*=========================以下代码是按键扫描程序=========================*/

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, GPIO_PIN_RESET); // 先清空引脚状态

/*----------------------------Scan the 1st ROW----------------------------*/

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2, GPIO_PIN_SET);   // 设置PD0~2为1

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_3, GPIO_PIN_RESET);                       // 设置PD3为0    二进制编码为 0111

    if((GPIOD->IDR & 0xF0) != 0xF0)

    {

HAL_Delay(10);   // 10ms延时消抖

if((GPIOD->IDR & 0xF0) != 0xF0)

{                                                                       

temp = (GPIOD->IDR & 0xF7);                                         // GPIOD->IDR寄存器为端口输入数据寄存器

switch(temp)                                                        // 用来读取GPIO口的电平状态

{

case 0xE7 : Key_val = 1;

break;


case 0xD7 : Key_val = 2;

break;


case 0xB7 : Key_val = 3;

break;


case 0x77 : Key_val = 4;

break;


default  : Key_val = 0; break;


}

}

    }

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, GPIO_PIN_RESET);

/*----------------------------Scan the 2nd ROW----------------------------*/

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_3, GPIO_PIN_SET);   

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);                       

    if((GPIOD->IDR & 0xF0) != 0xF0)

    {

HAL_Delay(10);   // 10ms延时消抖

if((GPIOD->IDR & 0xF0) != 0xF0)

{

temp = (GPIOD->IDR & 0xFB);

switch(temp)

{

case 0xEB : Key_val = 5;

break;


case 0xDB : Key_val = 6;

break;


case 0xBB : Key_val = 7;

break;


case 0x7B : Key_val = 8;

break;


default  : Key_val = 0; break;


}

}

    }

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, GPIO_PIN_RESET);

/*----------------------------Scan the 3rd ROW----------------------------*/

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0|GPIO_PIN_2|GPIO_PIN_3, GPIO_PIN_SET);   

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_1, GPIO_PIN_RESET);                       

    if((GPIOD->IDR & 0xF0) != 0xF0)

    {

HAL_Delay(10);   // 10ms延时消抖

if((GPIOD->IDR & 0xF0) != 0xF0)

{

temp = (GPIOD->IDR & 0xFD);

switch(temp)

{

case 0xED : Key_val = 9;

break;


case 0xDD : Key_val = 10;

break;


case 0xBD : Key_val = 11;

break;


case 0x7D : Key_val = 12;

break;


default   : Key_val = 0; break;


}

}

    }

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, GPIO_PIN_RESET);

/*----------------------------Scan the 4th ROW----------------------------*/

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, GPIO_PIN_SET);   

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0, GPIO_PIN_RESET);                       

    if((GPIOD->IDR & 0xF0) != 0xF0)

    {

HAL_Delay(10);   // 10ms延时消抖

if((GPIOD->IDR & 0xF0) != 0xF0)

{

temp = (GPIOD->IDR & 0xFE);

switch(temp)

{

case 0xEE : Key_val = 13;

break;


case 0xDE : Key_val = 14;

break;


case 0xBE : Key_val = 15;

break;


case 0X7E : Key_val = 16;

break;


default  : Key_val = 0; break;


}

}

    }

return Key_val;

}


5、 这是我的测试结果,见下图:

在这里插入图片描述

这个程序中的编码只是对应于我自己的接线,自己写的时候要注意自己的接线


关键字:STM32F407  4*4  矩阵键盘

编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic471357.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:基于STM32F407最小系统板三种矩阵键盘实现方法
下一篇:基于stm32f103的矩阵键盘

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM32F103 USART1串口重映射功能的实现

我们知道,F103的usart1串口是PA8 PA9的复用功能,我们在使用的时候直接配置这两个引脚,配置复用即可,但有时,在实际工作中,也会采用串口的重映射功能。由图可知,usart1是PB6 PB7的重定义功能,也就是重映射功能,话不多说,直接上代码。我使用的是103C8T7,请知悉。static void Gpio_Config1(void){ GPIO_InitTypeDef GPIO_InitStructure; /* TX PB6 */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7
发表于 2019-08-19
STM32F103 USART1串口重映射功能的实现

STM32F103 时钟系统明晰

本人小白一个,利用课外时间自学STM32。个人感觉,STM32的时钟系统什么的,感觉很复杂,对整个时钟系统的概念都很模糊,只知道该怎么配置,却不知道是怎么来的,所以就花了一天功夫专门上网搜集了一下资料,整理之后在此用通俗易懂的语言分享出来。如有用词不当以及总结错误的地方,还希望各位大佬指出。博主也好及时进行自我纠正,在此先谢过了。经常在配置外设时,总会有一句开启APB1或者APB2下的哪个外设的时钟,还有什么AHB时钟,SYSCLK时钟,让人很是很头疼。下面,你只需要记住这些死知识就够了:SYSCLK: 系统时钟,最大可以达到72MHZ。HCLK: AHB总线时钟,由SYSCLK分频得到,一般都是设置为不分频。经过时钟总线桥
发表于 2019-08-19

STM32F103 实验按键输入与串口实验

;   #endif} 运行结果如下:关于串口ALIENTEK精英STM32开发板所使用的STM32F103ZET6最多可提供5路串口,有分数波特率发生器,支持同步单线通信和半双工单线通讯,支持LIN,支持调制解调器操作,智能卡协议和IrDA SIR ENDEC规范,具有DMA等。 void uart_init(u32 bound)函数是串口1初始化函数 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA,ENABLE); //使用USART1,GPIOA,该口具有复用功能接下来,我们要初始化相应的GPIO端口为特定的状态,如下
发表于 2019-08-19
STM32F103 实验按键输入与串口实验

STM32F0 按键程序

#define     HAVEKEY_PIN    0x0003            //#define     KEYPOP                0x0000#define        KEY_START_PRESSED            1       
发表于 2019-08-19

基于stm32f103的矩阵键盘

我现在的任务是做一个8*8的矩阵键盘,制PCB版之前,我用电路板搭了一个3*3的矩阵键盘来模拟一下,设置PA0、PA1、PA2为PP输出,设置P3、P4、P5下拉输入。大多数的芯片内部上拉或下拉电阻都是弱上拉或弱下拉,stm32f103的内部也一样,内部上拉或下拉的电阻阻值约为40K,这样可以方便外部调整,但是,在作为一些通讯引脚时,可能会出现上电时数据不稳定的问题,如I2C通讯,解决的办法是在外部在加上一个较强的上拉或下拉即可。具体程序如下:#include <stm32f10x.h>#include "usart.h"void KeyBoard_Init(void)//按键初始化
发表于 2019-08-16

STM32矩阵键盘4*4扫描程序(无延时消抖,测试稳定)

直接上源码key.h文件#ifndef __KEY_H#define __KEY_H  #include "sys.h"   #define Read_Lie1 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_0)#define Read_Lie2 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_1)#define Read_Lie3 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2)#define Read_Lie4 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3
发表于 2019-08-19

小广播

何立民专栏

单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved