4×4矩阵键盘1.原理说明一般的4*4矩阵键盘(如图1)一般要8个I/O口(如图1),对于按键较多的硬件系统来说是很浪费的I/O口,本方案仅采用4个I/O和4个普通二极管就可以轻松实现4×4矩阵键盘,方案原理与普通4*4矩阵键盘类似,下面先分析普通矩阵键盘原理,再进一步改进为本方案。
原理如下B4口为低电平,A1~A4,B1~B3为高电平,单片机不停的扫描,假若有键按下如A1与B4交叉处按下则对应的A1被拉低为低电平,可以定义此键号为1,同理以此类推B3口为低电平,其余口为高电平,交叉处按键按下可定义其按键号,将按键号存储在寄存器中,可用查表方法并通过数码管显示按键号。
对于下图(图2)用4个I/O和4个普通二极管初始化PA0.0~PA0.3 均为高电平,在这里二极管作用是当IO口为低电平时可以导通,高电平时截止。
程序流程图如下图1图22.程序介绍如下void RCC_Configuration(void);{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);}void GPIO_Configuration(void){GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0| GPIO_Pin_1| GPIO_Pin_2| GPIO_Pin_3;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_PP _ OUT;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);}GPIOSetBits(){GPIO_SetBits(GPIOA,GPIO_Pin_0);GPIO_SetBits(GPIOA,GPIO_Pin_1);GPIO_SetBits(GPIOA,GPIO_Pin_2);GPIO_SetBits(GPIOA,GPIO_Pin_3);}单片机不停的扫描程序,(右侧四个键单独来写),由于扫描速度是很快(微妙级)的,所以有足够的时间去显示每个按键的。
当(GPIO_Pin_0==0)时表明有键按下,我们定义为0号键,当(GPIO_Pin_1==0)时表明有键按下,我们定义为1号键,当(GPIO_Pin2==0)时表明有键按下,我们定义为2号键,当(GPIO_Pin_3==0)时表明有键按下,我们定义为3号键,if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==0)return 0;if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)==0)return 1;if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2)==0)return 2;if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3)==0)return 3;其余按键方法不同于右侧四个按键,每个I/O口接一个二极管以保证当有高电平截止,低电平导通,即可得到每个键号。
扫描程序分析如下:当( GPIO_Pin_0==0) 时:若(GPIOA, GPIO_Pin_1)==0)则为4键按下,若(GPIOA, GPIO_Pin_2)==0)则为5键按下,若(GPIOA, GPIO_Pin_3)==0)则为6键按下,当GPIO_Pin_1==0时:若(GPIOA, GPIO_Pin_0)==0)则为7键按下,若(GPIOA, GPIO_Pin_2)==0)则为8键按下,若(GPIOA, GPIO_Pin_3)==0)则为9键按下,当GPIO_Pin_2==0时:若(GPIOA, GPIO_Pin_0)==0)则为A(10)键按下,若(GPIOA, GPIO_Pin_1)==0)则为B(11)键按下,若(GPIOA, GPIO_Pin_3)==0)则为C(12)键按下,当GPIO_Pin_3==0时:若(GPIOA, GPIO_Pin_0)==0)则为D(13)键按下,若(GPIOA, GPIO_Pin_1)==0)则为E(14)键按下,若(GPIOA, GPIO_Pin_2)==0)则为F(15)键按下,if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==0){if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)==0)return4;if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2)==0)return5;if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3)==0)return6;}if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)==0){if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==0)return7;if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2)==0)return8;if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3)==0)return9;}if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2)==0){if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==0)return10;if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)==0)return11;if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3)==0)return12;}if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3)==0){if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==0)return13;if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2)==0)return14;if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3)==0)return15;}/******************************************************************************** * @file None* @author None* @version V3.5.0* @date 2012年6月05号* @brief Main program body*//* Includes ------------------------------------------------------------------*/#include "stm32f10x.h"void RCC_Configuration(void);void GPIO_Configuration(void);void GPIOSetBits(void);/* Private functions ---------------------------------------------------------*/int main(void){/*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startupfile (startup_stm32f10x_xx.s) before to branch to application main.To reconfigure the default setting of SystemInit() function, refer tosystem_stm32f10x.c file*//* System Clocks Configuration */RCC_Configuration();/* GPIO Configuration */GPIO_Configuration();GPIOSetBits();if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==0){if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)==0)return 4;if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2)==0)return 5;if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3)==0)return 6;}if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)==0){if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==0)return 7;if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2)==0)return 8;if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3)==0)return 9;}if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2)==0){if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==0)return 10;if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)==0)return 11;if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3)==0)return 12;}if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3)==0)if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==0)return 13;if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2)==0)return 14;if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3)==0)return 15;}while (1){}}/*** @brief Configures the different system clocks.* @param None* @retval None*/void RCC_Configuration(void){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE); }void GPIO_Configuration(void){GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0| GPIO_Pin_1| GPIO_Pin_2| GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_PP _ OUT;}void GPIOSetBits(void){GPIO_SetBits(GPIOA,GPIO_Pin_0);GPIO_SetBits(GPIOA,GPIO_Pin_1);GPIO_SetBits(GPIOA,GPIO_Pin_2);GPIO_SetBits(GPIOA,GPIO_Pin_3);}#ifdef USE_FULL_ASSERT/*** @brief Reports the name of the source file and the source line number* where the assert_param error has occurred.* @param file: pointer to the source file name* @param line: assert_param error line source number* @retval Nonevoid assert_failed(uint8_t* file, uint32_t line){/* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */while (1){}}#endif/******************* (C) COPYRIGHT 2012 STMicroelectronics *****END OF FILE****/ 3.附录程序流程图图3。