赞
踩
点击下载源码
上一篇杂记写了个扫描方式的键盘程序,但是最近在做一个小游戏对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币发现过几天会自动升价)。还有其他建议,欢迎交流沟通呀!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。