精华内容
下载资源
问答
  • stm32矩阵键盘扫描

    2015-08-09 10:24:21
    stm32矩阵键盘扫描程序,亲测可用,GPIOA口,原理与51单片机类似
  • stm32矩阵键盘按键扫描程序亲测可用,PA0~PA7为矩阵键盘接口,PA9PA10为串口
  • STM32 矩阵键盘扫描实验

    热门讨论 2011-05-15 09:45:27
    STM32 矩阵键盘扫描实验,完整程序,高度的可移植性,可以接到任意IO口。 4*4 与4*3 扫描读按键程序
  • stm32矩阵键盘程序

    2016-07-25 13:43:46
    最简单的矩阵键盘程序代码,扫描只有九行代码,通俗易懂,方便移植,
  • STM32矩阵键盘扫描及处理

    千次阅读 多人点赞 2020-10-04 11:04:48
    STM32矩阵键盘扫描及处理 前言 由于最近帮做一个毕业设计需要用到直接输入目标值去控制输出,所以才写这么一个按键处理的程序。对于一个才接触单片机没多久的大学生菜鸟来说,实现毕设里的每一项功能都有一定的...

    STM32的矩阵键盘扫描及处理

    前言

    由于最近帮做一个毕业设计需要用到直接输入目标值去控制输出,所以才写这么一个按键处理的程序。对于一个才接触单片机没多久的大学生菜鸟来说,实现毕设里的每一项功能都有一定的挑战。接下来就分享一下我在写这按键扫描及处理中的一些经验吧。
    整个工程所需要的输出值可通过键盘任意控制,有一位小数。

    一、按键扫描

    1.矩阵按键的原理图

    矩阵键盘原理图示意图,具体键值根据自己需求设置

    这里只是键盘示意图,具体键值需根据自己需求设置

    2、按键扫描代码

    总体思路:先设置两个初始化函数,KeyPad_Init1()是高四位初始化为下拉输入、低四位为上拉输入(相当于就是给高四位低电平,低四位为高电平);KeyPad_Init2()是高四位初始化为上拉输入、低四位为下拉输入(相当于就是给高四位高电平,低四位为高电平)。程序首先使用KeyPad_Init1(),如果读取低8位引脚不是0x0f,就说明有按键被按下,然后短暂延时消抖后再次检测到低8位引脚不是0x0f,就储存高四位的的值然后进行初始化KeyPad_Init2(),然后又读取低8位引脚不是0x0f,储存其中的低四位的值,然后将高低四位值加起来就对应了一个键值。
    在这段扫描程序里面,由于扫描出的键值后面还需要处理,所以只有当有键按下后才返回才是有效的键值,没有按键按下就返回的是个无效值-1,目的是为了对每一次按键按下值进行处理,没有按下就不去处理。

    //函数名:扫描函数
    //返回值:有效键值或-1
    //功能:矩阵按键扫描,返回一个值
    short KeyPad_Scan(void)
    {
    	short num = -1; //保持按键值返回
    	
    	u16 readvalue = 0;
    	u16 re=0;
    	u16 re1=0;
    	u16 re2=0;
    	KeyPad_Init1();					//低4位引脚上拉输入,高4位引脚下拉输入
    	readvalue = GPIO_ReadInputData(GPIOA);	//读GPIOA引脚电平
    	readvalue &= 0x00ff;				//保留低8位的值(PA7-PA0)
    	if(readvalue != 0x000f) 				//高4位引脚有一个被按下
    	{
    		delay_ms(10);//消抖10ms
    		readvalue = GPIO_ReadInputData(GPIOA);	//读GPIOA引脚电平
    		if(readvalue != 0x000f)
    		{
    			re1 = GPIO_ReadInputData(GPIOA);	//再次读取状态
    			re1 &= 0x00f0;  				//保留PA4-PA7的值
    
    			KeyPad_Init2();  				//低4位引脚下拉输入,高4位引脚上拉输入
    			delay_ms(50);//经我测试,这里延迟50ms反应最快而很少出现不反应的状况
    			re2 = GPIO_ReadInputData(GPIOA);	//再次读取状态
    			re2 &= 0x000f;				//保留PA0-PA3的值
    			
    			re=re1|re2;					//相与,就知道哪一行哪一列被按下啦
    			
    			switch(re)
    			{
    			case 0x0011: num = 12;break;  
    			case 0x0012: num = 8;break;  
    			case 0x0014: num = 4;break; 
    			case 0x0018: num = 0;break;  
    			case 0x0021: num = 13;break;  
    			case 0x0022: num = 9;break; 
    			case 0x0024: num = 5;break;  
    			case 0x0028: num = 1;break;  
    			case 0x0041: num = 14;break;  
    			case 0x0042: num = 10;break;  
    			case 0x0044: num = 6;break;  
    			case 0x0048: num = 2;break;  
    			case 0x0081: num = 15;break;  
    			case 0x0082: num = 11;break;  
    			case 0x0084: num = 7;break;  
    			case 0x0088: num = 3;break;  
    			}
    			return num;
    		}
    	}
    	return -1;
    }
    
    

    二、键值处理

    1、键值处理代码

    在这段程序中我要的是按下【确定】键按下后返回确定键按下前所输入的键值(0-99.9),返回更高的值也行,不过小数点后面只能有一位数。

    /****************
    //按键值处理函数,返回最后需要的目标值,
    返回-1,按键没有按下
    返回-2或0,有按键按下,无效可适当延时
    返回其他,键值处理后的值
    *******************/
    float Key_value_processing(void)		
    {
    	
    	float key=0.0;	
    	int key_flag = -1;
    	static int key2 = 0;		//按键扫描返回值暂存处		
    	static u8		key1 = 0;
    
    	static int		Point_flag=0;		//判断‘.’是否按下标志,(Point_flag=2表示按下,Point_flag=1表示按下后进行了一次小数后一位赋值)
    	static int		key1_temp = 0;				//缓存key1值
    	
    
    				key_flag=KEYPAD_Scan();		//
    		 
    		 if(-1 == key_flag)			//如果按键没有按下
    			{
    			 return -1;
    			}
    		 else if(0 <= key_flag && key_flag <= 9)		//返回数字键,根据小数点是否按下,对数字进行
    			{
    					key1 = key_flag+key1*10;	//如有多位值,进行累加
    					key1_temp = key1;		
    				if(2 == Point_flag)
    				{
    					printf("xiaoshudianhou:%d \r\n",key1);
    					OLED_ShowNum(103,16,key1,1,16);
    					OLED_Refresh();
    					Point_flag	=	1;
    				}
    				else if(1 == Point_flag)		//点按下
    				{
    					key1=key_flag;
    				}
    				else
    				{
    					printf("shuqian:%d \r\n",key1);
    					OLED_ShowNum(63,16,key1,2,16);
    					OLED_Refresh();
    				}
    				return -2;
    			}
    			/***无效按键**/	
    			else if(10 <= key_flag && key_flag <= 13)		//暂时没有用的值,不处理
    			{
    				printf("无效值::%d \r\n",key_flag);
    				return -2;
    			}
    		 else if(Point == key_flag)		//
    			{
    			 key2 = key1_temp;
    			 Point_flag=2;
    			 key1=0;
    			 printf("float-----\r\n");
    			 OLED_ShowString(83,16,":",16); 
    				OLED_Refresh();
    				return -2;
    			}
    		 else if(Sure == key_flag)		//确定键按下后,返回处理好的值
    			{
    				if(1==Point_flag)
    				{
    					key = key2 + (float)key1/10.0;
    					Point_flag=0;
    				}
    			 else 
    			 {
    				 key=key1;
    			 }
    			 printf(":%f \r\n",key);
    			 key_flag = -1,key1 = 0,key2 = 0;
    			 return key;
    			}	
    			return -1;
    }	
    
    

    三、总结

    学习这个专业来第一次对自己所学的知识进行总结,虽然是一个做完后看起来很简单的一个知识点,在键值处理的过程中还是遇到了很多的问题。多亏了学长的帮忙才算比较轻松的完成了。这其中发现了自己以前很多的盲点,比如对于数据类型把握得不是很清楚,还有就是if else语句与if if语句的使用,在这之前写有关单片机的代码都是只用if语句,没考虑到当有多个条件时可以用if else语句可以有更快地执行效率。

    展开全文
  • STM32】4*4矩阵键盘扫描程序(扫描方式)

    千次阅读 热门讨论 2020-06-16 13:35:48
    能力有限,参照之前学的51单片机例程写了份简单粗暴型的按键扫描程序,如需在大项目中使用还是得用中断来处理比较好~ 矩阵键盘实物和原理图 图中厂家给的图应该标错了序号,从左到右是S1-S4、S5-S8、S9-S12、S13-...

    由于买的最小系统开发板只有一个按键感觉不大方便调试和搞其他东东,所以又在某宝买了一个4*4矩阵键盘拓展一下按键哈。能力有限,参照之前学的51单片机例程写了份简单粗暴型的按键扫描程序,如需在大项目中使用还是得用中断来处理比较好~
    点击下载源码

    矩阵键盘实物和原理图


    图中厂家给的图应该标错了序号,从左到右是S1-S4、S5-S8、S9-S12、S13-S16为一行,小伙伴们自行理会啦。

    总体思路:先向矩阵的4行输出低电平,然后检测4列的输入,若为’0’的那列即该列有按键按下;接着向列输出高电平,检测行输入,若为’1’的那行即为按键在该列的位置,从而确定按键所在的某列某行了。(先检测行再检测列也是可以的)

    void KEY1_Init(void)
    {
       GPIO_InitTypeDef GPIO_InitStructure;
       RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);//使能GPIOA、B
       GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//上拉输入  
       GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_10|GPIO_Pin_11;  
       GPIO_Init(GPIOB,&GPIO_InitStructure); 
       GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;        //推挽输出
       GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;      
       GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
       GPIO_Init(GPIOA,&GPIO_InitStructure);       
       GPIO_ResetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7); //行输出低电平,扫描列
    }
    void KEY2_Init(void)
    {
       GPIO_InitTypeDef GPIO_InitStructure;
       RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);
    
    	
       GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;        //推挽输出
       GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
       GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_10;
       GPIO_Init(GPIOB,&GPIO_InitStructure);
       GPIO_SetBits(GPIOB,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_10|GPIO_Pin_11);  //扫描行
       GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;   //下拉输入
       GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
       GPIO_Init(GPIOA,&GPIO_InitStructure);	 
    }
    u8 KeyScan(void)
    {
    	u8 column=0,KeyValue=0;
        KEY1_Init();    //行输入低电平,扫描列
    	while(1)
    	{
    		if(PBin(0)==0)
    		{
    			delay_ms(50);
    			if(PBin(0)==0)
    			{
    				column=1;        //第一列
    			}
    		}
    		if(PBin(1)==0)
    		{
    			delay_ms(50);
    			if(PBin(1)==0)
    			{
    				column=2;        //第二列
    			}
    		}
    		if(PBin(10)==0)
    		{
    			delay_ms(50);
    			if(PBin(10)==0)
    			{
    				column=3;        //第三列
    			}
    		}
    		if(PBin(11)==0)
    		{
    			delay_ms(50);
    			if(PBin(11)==0)
    			{
    				column=4;        //第四列
    			}
    		}		
    		if(column==1)  
    		{
    				KEY2_Init();     //列输出高电平,扫描行		           
    					if(PAin(7)==1) //第一列第一行
    					{
    						KeyValue=1;
    						break;   
    					}
    					if(PAin(6)==1) //第一列第二行
    					{
    						KeyValue=5;
    						break;   
    					}
    					if(PAin(5)==1) //第一列第三行
    					{
    						KeyValue=9;
    						break;   
    					}
    					if(PAin(4)==1) //第一列第四行
    					{
    						KeyValue=13;
    						break;   
    					}
    				
    		}	
    		
    		if(column==2)
    		{
    				KEY2_Init();     //以下同理				           
    					if(PAin(7)==1)
    					{
    						KeyValue=2;
    						break;   
    					}
    					if(PAin(6)==1)
    					{
    						KeyValue=6;
    						break;  
    					}
    					if(PAin(5)==1)
    					{
    						KeyValue=10;
    						break; 
    					}
    					if(PAin(4)==1)
    					{
    						KeyValue=14;
    						break;  
    					}
    				
    		}		
    		if(column==3)
    		{
    				KEY2_Init();    			           
    					if(PAin(7)==1)
    					{
    						KeyValue=3;
    						break;   
    					}
    					if(PAin(6)==1)
    					{
    						KeyValue=7;
    						break;   
    					}
    					if(PAin(5)==1)
    					{
    						KeyValue=11;
    						break;   
    					}
    					if(PAin(4)==1)
    					{
    						KeyValue=15;
    						break;   
    					}
    				
    		}
    		
    		if(column==4)
    		{
    				KEY2_Init();             
    					if(PAin(7)==1)
    					{
    						KeyValue=4;
    						break;  
    					}
    					if(PAin(6)==1)
    					{
    						KeyValue=8;
    						break;   
    					}
    					if(PAin(5)==1)
    					{
    						KeyValue=12;
    						break;   
    					}
    					if(PAin(4)==1)
    					{
    						KeyValue=16;
    						break;   
    					}				
    		}
    		
    	}
       return KeyValue;
    }
    

    效果图

    注意事项:
    ①在选择开发板的IO口时一定要看看原理图或者数据手册,确定这8个IO口是可用的(小编在使用时本来用了PB2引脚的,结果调试了好久都没得到正确的结果,检查了N多遍程序觉得没问题,最后回归到硬件上才发现原来只有PB2与BOOT1和GND相连了,所以就导致大部分结果都出错啦,希望其他小伙伴别走进坑哈哈)
    ②关于IO口输入输出模式的选择问题。输出模式一般都是选择推挽输出的,因为可直接输出0或1;关于输入模式的话,按键一边输出了0(1),那么要检测是否有按键按下,另一边的应选择上拉输入设置该引脚为1(下拉输入设置该引脚为0)。
    ③该程序没有写按键松开检测程序,所以不松开按键的话可以一直检测到;想弄按键松开检测的小伙伴可以设置一个静态变量作为按键松开的标志即可。

    这里用的方法比较简单易懂,但是比较占用MCU的资源。若大家有很好的推荐,欢迎交流沟通呀!!!若大家要下载源码可以留言邮箱(设置了0C币发现过几天会自动升价)。

    展开全文
  • 基于STM32l152做的4*8矩阵键盘,采用定时器消抖,扫描效率高
  • 矩阵键盘驱动 矩阵键盘驱动 /* *文件 *编写人LiuHui *描述扫描4x4矩阵键盘输入并返回键值 *适用范围驱动采用库编写适用于 STM32F10X系列单片机 *所用引脚PA0-PA7 *编写时间2014年5月20日 */ #i nclude" #i nclude" #...
  • 基于STM32的按键扫描测试程序(学习记录): 目录: 源码; 4x4按键原理; Tips: 粘贴代码时,粘贴在源文件存放的位置中(如:HARDWARE中的.c和.h文件),用C++编译器打开,而不是kei;最后keil会正常显示中文...

    基于STM32的按键扫描测试程序(学习记录):

    目录:

    1. 源码;
    2. 4x4按键原理;
    3. 按键扫描逻辑;

    Tips:

    1. 粘贴代码时,粘贴在源文件存放的位置中(如:HARDWARE中的.c和.h文件),用C++编译器打开,而不是kei;最后keil会正常显示中文字符;
    2. 程序使用嵌套循环实现4x4按键扫描,如果IO口设置过乱时,将循环拆分即可;

    key4x4.h源文件

    #ifndef __KEY4x4_H
    #define __KEY4x4_H	 
    #include "sys.h"
     
    #define KEY_X(X)	PEin(X)				// 尽量避免使用PD以上GPIO,便于移植;
    #define KEY_Y(Y)	PEout(Y)
    
    #define ALL_DOWN_KEY_Y	{	KEY_Y(11) = 0; KEY_Y(12) = 0; KEY_Y(13) = 0; KEY_Y(14) = 0;}
     
    void KEY4x4_Init(void);		// IO口初始化
    u8 KEY4x4_Scan(void);  		// 矩阵按键反馈函数	// 可配置任意矩阵按键使用!!
    u8 KEY16_Scan(void);
    
    /**************
    按键扫描方案二:
    按键使用8个输入IO口, 且所有IO口一端接VCC/VSS;
    
    程序框架:	
    	扫描检测哪两个IO口输入高/低电平;VCC/VSS
    	根据对应坐标,return对应编号;
    **************/
    
    #endif
    

    key4x4.c源文件

    #include "stm32f10x.h"
    #include "key4x4.h"
    #include "sys.h" 
    #include "delay.h"
    #include "usart.h"
    
    
    /*************************
    X:
    	PEin	7-10
    Y:
    	PEout	11-14
    *************************/
    
    
    // 矩阵按键初始化函数
    void KEY4x4_Init(void)
    {
    		GPIO_InitTypeDef GPIO_InitStructure;
    
    		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
    
    		GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10;//KEY0-KEY1
    		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //设置成下拉输入
    		GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE
    
    		GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14;				 //LED0-->PB.5 端口配置
    		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
    		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHz
    		GPIO_Init(GPIOE, &GPIO_InitStructure);					 		//根据设定参数初始化GPIOE
    }
    
    // 使所有输出拉低;初始化;		// 可以使用define宏定义,执行速度更快,不用跳转函数!!
    static void KEY_ALL_Pull_Down(void)
    {
    	KEY_Y(11) = 0;
    	KEY_Y(12) = 0;
    	KEY_Y(13) = 0;
    	KEY_Y(14) = 0;
    }
    
    // 4x4按键扫描函数
    // 使用一个嵌套循环,完成扫描X和Y;
    // 原理: 通过Y 依次输出高电平,
    //				扫描X 那个IO口输入高电平;
    // X轴:输入检查、扫描;
    // Y轴:设置输出状态;
    // 该函数适合任意排列矩阵按键,只需修改循环中对应编号!!
    // 注意: 1. 改变IO口时,该函数还需要改变循环中IO口编号;(可以定义好IO口编号,便于修改)
    //				2. 该函数同样有优先级问题! 即同时按下时,只反馈先被扫描到的(0-15标号最小的)
    //				3. 函数同一坐标轴的IO口编号必须相邻或能有 规律递增可寻;(否则无法用循环判断)
    //				4. 暂时未添加功能(模式):	按键复用 和 长按;
    // 2020-11-13		返回值调整为:1-16
    // 11/14 不支持连按;解决重复反馈的问题;
    u8 KEY4x4_Scan(void)
    {
    	int i,j;
    	u8 IO_Sign = 0;				// 很简便的一个IO反馈方式标签!!!  且嵌套循环特有!!  // 能返回0-15,适合任意排列矩阵按键
    	static key_up = 1;
    	
    	//KEY_ALL_Pull_Down();										// 初始化所有按键输出拉低;
    	
    	for (i = 11; i <= 14; i++)							// Y输出IO口编号;
    		for (j = 7; j <= 10; j++,IO_Sign++)		// X输出IO口编号;  // 递增IO_Sign,反馈对应值(0-15);
    		{
    			KEY_Y(i) = 1;			// 使PEout(i)输出高电平;
    			
    			if (KEY_Y(i))			// 扫描Y输出高电平, 可以取消此判断; 因为必须输出高电平时,才能正常判断!!
    			{
    				if (KEY_X(j) && key_up)		// 当输入检查到高电平时;
    				{
    					key_up = 0;
    					printf("按键扫描反馈: %d  \r\n",IO_Sign);
    					return IO_Sign;
    				}
    				else if (!KEY_X(7)&&!KEY_X(8)&&!KEY_X(9)&&!KEY_X(10))			// 当所有输入检测到低电平时,再次使能按键; 防止重复反馈
    				{
    					key_up = 1;
    					KEY_ALL_Pull_Down();										// 初始化所有按键输出拉低(低电平);必须在此位置;
    				}
    			}
    			else
    				printf("PEout:IO口%d输出异常!  \r\n ", i);
    		}
    		
    	delay_ms(10);					// 按键防抖;
    }
    
    
    /******************************************标准扫描函数*********************************************/
    // 支持连按
    u8 KEY16_Scan(void)
    {
    	int i,j;
    	u8 IO_Sign = 0;				// 很简便的一个IO反馈方式标签!!!  且嵌套循环特有!!  // 能返回0-15,适合任意排列矩阵按键
    	
    	ALL_DOWN_KEY_Y													// 初始化所有按键输出拉低;
    	
    	for (i = 11; i <= 14; i++)							// Y输出IO口编号;
    		for (j = 7; j <= 10; j++,IO_Sign++)		// X输出IO口编号;  // 递增IO_Sign,反馈对应值(0-15);
    		{
    			KEY_Y(i) = 1;			// 使PEout(i)输出高电平;
    
    			if (KEY_X(j))			// 当输入检查到高电平时;
    				return IO_Sign;
    		}
    		
    	delay_ms(20);					// 按键防抖;		// 连按延时;
    }
    
    

    *4x4按键原理图
    在这里插入图片描述

    1. 按键工作原理:
      当按键被按下时,相连的电路导通;即S1按下时,位于0行0列的线短路,使标号4和5对应的IO口相连(导通);
      最后通过扫描检测输入输出状态即可判断出对应按键被按下;

    2. 程序设计思路:
      程序通过依次使标号1、2、3、4(列0-3)输出高电平,判断5/6/7/8(行0-3)状态;完成按键扫描;

    展开全文
  • STM32】4*4矩阵键盘扫描程序(中断方式)

    千次阅读 热门讨论 2020-08-12 21:49:55
    上一篇杂记写了个扫描方式的键盘程序,但是最近在做一个小游戏对CPU响应速度有要求,于是再弄个简单的键盘中断检测程序吧。 总体思路:中断线为4行连接的GPIO口,先初始化矩阵的4行输出低电平4列输出高电平,当有...

    点击下载源码
    上一篇杂记写了个扫描方式的键盘程序,但是最近在做一个小游戏对CPU响应速度有要求,于是再弄个简单的键盘中断检测程序吧。

    总体思路:中断线为4行连接的GPIO口,先初始化矩阵的4行输出低电平4列输出高电平,当有按键按下时的上升沿触发中断;然后在相应的中断处理函数里面采取查询的方式(参考上篇)获得键值。

    部分程序

    void EXTI9_5_IRQHandler(void)                           //外部中断中断函数
    {
    
    		if(EXTI_GetITStatus(EXTI_Line7) != RESET)           //检测中断标志位
    		{			
    			//行置高,列置低,扫描列
    			GPIO_SetBits ( ROW1_GPIO_PORT, ROW1_GPIO_PIN );
    			
    			GPIO_ResetBits ( LINE1_GPIO_PORT, LINE1_GPIO_PIN );
    		    GPIO_ResetBits ( LINE2_GPIO_PORT, LINE2_GPIO_PIN );
    		    GPIO_ResetBits ( LINE3_GPIO_PORT, LINE3_GPIO_PIN );
    			GPIO_ResetBits ( LINE4_GPIO_PORT, LINE4_GPIO_PIN );
    
    			//取4列的状态
    			if(GPIO_ReadInputDataBit ( LINE1_GPIO_PORT, LINE1_GPIO_PIN ))
    			{
    				while(GPIO_ReadInputDataBit ( LINE1_GPIO_PORT, LINE1_GPIO_PIN )); //等待按键松开,不然出现连续进入中断的错误
    				KeyValue = 1;
    									
    			}
    			if(GPIO_ReadInputDataBit ( LINE2_GPIO_PORT, LINE2_GPIO_PIN ))
    			{
    				while(GPIO_ReadInputDataBit ( LINE2_GPIO_PORT, LINE2_GPIO_PIN ));
    				KeyValue = 2;
    			}
    			if(GPIO_ReadInputDataBit ( LINE3_GPIO_PORT, LINE3_GPIO_PIN ))
    			{
    				while(GPIO_ReadInputDataBit ( LINE3_GPIO_PORT, LINE3_GPIO_PIN ));
    				KeyValue = 3;
    			}
               if(GPIO_ReadInputDataBit ( LINE4_GPIO_PORT, LINE4_GPIO_PIN ))
    			{
    				while(GPIO_ReadInputDataBit ( LINE4_GPIO_PORT, LINE4_GPIO_PIN ));
    				KeyValue = 4;
    			}				
    			EXTI_ClearITPendingBit(EXTI_Line7);                         //清除标志位	
    
    		}		
    		
    		
    		if(EXTI_GetITStatus(EXTI_Line6) != RESET)           //检测中断标志位
    		{
    		
    			GPIO_SetBits ( ROW2_GPIO_PORT, ROW2_GPIO_PIN );
    			
    			GPIO_ResetBits ( LINE1_GPIO_PORT, LINE1_GPIO_PIN );
    		    GPIO_ResetBits ( LINE2_GPIO_PORT, LINE2_GPIO_PIN );
    		    GPIO_ResetBits ( LINE3_GPIO_PORT, LINE3_GPIO_PIN );
    			GPIO_ResetBits ( LINE4_GPIO_PORT, LINE4_GPIO_PIN );
    			//取4列的状态
    			if(GPIO_ReadInputDataBit ( LINE1_GPIO_PORT, LINE1_GPIO_PIN ))
    			{
    				while(GPIO_ReadInputDataBit ( LINE1_GPIO_PORT, LINE1_GPIO_PIN ));
    				KeyValue = 5;			
    			}
    			if(GPIO_ReadInputDataBit ( LINE2_GPIO_PORT, LINE2_GPIO_PIN ))
    			{
    				while(GPIO_ReadInputDataBit ( LINE2_GPIO_PORT, LINE2_GPIO_PIN ));
    				KeyValue = 6;
    			}
    			if(GPIO_ReadInputDataBit ( LINE3_GPIO_PORT, LINE3_GPIO_PIN ))
    			{
    				while(GPIO_ReadInputDataBit ( LINE3_GPIO_PORT, LINE3_GPIO_PIN ));
    				KeyValue = 7;
    			}
    			if(GPIO_ReadInputDataBit ( LINE4_GPIO_PORT, LINE4_GPIO_PIN ))
    			{
    				while(GPIO_ReadInputDataBit ( LINE4_GPIO_PORT, LINE4_GPIO_PIN ));
    				KeyValue = 8;
    			}
    			EXTI_ClearITPendingBit(EXTI_Line6);                         //清除标志位
    		}
    		
    		if(EXTI_GetITStatus(EXTI_Line5) != RESET)           //检测中断标志位
    		{
    	
    			GPIO_SetBits ( ROW3_GPIO_PORT, ROW3_GPIO_PIN );
    			
    			GPIO_ResetBits ( LINE1_GPIO_PORT, LINE1_GPIO_PIN );
    		    GPIO_ResetBits ( LINE2_GPIO_PORT, LINE2_GPIO_PIN );
    		    GPIO_ResetBits ( LINE3_GPIO_PORT, LINE3_GPIO_PIN );
    			GPIO_ResetBits ( LINE4_GPIO_PORT, LINE4_GPIO_PIN );
    			//取4列的状态
    			if(GPIO_ReadInputDataBit ( LINE1_GPIO_PORT, LINE1_GPIO_PIN ))
    			{
    				while(GPIO_ReadInputDataBit ( LINE1_GPIO_PORT, LINE1_GPIO_PIN ));
    				KeyValue = 9;			
    			}
    			if(GPIO_ReadInputDataBit ( LINE2_GPIO_PORT, LINE2_GPIO_PIN ))
    			{
    				while(GPIO_ReadInputDataBit ( LINE2_GPIO_PORT, LINE2_GPIO_PIN ));
    				KeyValue = 10;
    			}
    			if(GPIO_ReadInputDataBit ( LINE3_GPIO_PORT, LINE3_GPIO_PIN ))
    			{
    				while(GPIO_ReadInputDataBit ( LINE3_GPIO_PORT, LINE3_GPIO_PIN ));
    				KeyValue = 11;
    			}
    			if(GPIO_ReadInputDataBit ( LINE4_GPIO_PORT, LINE4_GPIO_PIN ))
    			{
    				while(GPIO_ReadInputDataBit ( LINE4_GPIO_PORT, LINE4_GPIO_PIN ));
    				KeyValue = 12;
    			}
    			EXTI_ClearITPendingBit(EXTI_Line5);                         //清除标志位
    		}
    				
    		//重置GPIO,等待下次中断
    	    //行置高
    		GPIO_ResetBits ( ROW1_GPIO_PORT, ROW1_GPIO_PIN );
    		GPIO_ResetBits ( ROW2_GPIO_PORT, ROW2_GPIO_PIN );
    		GPIO_ResetBits ( ROW3_GPIO_PORT, ROW3_GPIO_PIN );
    	    GPIO_ResetBits ( ROW4_GPIO_PORT, ROW4_GPIO_PIN );
        	//列置高
    		GPIO_SetBits ( LINE1_GPIO_PORT, LINE1_GPIO_PIN );
    		GPIO_SetBits ( LINE2_GPIO_PORT, LINE2_GPIO_PIN );
    		GPIO_SetBits ( LINE3_GPIO_PORT, LINE3_GPIO_PIN );	
    		GPIO_SetBits ( LINE4_GPIO_PORT, LINE4_GPIO_PIN );	
    	}
    void EXTI4_IRQHandler(void) 
    {
    if(EXTI_GetITStatus(EXTI_Line4) != RESET)           //检测中断标志位
    		{
    		
    			
    			GPIO_SetBits ( ROW4_GPIO_PORT, ROW4_GPIO_PIN );
    			
    			GPIO_ResetBits ( LINE1_GPIO_PORT, LINE1_GPIO_PIN );
    		    GPIO_ResetBits ( LINE2_GPIO_PORT, LINE2_GPIO_PIN );
    		    GPIO_ResetBits ( LINE3_GPIO_PORT, LINE3_GPIO_PIN );
    			GPIO_ResetBits ( LINE4_GPIO_PORT, LINE4_GPIO_PIN );
    			//取4列的状态
    			if(GPIO_ReadInputDataBit ( LINE1_GPIO_PORT, LINE1_GPIO_PIN ))
    			{
    				while(GPIO_ReadInputDataBit ( LINE1_GPIO_PORT, LINE1_GPIO_PIN ));
    				KeyValue = 13;		
    			}
    			if(GPIO_ReadInputDataBit ( LINE2_GPIO_PORT, LINE2_GPIO_PIN ))
    			{
    				while(GPIO_ReadInputDataBit ( LINE2_GPIO_PORT, LINE2_GPIO_PIN ));
    				KeyValue = 14;
    			}
    			if(GPIO_ReadInputDataBit ( LINE3_GPIO_PORT, LINE3_GPIO_PIN ))
    			{
    				while(GPIO_ReadInputDataBit ( LINE3_GPIO_PORT, LINE3_GPIO_PIN ));
    				KeyValue = 15;   
    			}
    			if(GPIO_ReadInputDataBit ( LINE4_GPIO_PORT, LINE4_GPIO_PIN ))
    			{
    				while(GPIO_ReadInputDataBit ( LINE4_GPIO_PORT, LINE4_GPIO_PIN ));
    				KeyValue = 16;   
    			}
    			EXTI_ClearITPendingBit(EXTI_Line4);                         //清除标志位
    		}
    		//重置GPIO,等待下次中断
    	    //行置高
    		GPIO_ResetBits ( ROW1_GPIO_PORT, ROW1_GPIO_PIN );
    		GPIO_ResetBits ( ROW2_GPIO_PORT, ROW2_GPIO_PIN );
    		GPIO_ResetBits ( ROW3_GPIO_PORT, ROW3_GPIO_PIN );
    	    GPIO_ResetBits ( ROW4_GPIO_PORT, ROW4_GPIO_PIN );
        	//列置高
    		GPIO_SetBits ( LINE1_GPIO_PORT, LINE1_GPIO_PIN );
    		GPIO_SetBits ( LINE2_GPIO_PORT, LINE2_GPIO_PIN );
    		GPIO_SetBits ( LINE3_GPIO_PORT, LINE3_GPIO_PIN );	
    		GPIO_SetBits ( LINE4_GPIO_PORT, LINE4_GPIO_PIN );	
    }
    
    

    注意事项:
    ①在选择开发板的IO口时一定要看看原理图或者数据手册,确定这8个IO口是可用的
    ②使用外部中断时要打开复用IO时钟AFIO
    ③中断程序里面一定要有按键松开的检测,不然会一直进入中断服务函数。

    若大家要下载源码可以留言邮箱(设置了0C币发现过几天会自动升价)。还有其他建议,欢迎交流沟通呀!!!

    展开全文
  • //按键扫描函数 void Key_Text(void); #endif key.c文件 #include "key.h" #include "sys.h" #include "delay.h" #include "usart.h" #include "lcd.h" u8 tem; //按键初始化函数 void KEY_Init...
  • STM32 矩阵键盘通过串口输出

    千次阅读 2018-05-21 21:18:08
    STM32F103C8T6 4*4矩阵键盘 通过串口输出,可以用来写密码锁程序的思路如下:1、首先需要配置的是矩阵键盘:配置两个函数: KEY44_Init(矩阵键盘初始化)和key44_Scan(扫描并获取值) 。2、其次,设置串口(本文设置...
  • 亲测可用4X4矩阵键盘,简单好用,采用行列扫描方法,延时程序不占用MCU资源。 主控芯片为stm32f407VGT6
  • stm32矩阵按键程序.rar

    2020-06-16 13:19:05
    键盘扫描
  • //stm32矩阵键盘翻转扫描法(PB口的低8位) //将此矩阵键盘扫描程序放在定时器中断服务程序里 //每10ms进入一次中断服务程序 s8 scan_MatrixKey(void) { #define PORT GPIOB->IDR u8 column;//列 u8 row;//行 u8 ...
  • 经本人刻苦钻研,将51单片机上用的矩阵键盘扫描程序移植到了stm32上,同时也做了很大的改进,最大的改进莫过于消抖这块了。以前的消抖总是采用delay延时约10到20ms的时间,但这样会导致MCU在延时里空跑而造成主程序...
  • 本文实现的代码是基于STM32HAL库的基础上的,不过标准库也可以用,只是调用的库函数不同,逻辑跟配置是一样的,按我这里的逻辑来配置即可。 1、键盘原理图: 原理举例:先把 F0-F7 内部拉高,这样这个8个引脚都是高...
  • 利用stm32f103vet6外部中断来获取矩阵键盘键值外加可精确到小数点后6位计算器源程序 利用外部中断来获取键值,避免了逐行扫描,减少了cpu的占用。准确的获取键值,运用二维数组来存放键值,让55的矩阵键盘输出键值,...
  • title: stm32的4X4矩阵键盘任意管脚扫描 tags: [单片机,编程] categories: 技术 两年前闲来无事 在发烧友发了个程序 加了精华的(修改之后还没加) 哈哈 文章链接 那时候,喜欢玩单片机的不行,玩了两年。上位机、APP...
  • 本人今天又换种思路写了个关于stm32的4X4矩阵键盘定时器扫描消抖法的算法程序,同样是采用的效率较高的翻转法,已通过测试,希望大家喜欢!大概思路为:将端口的第N次扫描值和第(N-1)次的扫描值进行比较,若相等则...
  • 程序实现4*5键盘扫描 从左到右,从上到下,键值 依次为1-20 中断扫描模式 ,要在NVIC在中打开对应中断 /*可以自己定义其它扫描方式
  • 程序已经过测验通过,使用扫描法完成了矩阵键盘的设计,每一句基本都有注释,工程文件齐全,测试方便,使用的是神州I号 STM32F103RBT6
  • 关注【电子开发圈】微信公众号,一起学习吧!...电子DIY、Arduino、51单片机、STM32单片机、FPGA…… 电子百科、开发技术、职业经验、趣味知识、科技头条、设备拆机…… 点击链接,免费下载100G+电子设计学习资料! ...
  • 单片机STM32入门——(3)矩阵按键1.理论分析1.1键盘扫描方式1.2行扫描逻辑1.3列扫描逻辑2.程序编写2.1按键扫描程序2.1.1按键初始化2.1.2按键扫描程序头文件2.1.3行扫描函数2.1.3列扫描函数2.2主程序 1.理论分析 1.1...
  • 4x4矩阵键盘.zip

    2019-07-27 11:27:34
    基于STM32f407zgt6的4*4矩阵键盘程序,采用行列扫描的方式,操作矩阵键盘。 有疑惑的朋友,欢迎通过Read me中的联系方式,前来共同探讨。
  • 接上文STM32矩阵键盘的设计实现。 按键抖动 成功扫描到按键按下后,由于按键本身有着不可避免的抖动问题,一般我们会设置一段延时,延时过后再次判断按键是否按下。 这是使用逻辑分析仪捕捉的一个按键从按下到...
  • 电子设计.doc

    2019-05-28 11:58:28
    0232、例说STM32 ALIENTEK MINISTM32 实验27例光盘资料 0233、UC3843控制多路输出开关电源设计与实现 0234、1.8V 5.2 GHz 差分结构CMOS 低噪声放大器 0235、40kHZ_超声波测距 0236、51单片机开发板实验板程序60例...

空空如也

空空如也

1 2
收藏数 30
精华内容 12
关键字:

stm32矩阵键盘扫描程序