原理图:
从左到右、从上到下,按键是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);//正常显示
}
}
}