精华内容
下载资源
问答
  • 4*4矩阵键盘

    2013-08-17 09:59:36
    4*4矩阵键盘程序。c代码。
  • stm32 4*4矩阵键盘程序

    2017-03-25 10:57:51
    stm32 4*4矩阵键盘程序
  • 4*4矩阵键盘原理图及资料
  • fpga的4*4矩阵键盘代码

    2018-11-27 15:30:05
    fpga的4*4矩阵键盘Verilog代码,可编译下载直接使用。
  • 4*4矩阵键盘扫描

    2014-01-03 23:15:33
    单片机4*4矩阵键盘扫描代码,实现按键读取功能
  • 4*4矩阵键盘学习

    千次阅读 2021-04-01 19:35:43
    提示:这里主要围绕4*4矩阵键盘,其他结构键盘的原理可通用。 一、为什么用矩阵键盘 我们在做独立键盘实验的时候,独立键盘与单片机连接时,每一个按键都需要一个独立的I/O口。 如果某单片机系统需要较多按键,使用...

    提示:这里主要围绕4*4矩阵键盘,其他结构键盘的原理可通用。


    一、为什么用矩阵键盘

    我们在做独立键盘实验的时候,独立键盘与单片机连接时,每一个按键都需要一个独立的I/O口。
    如果某单片机系统需要较多按键,使用独立按键便会占用较多的I/O口资源。
    单片机系统中I/O口资源往往比较宝贵,当用到多个按键时,为了节省I/O口,我们选择矩阵键盘。
    在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。这样,一个端口(如P1口)就可以构成4*4=16个按键,比之直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显,比如再多加一条线就可以构成20键的键盘,而直接用端口线则只能多出一键(9键)。

    二、矩阵键盘的工作原理

    在这里插入图片描述
    如上图,由IO接口线组成行和列结构,键位设置在行和列的交叉点上。8个IO口实现了16个按键。

    当按键没有按下时,行线与列线之间开路,所有的输入端都是高电平,代表无键按下。行线输出是低电平,一旦有键按下,两条I/O口线之间短路,则输入线就会被拉低,这样,通过读入输入线的状态就可得知是否有键按下了。

    三、如何判断按键按下

    1.逐行扫描

    我们可以通过高四位轮流输出低电平来对矩阵键盘进行逐行扫描,当低四位接收到的数据不全为1的时候,说明有按键按下,然后通过接收到的数据是哪一位为0来判断是哪一个按键被按下。

    2.行列扫描

    我们可以通过高四位全部输出为低电平,低四位输出为高电平。当接收到的数据低四位不全为高电平时,说明有按键按下,然后通过接收的数据值,判断是哪一列有按键按下;然后再反过来,高四位输出为高电平,低四位输出低电平,然后根据接收到的高四位的值判断是哪一行有按键按下,这样就能确定是哪个按键被按下了。

    四、按键的消抖

    按键在按下或释放时,由于机械弹性作用的影响,通常伴随有一定时间的触点机械抖动。抖动时长与开关的机械特性有关,一般为5~10ms。为了保证键每闭合一次CPU仅作一次处理,必须去除键释放时的抖动。

    消除抖动的常见方法:硬件去抖和软件去抖。
    在按键数较少时,可采用硬件去抖;而当按键数较多时,采用软件去抖。

    硬件去抖:并联电容或双稳态消抖电路;
    软件去抖:延时约10ms后再次判断。

    五、参考程序
    代码如下(示例):

    	if( tmp != 0XF0 )//如果有按键按下
    	{   
    		//防止长按时,持续自增导致变量溢出
    		if( key_count < 2 )
    		{
    			key_count++;
    		}
    	}
    	//若产生按键抖动被抬起则计数清0 
    	else
    	{
    		key_count = 0;
    	}
    	
    	//若连续2次扫描均处于按下状态 则认定按键确实被按下
    	if( key_count == 2 )
    	{          
    		column = tmp & 0XF0;//获取列号
    
    		/*------------- GPIOE 高8位端口配置 -------------*/
    		PB -> OUTEN |= 0XFF00;//PB输出使能
    		
    		//翻转: GPIOE 高8位端口 低4位为高, 高4位为低
    		PB -> OUT &= 0X00FF;
    		PB -> OUT |= 0X0F00;
    		
    		//GPIOE 高8位端口 低4位为 上拉输入
    		PB -> OUTEN &= 0XF0FF;//PB输入使能
    		GPIO_PUPD_SEL(PUPD_PU, PB, 8 );
    		GPIO_PUPD_SEL(PUPD_PU, PB, 9 );
    		GPIO_PUPD_SEL(PUPD_PU, PB, 10 );
    		GPIO_PUPD_SEL(PUPD_PU, PB, 11 );
    										
    		row = ( PORTE >> 8 ) & 0X0F;//获取行号 		
    

    之后会对矩阵键盘的应用做出详细介绍。

    展开全文
  • 4*4矩阵键盘+四位共阳数码管PCB图,包括矩阵键盘的PCB图和四位共阳数码管驱动电路的原理图,是51单片机学习的小模块
  • 51单片机控制4*4矩阵键盘反转扫描keil工程文件C源文件,采用反转扫描方式读取4*4矩阵键盘,按下按键后数码管显示相应数码管编码
  • 430程序,4*4矩阵键盘

    2014-03-15 11:22:40
    430程序,4*4矩阵键盘
  • 4*4矩阵键盘C

    2011-10-30 13:57:24
    自己写的4*4矩阵键盘的C代码,有防抖动
  • 51单片机控制4*4矩阵键盘行列扫描keil工程文件C源文件,4*4矩阵按键,带数码管显示,按下按键后在数码管显示按键编号
  • 4*4矩阵键盘与1602液晶显示 4*4矩阵键盘与1602液晶显示 4*4矩阵键盘与1602液晶显示
  • STM32F407ZG实现4*4矩阵键盘
  • 用verilog写的 4*4矩阵键盘键盘,作为自定义外设可直接在sopc builder中加入
  • 4*4矩阵键盘 AD工程源文件 原理图+PCB 单面布线 可供参考
  • 4*4矩阵键盘扫描函数

    2012-09-04 16:33:20
    51单片机4*4矩阵键盘扫描函数,需要放进C51主函数中运行。
  • 4*4矩阵键盘,在linux下的驱动程序
  • 个人作品,FPGA矩阵键盘。FPGA4*4矩阵键盘电路设计
  • 4*4矩阵键盘电路设计

    2010-12-11 15:46:57
    4*4矩阵键盘电路设计c51单片机c程序设计
  • 基于 STM32F407 使用 4*4 矩阵键盘(附完整程序)

    万次阅读 多人点赞 2019-03-03 08:56:16
    STM32F407使用4*4矩阵键盘

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


    作者:李剀
    出处:https://www.cnblogs.com/kevin-nancy/ 或者 https://blog.csdn.net/Kevin_8_Lee/article/details/88084516
    欢迎转载,但也请保留上面这段声明。谢谢!(上面这个也是我写的博客,只是在另一个平台)
    写在前面:

      这是我第一次开始写博客,可能写的不是很好,也请大家谅解。
      我现在是在上大三,以前在学习过程中遇到过各种各样的问题,关于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、 这是我的测试结果,见下图:

    在这里插入图片描述

    这个程序中的编码只是对应于我自己的接线,自己写的时候要注意自己的接线
    上面有些连接是我上传的图片,我自己看的时候看不到图片,不知道什么原因,但是点击链接打开就是图片了


    2019/06/19补充

    完整工程代码下载连接

    点击上方蓝字下载工程文件,完整的Cube配置工程以及IAR工程文件。
    {PS: IAR跟keil都是一样的,写代码来说没什么区别,不用担心不可以移植,都是可以的,如果不懂的可以评论私聊我}

    
    let‘s dream high   每个不满意的现在,都有一个不努力的曾经。加油吧
    
    
    展开全文
  • 4*4矩阵键盘的FPGA驱动

    千次阅读 2020-01-15 17:07:02
    4*4矩阵键盘的FPGA驱动 一、硬件原理 4*4矩阵键盘有4行与4列,在按键按下时一行与一列即导通。其驱动方法非常简单。本设计中以一定的时间频率分别将每一行的引脚电平拉高,并在拉高某个引脚的同时检测每一列的电平...

    4*4矩阵键盘的FPGA驱动

    一、硬件原理

    在这里插入图片描述
    4*4矩阵键盘有4行与4列,在按键按下时一行与一列即导通。其驱动方法非常简单。本设计中以一定的时间频率分别将每一行的引脚电平拉高,并在拉高某个引脚的同时检测每一列的电平变化,当检测到某列引脚有上升沿跳变时,即为该行与该列导通对应的那个按键被按下。
    例如上图中,拉高PD4,此时检测到PD2引脚有上升沿电平跳变,则按键S5被按下。其余同理。

    二、Verilog代码实现

    //
    // Company: NanJing University of Information Science & Technology
    // Engineer: Yang Cheng Yu
    // 
    // Create Date: 2020/01/13 20:01:50
    // Design Name: keyboard_4_4
    // Module Name: keyboard_4_4
    // Project Name: Clock
    // Target Devices: 
    // Tool Versions: 
    // Description: 
    // 
    // Dependencies: 
    // 
    // Revision:
    // Revision 0.01 - File Created
    // Additional Comments:
    // 
    //
    module keyboard_4_4(
    	input 					clk,//时钟
    	input 					rst,//复位
    	output reg[3:0] 		c_pin,//行引脚
    	input[3:0] 				r_pin,//列引脚
    	output reg[3:0]			key_out//按键编号输出
    );
    	reg[15:0] 				div_cnt;//分频计数器
    	reg[2:0]				state;
    	reg						cnt_full;//分频计数器计满逻辑
    	localparam				CHECK_R1=3'b000;//检测R1
    	localparam				CHECK_R2=3'b001;//检测R2
    	localparam				CHECK_R3=3'b011;//检测R3
    	localparam				CHECK_R4=3'b010;//检测R4
    	//分频计数器逻辑
    	always@(posedge clk or negedge rst)begin//此处设计每次拉高一行时间为1ms
    		if(!rst)begin
    			div_cnt <= 16'd0;
    			cnt_full <= 1'b0;
    		end
    		else
    			if(div_cnt==16'd49999)begin
    				div_cnt <= 16'd0;
    				cnt_full <= 1'b1;
    			end
    			else begin
    				div_cnt <= div_cnt + 1'b1;
    				cnt_full <= 1'b0;
    			end
    	end
    
    	//状态组合判断
    	always@(posedge cnt_full or negedge rst)begin
    		if(!rst)
    			state <= CHECK_R1;
    		else
    			case(state)
    				CHECK_R1:
    					if(cnt_full)
    						state <= CHECK_R2;
    					else
    						state <= CHECK_R1;
    				CHECK_R2:
    					if(cnt_full)
    						state <= CHECK_R3;
    					else
    						state <= CHECK_R2;
    				CHECK_R3:
    					if(cnt_full)
    						state <= CHECK_R4;
    					else
    						state <= CHECK_R3;
    				CHECK_R4:
    					if(cnt_full)
    						state <= CHECK_R1;
    					else
    						state <= CHECK_R4;
    				default:
    					state <= state;
    			endcase
    	end
    	//状态机输出逻辑
    	always@(posedge clk or negedge rst)begin
    		if(!rst)
    			c_pin <= 4'b0000;
    		else
    			case(state)
    				CHECK_R1:begin
    					c_pin <= 4'b1000;
    					case(r_pin)
    						4'b1000:key_out <= 4'd0;
    						4'b0100:key_out <= 4'd1;
    						4'b0010:key_out <= 4'd2;
    						4'b0001:key_out <= 4'd3;
    					endcase
    				end
    				CHECK_R2:begin
    					c_pin <= 4'b0100;
    					case(r_pin)
    						4'b1000:key_out <= 4'd4;
    						4'b0100:key_out <= 4'd5;
    						4'b0010:key_out <= 4'd6;
    						4'b0001:key_out <= 4'd7;
    					endcase
    				end
    				CHECK_R3:begin
    					c_pin <= 4'b0010;
    					case(r_pin)
    						4'b1000:key_out <= 4'd8;
    						4'b0100:key_out <= 4'd9;
    						4'b0010:key_out <= 4'd10;
    						4'b0001:key_out <= 4'd11;
    					endcase
    				end
    				CHECK_R4:begin
    					c_pin <= 4'b0001;
    					case(r_pin)
    						4'b1000:key_out <= 4'd12;
    						4'b0100:key_out <= 4'd13;
    						4'b0010:key_out <= 4'd14;
    						4'b0001:key_out <= 4'd15;
    					endcase
    				end	
    				default:begin
    					c_pin <= 4'b0000;
    					key_out <= 4'd0;
    				end
    			endcase
    	end
    endmodule
    
    

    状态转移图
    在这里插入图片描述

    展开全文
  • 51单片机设计矩阵键盘密码锁keil工程文件C源文件,密码固化到ROM,采用4*4矩阵键盘,按下按键后数码管显示相应的案件,然后与设定的密码进行对比,密码正确数码管显示OPEN,错误显示ERR
  • 单片机的4*4矩阵键盘

    2010-06-27 11:41:52
    基于单片机的4*4矩阵键盘,源程序,keil的C语言程序

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 733
精华内容 293
关键字:

4*4矩阵键盘