首页 LMVE论坛 资讯 插画 时光机 我的社区 用户 搜索

[HAL库]HAL库 矩阵键盘 计数消抖法 与 全键盘无冲突想法

无闻风
发表于 2019-06-27 14:12:08
0
174

使用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<
最后修改 2019-07-07 19:16:05
0
174
用户评论
一起折腾