使用cube mx配置一下引脚参数
配置GPIOA 0 2 4 6 为行输出,GPPIOA 1 3 5 7 为列输入
在这里就有必要提一下矩阵键盘的工作原理
首先下拉一行然后检测这一行对应的列有没有被拉低,每行都检测一遍就可以知道那些按键被按下,把这些数据记录到一个数组中,查询的话直接查询这个数组,理论上是全键盘无冲突的。但后面我发现并不是这样,先讲讲按键扫描
uint16_t key_scan()
{
uint16_t key_state = 0x0000;
HAL_GPIO_WritePin(GPIOA, KEY_R1_Pin|KEY_R3_Pin|KEY_R2_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, KEY_R0_Pin, GPIO_PIN_RESET);
if(HAL_GPIO_ReadPin(GPIOA,KEY_C0_Pin) == GPIO_PIN_RESET)
key_state |= 0x1;
else
key_state &= ~(0x1);
if(HAL_GPIO_ReadPin(GPIOA,KEY_C1_Pin) == GPIO_PIN_RESET)
key_state |= 0x2;
else
key_state &= ~(0x2);
if(HAL_GPIO_ReadPin(GPIOA,KEY_C2_Pin) == GPIO_PIN_RESET)
key_state |= 0x4;
else
key_state &= ~(0x4);
if(HAL_GPIO_ReadPin(GPIOA,KEY_C3_Pin) == GPIO_PIN_RESET)
key_state |= 0x8;
else
key_state &= ~(0x8);
HAL_GPIO_WritePin(GPIOA, KEY_R0_Pin|KEY_R3_Pin|KEY_R2_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, KEY_R1_Pin, GPIO_PIN_RESET);
if(HAL_GPIO_ReadPin(GPIOA,KEY_C0_Pin) == GPIO_PIN_RESET)
key_state |= 0x10;
else
key_state &= ~(0x10);
if(HAL_GPIO_ReadPin(GPIOA,KEY_C1_Pin) == GPIO_PIN_RESET)
key_state |= 0x20;
else
key_state &= ~(0x20);
if(HAL_GPIO_ReadPin(GPIOA,KEY_C2_Pin) == GPIO_PIN_RESET)
key_state |= 0x40;
else
key_state &= ~(0x40);
if(HAL_GPIO_ReadPin(GPIOA,KEY_C3_Pin) == GPIO_PIN_RESET)
key_state |= 0x80;
else
key_state &= ~(0x80);
HAL_GPIO_WritePin(GPIOA, KEY_R0_Pin|KEY_R1_Pin|KEY_R3_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, KEY_R2_Pin, GPIO_PIN_RESET);
if(HAL_GPIO_ReadPin(GPIOA,KEY_C0_Pin) == GPIO_PIN_RESET)
key_state |= 0x100;
else
key_state &= ~(0x100);
if(HAL_GPIO_ReadPin(GPIOA,KEY_C1_Pin) == GPIO_PIN_RESET)
key_state |= 0x200;
else
key_state &= ~(0x200);
if(HAL_GPIO_ReadPin(GPIOA,KEY_C2_Pin) == GPIO_PIN_RESET)
key_state |= 0x400;
else
key_state &= ~(0x400);
if(HAL_GPIO_ReadPin(GPIOA,KEY_C3_Pin) == GPIO_PIN_RESET)
key_state |= 0x800;
else
key_state &= ~(0x800);
HAL_GPIO_WritePin(GPIOA, KEY_R0_Pin|KEY_R1_Pin|KEY_R2_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, KEY_R3_Pin, GPIO_PIN_RESET);
if(HAL_GPIO_ReadPin(GPIOA,KEY_C0_Pin) == GPIO_PIN_RESET)
key_state |= 0x1000;
else
key_state &= ~(0x1000);
if(HAL_GPIO_ReadPin(GPIOA,KEY_C1_Pin) == GPIO_PIN_RESET)
key_state |= 0x2000;
else
key_state &= ~(0x2000);
if(HAL_GPIO_ReadPin(GPIOA,KEY_C2_Pin) == GPIO_PIN_RESET)
key_state |= 0x4000;
else
key_state &= ~(0x4000);
if(HAL_GPIO_ReadPin(GPIOA,KEY_C3_Pin) == GPIO_PIN_RESET)
key_state |= 0x8000;
else
key_state &= ~(0x8000);
return key_state;
}
这个很简单 就是我上面所说的拉低一行然后检测被拉低的列,用for循环的话就不用写这么多东西了。然后是滤波
uint16_t key_event(uint16_t key_state)
{
#define KEY_STATE_CNT_MAX 10
const uint8_t mode[16] = {0,0,0,1, 1,1,0,1, 1,1,0,0, 1,1,1,1}; //0:取上升沿,1:取高电平
uint16_t key_mode = 0x0000;
static uint8_t key_state_cnt[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
uint8_t i;
for(i=0;i<16;++i)
{
//滤波
if(key_state&(0x1<