b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

完美:使用基于STM32F407的4 * 4矩阵键盘(带有完整程序)

电脑杂谈  发布时间:2020-10-12 05:08:17  来源:网络整理

stm32矩阵键盘程序_stm32 矩阵键盘程序_stm32 矩阵键盘 程序

基于STM32使用4 * 4矩阵键盘作者:Lee Kelly出处:或欢迎转载,但请紧记此声明。谢谢! (上面的博客也是由我写的,只是在另一个平台上)写在前面:

这是我第一次开始写博客。我可能写得不太好。请理解。

我现在是大三。我在学习过程中遇到了各种问题。关于51单片机,STM32单片机,我最近正在学习ARM11 Tiny6410。我将来会更新一些C / C ++ / Qt。依此类推。

关于写博客,我一直想写一个博客并记录下来,但是出于某种原因(懒惰),所以我没有写它。从现在开始,我将记录未来在微控制器或编程中遇到的问题,并自己解决这些问题。我希望通过博客记录我的学习历程,并希望解决问题的过程可以帮助需要帮助的人,让我们加油! ! !

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

以下是我使用的开发板

在这里插入图片描述

stm32 矩阵键盘 程序_stm32 矩阵键盘程序_stm32矩阵键盘程序

在这里插入图片描述

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

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

2、多维数据集配置

在这里插入图片描述

  矩阵键盘从下到上依次接到STM32F407zg单片机的PD0~7引脚  ,其中,矩阵键盘下面的四个排针对应的是键盘的行(ROW)
  上面四个对应列(COL)   这里我画了一张图来说明我所使用的

键盘原理示意

stm32矩阵键盘程序_stm32 矩阵键盘 程序_stm32 矩阵键盘程序

    PD0-3依次对应3-0行  PD4-7依次对应0-3列   这张图里可以看到我画了两个箭头,下面就给大家说一下我的配置
   
    配置PD0~3为推挽输出   PD4~7为下拉输入,下图是我在STM32CubeMX 5.1.0中配置的

在这里插入图片描述

    上面的箭头,横向的表示是单片机输出给键盘的,竖向的是表示送给单片机的,也就是单片机配置的输入引脚
    用来读取PD4~7的电平

3、程序编写

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

在这里插入图片描述

在这里插入图片描述

stm32矩阵键盘程序_stm32 矩阵键盘程序_stm32 矩阵键盘 程序

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

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

    后面以此类推

注意:编写程序后,某些行可能无法扫描,并且某些键行在按下时未通过串行端口返回信息。

我的解决方案是在扫描每一行之前清除与该行相对应的图钉

在这里插入图片描述

那将没有问题

stm32 矩阵键盘程序_stm32矩阵键盘程序_stm32 矩阵键盘 程序

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、这是我的测试结果,请参见下图:

在这里插入图片描述

该程序中的编码仅对应于我自己的接线。自己书写时,应注意自己的接线

上面的一些链接是我上传的照片。我自己看时看不到图片。我不知道为什么,但是我单击链接打开图片。

2019/06/19补充完整的项目代码下载链接单击上面的蓝色字母以下载项目文件,完整的Cube配置项目和IAR项目文件。 {PS:IAR和keil相同,编写代码没有区别,不用担心不会被移植,两者都可以,如果您不理解,可以与我评论并聊天}


let‘s dream high   每个不满意的现在,都有一个不努力的曾经。加油吧


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/bofangqi/article-325499-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      每日福利
      热点图片
      拼命载入中...