不同于之前一篇,这篇就是走常规路子的方法了,
KEY.C
#include "Key.h"
/********************************配置IO为上拉输入********************************************/
#define configInputPullUp(port, pin, GPIO_InitStruct) { \
/* HAL_GPIO_WritePin(port, pin, GPIO_PIN_RESET); */ \
(GPIO_InitStruct)->Pin = pin ; \
(GPIO_InitStruct)->Mode = GPIO_MODE_INPUT ; \
(GPIO_InitStruct)->Pull = GPIO_PULLUP ; \
(GPIO_InitStruct)->Speed = GPIO_SPEED_FREQ_LOW; \
HAL_GPIO_Init(port, GPIO_InitStruct) ; \
}
/********************************配置IO为推挽输出低电平********************************************/
#define configOutputLow(port, pin, GPIO_InitStruct) { \
(GPIO_InitStruct)->Pin = pin ; \
(GPIO_InitStruct)->Mode = GPIO_MODE_OUTPUT_PP ; \
(GPIO_InitStruct)->Pull = GPIO_NOPULL ; \
(GPIO_InitStruct)->Speed = GPIO_SPEED_FREQ_LOW; \
HAL_GPIO_Init(port, GPIO_InitStruct) ; \
HAL_GPIO_WritePin(port, pin, GPIO_PIN_RESET); \
}
void rowScanningEnter()
{
GPIO_InitTypeDef GPIO_InitStruct;
configInputPullUp(ROW3_GPIO_Port,ROW3_Pin,&GPIO_InitStruct);
configInputPullUp(ROW2_GPIO_Port,ROW2_Pin,&GPIO_InitStruct);
configInputPullUp(ROW1_GPIO_Port,ROW1_Pin,&GPIO_InitStruct);
configInputPullUp(ROW0_GPIO_Port,ROW0_Pin,&GPIO_InitStruct);
configOutputLow(COL3_GPIO_Port,COL3_Pin,&GPIO_InitStruct);
configOutputLow(COL2_GPIO_Port,COL2_Pin,&GPIO_InitStruct);
configOutputLow(COL1_GPIO_Port,COL1_Pin,&GPIO_InitStruct);
configOutputLow(COL0_GPIO_Port,COL0_Pin,&GPIO_InitStruct);
}
void colScanningEnter()
{
GPIO_InitTypeDef GPIO_InitStruct;
configOutputLow(ROW3_GPIO_Port,ROW3_Pin,&GPIO_InitStruct);
configOutputLow(ROW2_GPIO_Port,ROW2_Pin,&GPIO_InitStruct);
configOutputLow(ROW1_GPIO_Port,ROW1_Pin,&GPIO_InitStruct);
configOutputLow(ROW0_GPIO_Port,ROW0_Pin,&GPIO_InitStruct);
configInputPullUp(COL3_GPIO_Port,COL3_Pin,&GPIO_InitStruct);
configInputPullUp(COL2_GPIO_Port,COL2_Pin,&GPIO_InitStruct);
configInputPullUp(COL1_GPIO_Port,COL1_Pin,&GPIO_InitStruct);
configInputPullUp(COL0_GPIO_Port,COL0_Pin,&GPIO_InitStruct);
}
u8 KEY_SCAN(void)
{
u8 Key_ROW = 0,Key_COL = 0,Key_Read = 0;
u8 key;
rowScanningEnter();
Key_ROW = (u8)( (((u8)DETECT_R0) << 3) |
(((u8)DETECT_R1) << 2) |
(((u8)DETECT_R2) << 1) |
((u8)DETECT_R3) );
Key_ROW&=0x0f;
if(Key_ROW != 0x0f)
{
HAL_Delay(10);
Key_ROW = (u8)( (((u8)DETECT_R0) << 3) |
(((u8)DETECT_R1) << 2) |
(((u8)DETECT_R2) << 1) |
((u8)DETECT_R3) );
Key_ROW&=0x0f;
if(Key_ROW != 0x0f)
{
colScanningEnter();
Key_COL = (u8)( (((u8)DETECT_C0) << 3) |
(((u8)DETECT_C1) << 2) |
(((u8)DETECT_C2) << 1) |
((u8)DETECT_C3) );
Key_Read = (Key_ROW << 4) | Key_COL;
switch(Key_Read)
{
//第1行
case 0x77: key = 1; break;
case 0x7b: key = 2; break;
case 0x7d: key = 3; break;
case 0x7e: key = 4; break;
//第2行
case 0xb7: key = 5; break;
case 0xbb: key = 6; break;
case 0xbd: key = 7; break;
case 0xbe: key = 8; break;
//第3行
case 0xd7: key = 9; break;
case 0xdb: key = 10; break;
case 0xdd: key = 11; break;
case 0xde: key = 12; break;
//第4行
case 0xe7: key = 13; break;
case 0xeb: key = 14; break;
case 0xed: key = 15; break;
case 0xee: key = 16; break;
default : break;
}
while(Key_COL != 0x0f) //检测到按键松开了
{
Key_COL = (u8)( (((u8)DETECT_C0) << 3) |
(((u8)DETECT_C1) << 2) |
(((u8)DETECT_C2) << 1) |
((u8)DETECT_C3) );
}
return key;
}
}
return 0;
}
KEY.H
#ifndef __KEY_H__
#define __KEY_H__
#include "main.h"
#include "gpio.h"
#define DETECT_R0 HAL_GPIO_ReadPin(ROW0_GPIO_Port,ROW0_Pin)
#define DETECT_R1 HAL_GPIO_ReadPin(ROW1_GPIO_Port,ROW1_Pin)
#define DETECT_R2 HAL_GPIO_ReadPin(ROW2_GPIO_Port,ROW2_Pin)
#define DETECT_R3 HAL_GPIO_ReadPin(ROW3_GPIO_Port,ROW3_Pin)
#define DETECT_C0 HAL_GPIO_ReadPin(COL0_GPIO_Port,COL0_Pin)
#define DETECT_C1 HAL_GPIO_ReadPin(COL1_GPIO_Port,COL1_Pin)
#define DETECT_C2 HAL_GPIO_ReadPin(COL2_GPIO_Port,COL2_Pin)
#define DETECT_C3 HAL_GPIO_ReadPin(COL3_GPIO_Port,COL3_Pin)
u8 KEY_SCAN(void);
#endif
在main中加这个即可。
Key_Value = KEY_SCAN();
if(Key_Value!=0)
printf("%d \r\n",Key_Value);
bug调试
1.不要手碰到矩阵键盘底部,否则一通混乱
2.按键消抖部分
最开始是这样的
rowScanningEnter();
Key_ROW = (u8)( (((u8)DETECT_R0) << 3) |
(((u8)DETECT_R1) << 2) |
(((u8)DETECT_R2) << 1) |
((u8)DETECT_R3) );
Key_ROW&=0x0f;
if(Key_ROW != 0x0f)
{
HAL_Delay(10);
问题就出在这里,延时之后再去判断没有用啊,因为
值没有改变,还是那些,只有再次取值才以实现消抖的功能
if(Key_ROW != 0x0f)
{
colScanningEnter();
Key_COL = (u8)( (((u8)DETECT_C0) << 3) |
(((u8)DETECT_C1) << 2) |
(((u8)DETECT_C2) << 1) |
((u8)DETECT_C3) );
Key_Read = (Key_ROW << 4) | Key_COL;
printf("aaaa:%x\r\n",Key_Read);
rowScanningEnter();
Key_ROW = (u8)( (((u8)DETECT_R0) << 3) |
(((u8)DETECT_R1) << 2) |
(((u8)DETECT_R2) << 1) |
((u8)DETECT_R3) );
Key_ROW&=0x0f;
if(Key_ROW != 0x0f)
{
HAL_Delay(10);
Key_ROW = (u8)( (((u8)DETECT_R0) << 3) |
(((u8)DETECT_R1) << 2) |
(((u8)DETECT_R2) << 1) |
((u8)DETECT_R3) );
Key_ROW&=0x0f;
if(Key_ROW != 0x0f)
{
colScanningEnter();
Key_COL = (u8)( (((u8)DETECT_C0) << 3) |
(((u8)DETECT_C1) << 2) |
(((u8)DETECT_C2) << 1) |
((u8)DETECT_C3) );
Key_Read = (Key_ROW << 4) | Key_COL;
printf("aaaa:%x\r\n",Key_Read);
3.跟上一篇的方法一样的问题是,都不能检测按键同时按下,比如同时按两个,你能在行读取的值中有两个0,列读取的值中,两个0,而且还不固定,这样就无法读取。