欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

【STM32】4*4矩阵键盘扫描程序(中断方式)

程序员文章站 2022-03-27 21:53:15
上一篇杂记写了个扫描方式的键盘程序,但是最近在做一个小游戏对CPU响应速度有要求,于是再弄个简单的键盘中断检测程序吧。 总体思路:中断线为4行连接的GPIO口,先初始化矩阵的4行输出低电平4列输出高电平,当有按键按下时的上升沿触发中断;然后在相应的中断处理函数里面采取查询的方式(参考上篇)获得键值。部分程序void EXTI9_5_IRQHandler(void) //外部中断中断函数{if(EXTI_GetITStatus(EXTI...

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

【STM32】4*4矩阵键盘扫描程序(中断方式)

总体思路:中断线为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
③中断程序里面一定要有按键松开的检测,不然会一直进入中断服务函数。

若大家有其他建议,欢迎交流沟通呀!!!

本文地址:https://blog.csdn.net/yechongbinbin/article/details/107967191