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