一、先上代码
matrix_keyboard.c
cpp
/*******************************************************************************
* 矩阵键盘驱动程序
*
* 硬件连接说明:
* ============================================================================
* 矩阵键盘引脚 单片机引脚 说明
* ---------------------------------------------------------------------------
* 行1-行4 P1.0-P1.3 输出,用于扫描
* 列1-列4 P1.4-P1.7 输入,用于检测按键
* ============================================================================
*
* 键盘布局:
* ============================================================================
* 列1 列2 列3 列4
* 行1: 1 2 3 上
* 行2: 4 5 6 下
* 行3: 7 8 9 设置
* 行4: . 0 OK 清除
* ============================================================================
*
* 代码使用说明:
* 1. 在主程序中包含头文件: #include "matrix_keyboard.h"
* 2. 系统初始化时调用 keyboard_init() 初始化键盘
* 3. 使用 keyboard_scan() 扫描键盘获取键值
* 4. 使用 keyboard_get_key() 获取按键(带消抖)
*
* 使用示例代码:
* ============================================================================
* #include "matrix_keyboard.h"
*
* void main(void)
* {
* u8 key;
*
* // 初始化键盘
* keyboard_init();
*
* while(1)
* {
* // 获取按键
* key = keyboard_get_key();
*
* if(key != KEY_NO_PRESS)
* {
* // 处理按键
* switch(key)
* {
* case KEY_1: // 处理数字1
* break;
* case KEY_UP: // 处理上键
* break;
* // ... 其他按键处理
* }
* }
*
* delay_ms(10); // 适当延时
* }
* }
* ============================================================================
*
* 注意事项:
* 1. P1口需要配置为推挽输出模式
* 2. 扫描频率不宜过高,建议10-20ms扫描一次
* 3. 键值范围: 0-16 (0表示无按键)
* 4. 支持按键消抖和按键释放检测
******************************************************************************/
#include "matrix_keyboard.h"
/*******************************************************************************
* 函数名: delay_ms
* 功能: 毫秒级延时(内部使用)
* 参数: ms - 延时的毫秒数
* 返回值: 无
* 说明: 该函数为内部函数,用于按键消抖
******************************************************************************/
static void delay_ms(int ms)
{
int i, j;
for(i = 0; i < ms; i++)
for(j = 0; j < 110; j++);
}
/*******************************************************************************
* 函数名: keyboard_init
* 功能: 初始化矩阵键盘
* 参数: 无
* 返回值: 无
* 说明: 配置键盘端口为初始状态
* 设置P1口为高电平,准备扫描
* 使用示例:
* keyboard_init(); // 初始化键盘
******************************************************************************/
void keyboard_init(void)
{
KEYBOARD_PORT = 0xFF; // 设置所有引脚为高电平
}
/*******************************************************************************
* 函数名: keyboard_scan
* 功能: 扫描矩阵键盘
* 参数: 无
* 返回值: u8 - 键值 (0表示无按键,1-16表示对应按键)
* 说明: 逐行扫描检测按键,返回检测到的键值
* 该函数不包含消抖,建议使用 keyboard_get_key()
* 使用示例:
* u8 key = keyboard_scan(); // 扫描键盘
* if(key != KEY_NO_PRESS) {
* // 有按键按下
* }
******************************************************************************/
unsigned char keyboard_scan(void)
{
unsigned char key_value = 0;
unsigned char row, col;
// 设置行线为输出,列线为输入
KEYBOARD_PORT = COL_MASK; // 1111 0000
if((KEYBOARD_PORT & COL_MASK) != COL_MASK) { // 有按键按下
// 逐行扫描
for(row = 0; row < 4; row++) {
// 将当前行置低,其他行置高
KEYBOARD_PORT = ~(1 << row) | COL_MASK;
// 检查列
if((KEYBOARD_PORT & 0x10) == 0) col = 0; // 第1列
else if((KEYBOARD_PORT & 0x20) == 0) col = 1; // 第2列
else if((KEYBOARD_PORT & 0x40) == 0) col = 2; // 第3列
else if((KEYBOARD_PORT & 0x80) == 0) col = 3; // 第4列
else continue;
// 计算键值
key_value = row * 4 + col + 1; // 键值从1开始
break;
}
}
return key_value;
}
/*******************************************************************************
* 函数名: keyboard_get_key
* 功能: 获取按键值(带消抖)
* 参数: 无
* 返回值: u8 - 键值 (0表示无按键,1-16表示对应按键)
* 说明: 包含按键消抖和按键释放检测
* 只有在按键释放后才返回键值,避免重复触发
* 使用示例:
* u8 key = keyboard_get_key(); // 获取按键
* if(key != KEY_NO_PRESS) {
* // 处理按键
* }
******************************************************************************/
unsigned char keyboard_get_key(void)
{
unsigned char key_value = 0;
// 扫描键盘
key_value = keyboard_scan();
if(key_value != KEY_NO_PRESS) { // 有按键按下
// 消抖延时
delay_ms(10);
// 再次扫描确认
if(keyboard_scan() == key_value) { // 确认按键按下
// 等待按键释放
while(keyboard_scan() != KEY_NO_PRESS);
// 再次消抖
delay_ms(10);
return key_value;
}
}
return KEY_NO_PRESS;
}
matrix_keyboard.h
cpp
#ifndef __MATRIX_KEYBOARD_H__
#define __MATRIX_KEYBOARD_H__
#include <reg52.h>
//typedef unsigned char u8;
//typedef unsigned int u16;
// 矩阵键盘端口定义
#define KEYBOARD_PORT P1
#define ROW_MASK 0x0F // 行掩码 (P1.0-P1.3)
#define COL_MASK 0xF0 // 列掩码 (P1.4-P1.7)
// 键值定义
#define KEY_1 1 // 数字键1
#define KEY_2 2 // 数字键2
#define KEY_3 3 // 数字键3
#define KEY_UP 4 // 上键
#define KEY_4 5 // 数字键4
#define KEY_5 6 // 数字键5
#define KEY_6 7 // 数字键6
#define KEY_DOWN 8 // 下键
#define KEY_7 9 // 数字键7
#define KEY_8 10 // 数字键8
#define KEY_9 11 // 数字键9
#define KEY_SET 12 // 设置键
#define KEY_DOT 13 // 小数点
#define KEY_0 14 // 数字键0
#define KEY_OK 15 // 确认键
#define KEY_CLEAR 16 // 清除键
// 键盘状态
#define KEY_NO_PRESS 0 // 无按键按下
// 函数声明
void keyboard_init(void);
unsigned char keyboard_scan(void);
unsigned char keyboard_get_key(void);
#endif
二、硬件连接说明
模块和硬件的连接方式
Px0-》R1,
PX1->R2
PX2->R3
PX3->R4
PX4->C1
PX5->C2
PX6->C3
PX7->C4

如果自己画电路图
PX0开始接第一行
PX4开始接第一列
三、代码用法
调用函数eyboard_get_key(); 可返回按下的按键数值,16个按键从左上到右下分别为1-16,第一行1-4,按键具体功能据需要自定义了。比如提供的代码中宏定义
#define KEY_UP 4 // 上键
那么就是4号按键代表"上"