STM32f4日記7之外設矩陣鍵盤的使用(4X4矩陣鍵盤解放板上資源)
板子:stm32f407zgt6正點原子迷你版
鑒于目前網上的教學形態各異,很多帶有迷惑、誤導性質,所以寫這篇文章交流自己的看法,也權當紀錄自己的學習經歷,
作者:shawn
可咨詢QQ:965798711(要完整代碼可在評論區留下郵箱)
2021.2.13(大年初二)
19:05
All rights reserved
//
如果你覺得對你有幫助,請點贊同,這對我很重要,謝謝,
//
一、器材介紹
核心模塊:4X4矩陣鍵盤

原理圖如下:

二、原理講解
扎實學過51單片機的朋友一定對矩陣鍵盤了解的多一些,但是對于一開始就入手STM32的朋友,矩陣鍵盤可能是個難點,我簡單介紹一下(用不規范的語言),
就用這張原理圖來說:

矩陣鍵盤16個按鍵,一共被8根線連接P30,P31,P32,P33連接四行,P34,P35,P36,P37連接四列,
首先我們將P30,P31,P32,P33初始化為輸入IO,將P34,P35,P36,P37初始化為輸出IO
舉個栗子:如果我們按下S1
先給P30高電平,此時我們檢測P34,P35,P36,P37發現P34高電平
再給P31高電平,此時我們檢測P34,P35,P36,P37發現都是低電平
再給P32高電平,此時我們檢測P34,P35,P36,P37發現都是低電平
再給P33高電平,此時我們檢測P34,P35,P36,P37發現都是低電平
此時,我們就確定了,跟P34,P30有關的那個按鍵就是被按下的按鍵,此時就是S1,這就是俗稱的矩陣鍵盤的掃描
其他的幾個按鍵以此類推,會發現每一個按鍵對應的兩根線都是獨一無二的,
三、硬體連接
我們是用PF的2,3,4,5 IO口跟PC的0,1,2,3 IO口(PF輸出,PC輸入)
按照上面給出的那個矩陣鍵盤的圖:
PF的2,3,4,5 IO口對應R1,2,3,4,
PC的0,1,2,3 對應C1,2,3,4,
四、代碼撰寫
key.c
里面兩個函式void KEY_Init(void) 用來配置底層
u8 KEY_Scan(void)用來矩陣鍵盤檢測
#include "key.h"
#include "sys.h"
#include "usart.h"
u8 tem;
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOF,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);//輸入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOF, &GPIO_InitStructure);//輸出
}
u8 KEY_Scan(void)
{
static u8 key_flag1=1,key_flag2=1,key_flag3=1,key_flag4=1;
u8 KeyVal;
GPIO_Write(GPIOF,(( GPIOF->ODR & 0xFFC3 )|0x0004)); //0100 1111 1111 1100 0011 檢測第一行
if(key_flag1&&(Read_Lie1==1||Read_Lie2==1||Read_Lie3==1||Read_Lie4==1))
{
key_flag1=0;
if (Read_Lie1==1){ KeyVal= 1; printf("key:%d\r\n",KeyVal);}
else if (Read_Lie2==1) {KeyVal= 2; printf("key:%d\r\n",KeyVal);}
else if (Read_Lie3==1) {KeyVal= 3; printf("key:%d\r\n",KeyVal);}
else if (Read_Lie4==1) {KeyVal= 4; printf("key:%d\r\n",KeyVal);}
}
else if(Read_Lie1==0&&Read_Lie2==0&&Read_Lie3==0&&Read_Lie4==0)key_flag1=1;
else return 0;
GPIO_Write(GPIOF,(( GPIOF->ODR & 0xFFC3 )|0x0008));//1000檢測第二行
if(key_flag2&&(Read_Lie1==1||Read_Lie2==1||Read_Lie3==1||Read_Lie4==1))
{
key_flag2=0;
if (Read_Lie1==1){ KeyVal= 5; printf("key:%d\r\n",KeyVal);}
else if (Read_Lie2==1) {KeyVal= 6; printf("key:%d\r\n",KeyVal);}
else if (Read_Lie3==1) {KeyVal= 7; printf("key:%d\r\n",KeyVal);}
else if (Read_Lie4==1) {KeyVal= 8; printf("key:%d\r\n",KeyVal);}
}
else if(Read_Lie1==0&&Read_Lie2==0&&Read_Lie3==0&&Read_Lie4==0)key_flag2=1;
else return 0;
GPIO_Write(GPIOF,(( GPIOF->ODR & 0xFFC3 )|0x0010));// 0001 0000檢測第三行
if(key_flag3&&(Read_Lie1==1||Read_Lie2==1||Read_Lie3==1||Read_Lie4==1))
{
key_flag3=0;
if (Read_Lie1==1){ KeyVal= 9; printf("key:%d\r\n",KeyVal);}
else if (Read_Lie2==1) {KeyVal= 10; printf("key:%d\r\n",KeyVal);}
else if (Read_Lie3==1) {KeyVal= 11; printf("key:%d\r\n",KeyVal);}
else if (Read_Lie4==1) {KeyVal= 12; printf("key:%d\r\n",KeyVal);}
}
else if(Read_Lie1==0&&Read_Lie2==0&&Read_Lie3==0&&Read_Lie4==0)key_flag3=1;
else return 0;
GPIO_Write(GPIOF,(( GPIOF->ODR & 0xFFC3 )|0x0020));//0010 0000檢測第四行
if(key_flag4&&(Read_Lie1==1||Read_Lie2==1||Read_Lie3==1||Read_Lie4==1))
{
key_flag4=0;
if (Read_Lie1==1){ KeyVal= 13; printf("key:%d\r\n",KeyVal);}
else if (Read_Lie2==1) {KeyVal= 14; printf("key:%d\r\n",KeyVal);}
else if (Read_Lie3==1) {KeyVal= 15; printf("key:%d\r\n",KeyVal);}
else if (Read_Lie4==1) {KeyVal= 16; printf("key:%d\r\n",KeyVal);}
}
else if(Read_Lie1==0 &&Read_Lie2==0 &&Read_Lie3==0 &&Read_Lie4==0 )key_flag4=1;
else return 0;
return KeyVal;
}
GPIO_Write(GPIOF,(( GPIOF->ODR & 0xFFC3 )|0x0008));這是位操作,劃重點 ,大家理解一下
key.h里面
#ifndef __KEY_H
#define __KEY_H
#include "sys.h"
#define Read_Lie1 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_0)
#define Read_Lie2 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_1)
#define Read_Lie3 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2)
#define Read_Lie4 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)
void KEY_Init(void);
u8 KEY_Scan(void);
#endif
主函式里面回圈KEY_Scan()就行
五、實驗效果
打開串口依次按鍵就能看到資料

六、其實打比賽輸入顯示可以合為一體
使用串口屏
可以看我之前發過的文章STM32f4日記4之HMI智能串口屏與單片機串口通信實驗
點上面鏈接就行
作者:shawn
可咨詢QQ:965798711(要完整代碼可在評論區留下郵箱)
2021.2.13(大年初二)
19:05
All rights reserved
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/259552.html
標籤:其他
下一篇:猜數字小游戲
