【单片机】STM32单片机的矩阵键盘驱动,标准库,无阻塞方式的矩阵键盘读取

原理图:
在这里插入图片描述

从左到右、从上到下,按键是1到16,没有按键返回0:
key.c

#include "key.h"

/* 按键初始化函数 */
void KEY_Init(void) {
    
    
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);                          /* 使能时钟 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;       /* key */
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;                                                        /* 设置成上拉输入 */
    GPIO_Init(GPIOB, &GPIO_InitStructure);                                                                /* 初始化GPIO */

    GPIO_InitStructure.GPIO_Pin =
            GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;                 //LED2-->PC13 端口配置
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         //推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;         //IO口速度为50MHz
    GPIO_Init(GPIOB, &GPIO_InitStructure);                     //根据设定参数初始化PC13


}

#define OUT1 PBout(8)
#define OUT2 PBout(9)
#define OUT3 PBout(10)
#define OUT4 PBout(11)

#define IN1  PBin(12)
#define IN2  PBin(13)
#define IN3  PBin(14)
#define IN4  PBin(15)


u8 read_key(void) {
    
    
    OUT1 = 0, OUT2 = 1, OUT3 = 1, OUT4 = 1;
    if (IN1 == 0) {
    
    
        //while (IN1 == 0);
        return (1);
    } else if (IN2 == 0) {
    
    
        //while (IN2 == 0);
        return (5);
    } else if (IN3 == 0) {
    
    
        //while (IN3 == 0);
        return (9);
    } else if (IN4 == 0) {
    
    
        //while (IN4 == 0);
        return (13);
    }

    OUT1 = 1, OUT2 = 0, OUT3 = 1, OUT4 = 1;
    if (IN1 == 0) {
    
    
        //while (IN1 == 0);
        return (2);
    } else if (IN2 == 0) {
    
    
        //while (IN2 == 0);
        return (6);
    } else if (IN3 == 0) {
    
    
        //while (IN3 == 0);
        return (10);
    } else if (IN4 == 0) {
    
    
        //while (IN4 == 0);
        return (14);
    }

    OUT1 = 1, OUT2 = 1, OUT3 = 0, OUT4 = 1;
    if (IN1 == 0) {
    
    
        //while (IN1 == 0);
        return (3);
    } else if (IN2 == 0) {
    
    
        //while (IN2 == 0);
        return (7);
    } else if (IN3 == 0) {
    
    
        //while (IN3 == 0);
        return (11);
    } else if (IN4 == 0) {
    
    
        //while (IN4 == 0);
        return (15);
    }

    OUT1 = 1, OUT2 = 1, OUT3 = 1, OUT4 = 0;
    if (IN1 == 0) {
    
    
        //while (IN1 == 0);
        return (4);
    } else if (IN2 == 0) {
    
    
        //while (IN2 == 0);
        return (8);
    } else if (IN3 == 0) {
    
    
        //while (IN3 == 0);
        return (12);
    } else if (IN4 == 0) {
    
    
        //while (IN4 == 0);
        return (16);
    }


    return (0); /* 无按键按下 */
}

//非阻塞型读矩阵键盘按键值
u8 read_key_2(u8 mode) {
    
    
    static u8 key_up = 1; //按键按松开标志
    if (mode)key_up = 1;  //支持连按
    if (key_up && (read_key() != 0)) {
    
    
        delay_ms(10); //去抖动
        key_up = 0;
        return (read_key());
    } else if (read_key() == 0)key_up = 1;
		return 0;
}


key.h

#ifndef __KEY_H
#define __KEY_H	 
#include "sys.h"


 
void KEY_Init(void);//IO初始化

u8 read_key(void);  	//按键扫描函数					   
u8 read_key_2(u8 mode);

#endif

main.c调用示例:

void main(void)
{
    
    
    while (1) {
    
    
        delay_ms(5);

        t++;
        if (t > 50) {
    
    
            t = 0;
            LED0=!LED0;
        }

        key=read_key_2(0);
        if(key)
        {
    
    
            process_key(key);
            dis_cnt=0;
            display_str[dis_cnt++]=key/10+'0';
            display_str[dis_cnt++]=key%10+'0';
            display_str[dis_cnt++]=0;
            OLED_P8x16Str(0,2,display_str,0);//正常显示
        }

    }
}

猜你喜欢

转载自blog.csdn.net/x1131230123/article/details/131341592