一.概要
在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式。在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。这样,8个I/O口就可以构成4*4=16个按键,比之直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显,比如再多加1个I/O口就可以构成20键的键盘,而直接用端口线则只能多出1键(总共9键)。由此可见,在需要的键数比较多时,采用矩阵法来做键盘是合理的。
本文介绍了4*4矩阵按键,以及用STM32单片机实现矩阵按键数字输入。
二.4*4矩阵按键原理图
4*4矩阵按键的原理就是通过8个端口与单片机连接,4个IO口控制行,4个IO口控制列。
三.4*4矩阵按键代码驱动原理
如下图所示:
A0,A1,A2,A3接单片机的PA0,PA1,PA2,PA3脚,单片机这几个脚配置成输出。
A4,A5,A6,A7接单片机的PA4,PA5,PA6,PA7脚,单片机这几个脚配置成输入,并且管脚上拉,这样没有按键按下,A0脚输出低电平,没有导通,从A4脚读到的电平是高电平。假如K1按键按下,A0脚输出低电平就能从A4读到低电平,接下去A0输出高,然后依次A1,A2,A3先输出低,再输出高循环,假如下一个循环A2输出低的时候,A4读到低电平,那就是K9按键按下了。如果在A2输出低的时候,A5读到低电平,那就是K10按键按下了。
四.STM32单片机4*4矩阵按键实验
用杜邦线连接板子与OLED液晶:
板子G----液晶GND
板子3.3–液晶VCC
板子B8—液晶D0
板子B9—液晶D1
板子B12–液晶RES
板子B13–液晶DC
板子B14–液晶CS
用杜邦线连接板子与键盘模块:
开发板PA0<->模块R1
开发板PA1<->模块R2
开发板PA2<->模块R3
开发板PA3<->模块R4
开发板PA4<->模块C1
开发板PA5<->模块C2
开发板PA6<->模块C3
开发板PA7<->模块C4
打开STM32CubeMX软件,新建工程
Part Number处输入STM32F103C8,再双击就创建新的工程
配置下载口引脚
配置外部晶振引脚
GPIO配置
配置系统主频
配置工程文件名,保存路径,KEIL5工程输出方式
生成工程
用Keil5打开工程
添加代码
主要程序:
uint8_t Key_row[1]={0xff}; //保存按键行扫描情况的状态数组
uint8_t key_Data;
/***
*函数名:KEY_ROW_SCAN
*功 能:按键行扫描
*返回值:1~4,对应1~4行按键位置
*/
char KEY_ROW_SCAN(void)
{
//读出行扫描状态
Key_row[0] = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_4)<<3;//列1读取
Key_row[0] = Key_row[0] | (HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_5)<<2);//列2读取
Key_row[0] = Key_row[0] | (HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_6)<<1);//列3读取
Key_row[0] = Key_row[0] | (HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_7));//列4读取
if(Key_row[0] != 0x0f) //行扫描有变化,判断该列有按键按下
{
HAL_Delay(10); //消抖
if(Key_row[0] != 0x0f)
{
switch(Key_row[0])
{
case 0x07: //0111 判断为该列第1行的按键按下
return 1;
case 0x0b: //1011 判断为该列第2行的按键按下
return 2;
case 0x0d: //1101 判断为该列第3行的按键按下
return 3;
case 0x0e: //1110 判断为该列第4行的按键按下
return 4;
default :
return 0;
}
}
else return 0;
}
else return 0;
}
/***
*函数名:KEY_SCAN
*功 能:4*4按键扫描
*返回值:0~16,对应16个按键
*/
char KEY_SCAN(void)
{
char Key_Num=0; //1-16对应的按键数
char key_row_num=0; //行扫描结果记录
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET); //行1置低
if( (key_row_num=KEY_ROW_SCAN()) != 0 )
{
while(KEY_ROW_SCAN() != 0); //消抖
Key_Num = 0 + key_row_num;
}
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET); //行1置高
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET); //行2置低
if( (key_row_num=KEY_ROW_SCAN()) != 0 )
{
while(KEY_ROW_SCAN() != 0);
Key_Num = 4 + key_row_num;
}
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET); //行2置高
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET); //行3置低
if( (key_row_num=KEY_ROW_SCAN()) != 0 )
{
while(KEY_ROW_SCAN() != 0);
Key_Num = 8 + key_row_num;
}
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET); //行3置高
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET); //行4置低
if( (key_row_num=KEY_ROW_SCAN()) != 0 )
{
while(KEY_ROW_SCAN() != 0);
Key_Num = 12 + key_row_num;
}
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET); //行4置高
return Key_Num;
}
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();//8M外部晶振,72M系统主频
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
OLED_Init(); //初始化OLED
OLED_Clear();
OLED_ShowCHinese(34,0,0);//光
OLED_ShowCHinese(52,0,1);//子
OLED_ShowCHinese(70,0,2);//物
OLED_ShowCHinese(88,0,3);//联
OLED_ShowString(36,3,"KEY TEST");
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
key_Data = KEY_SCAN();
if(key_Data!=0)
{
OLED_ShowNum(48,6,key_Data,3,16);//显示数字
}
}
/* USER CODE END 3 */
}
五.CubeMX工程源代码下载
通过百度网盘分享的文件:32.4乘4矩阵键盘.rar
链接:https://pan.baidu.com/s/174j9-_OOCh2lOwJjmdwpvg
提取码:eryb
如果链接失效,可以联系博主给最新链接
程序下载下来之后解压就行
六.小结
矩阵键盘主要应用在需要使用大量按键的场景中,以节省IO资源。矩阵键盘通过将按键排列成矩阵形式,可以有效地减少I/O口的占用,适用于计算器、遥控器、触摸屏ID产品、银行的提款机、密码输入器等多种设备。