单片机按键控制详解:从独立按键到矩阵按键
一、独立按键控制
1. 独立按键原理分析
从电路图中可以看出,独立按键的工作原理:
- 按键未按下时:P3口对应的引脚通过上拉电阻保持高电平(1)
- 按键按下时:引脚与GND连接,变为低电平(0)

2. 按键检测引脚对应关系
使用P3_4到P3_7四个引脚来检测四个独立按键:

| 单片机引脚 | 对应按键 |
|---|---|
| P3_4 | 按键1 |
| P3_5 | 按键2 |
| P3_6 | 按键3 |
| P3_7 | 按键4 |
3. 基础按键检测程序
// 头文件
#include <REGX52.H>
// 按键检测函数
unsigned char Key_Read() {
unsigned char temp = 0;
if (P3_4 == 0) temp = 1;
if (P3_5 == 0) temp = 2;
if (P3_6 == 0) temp = 3;
if (P3_7 == 0) temp = 4;
return temp;
}
// 主函数
void main() {
while (1) {
if (Key_Read() == 1) {
P1_0 = 0; // 按键1按下,点亮LED1
} else {
P1_0 = 1; // 按键1松开,熄灭LED1
}
}
}
4. 高级按键检测:边沿触发
在实际应用中,我们经常需要检测按键的按下和释放动作:
// 头文件
#include <REGX52.H>
// 按键检测函数
unsigned char Key_Read() {
unsigned char temp = 0;
if (P3_4 == 0) temp = 1;
if (P3_5 == 0) temp = 2;
if (P3_6 == 0) temp = 3;
if (P3_7 == 0) temp = 4;
return temp;
}
// 全局变量声明
unsigned char Key_Val, Key_Down, Key_Up, Key_Old;
// 主函数
void main() {
while (1) {
// 按键检测与边沿判断
Key_Val = Key_Read(); // 读取当前按键状态
Key_Down = Key_Val & (Key_Val ^ Key_Old); // 检测下降沿(按键按下)
Key_Up = ~Key_Val & (Key_Val ^ Key_Old); // 检测上升沿(按键释放)
Key_Old = Key_Val; // 保存当前状态供下次比较
// 按键动作响应
if (Key_Down == 1) {
P1_0 = 0; // 按键1按下时点亮LED1
}
if (Key_Up == 2) {
P1_1 = 0; // 按键2释放时点亮LED2
}
if (Key_Old == 3) {
P1_2 = 0; // 按键3持续按下时点亮LED3
} else {
P1_2 = 1; // 按键3释放时熄灭LED3
}
}
}
三种触发方式对比:
| 触发方式 | 对应变量 | 说明 |
|---|---|---|
| 下降沿触发 | Key_Down | 按键从松开到按下瞬间触发 |
| 上升沿触发 | Key_Up | 按键从按下到松开瞬间触发 |
| 电平触发 | Key_Old | 按键持续按下时保持触发 |
二、矩阵按键控制
1. 矩阵按键原理
矩阵按键通过行列交叉的方式连接,可以有效减少引脚占用:


2. 矩阵按键扫描原理
采用逐行扫描的方式检测按键:
- 将某一行置为低电平,其余行置为高电平
- 检测各列的电平状态
- 根据行和列的组合确定按下的按键
// 矩阵按键检测函数
unsigned char Matrix_Key_Read() {
unsigned char temp = 0;
// 扫描第一行
P3_0 = 0; P3_1 = 1; P3_2 = 1; P3_3 = 1;
if (P3_4 == 0) temp = 1;
if (P3_5 == 0) temp = 2;
if (P3_6 == 0) temp = 3;
if (P3_7 == 0) temp = 4;
// 扫描第二行
P3_0 = 1; P3_1 = 0; P3_2 = 1; P3_3 = 1;
if (P3_4 == 0) temp = 5;
if (P3_5 == 0) temp = 6;
if (P3_6 == 0) temp = 7;
if (P3_7 == 0) temp = 8;
// 扫描第三行
P3_0 = 1; P3_1 = 1; P3_2 = 0; P3_3 = 1;
if (P3_4 == 0) temp = 9;
if (P3_5 == 0) temp = 10;
if (P3_6 == 0) temp = 11;
if (P3_7 == 0) temp = 12;
// 扫描第四行
P3_0 = 1; P3_1 = 1; P3_2 = 1; P3_3 = 0;
if (P3_4 == 0) temp = 13;
if (P3_5 == 0) temp = 14;
if (P3_6 == 0) temp = 15;
if (P3_7 == 0) temp = 16;
return temp;
}
按键编号对应关系:
1 2 3 4 ← 第一行
5 6 7 8 ← 第二行
9 10 11 12 ← 第三行
13 14 15 16 ← 第四行
三、综合练习:彩灯控制系统
1. 系统功能概述
设计一个包含四种流水灯模式和启停控制的彩灯系统:

2. 按键功能定义
| 按键 | 功能说明 |
|---|---|
| 按键1 | 启动系统 |
| 按键2 | 停止系统 |
| 按键3 | 模式切换(下一个模式) |
| 按键4 | 模式切换(上一个模式) |
3. 完整程序代码
// 头文件
#include <REGX52.H>
#include <INTRINS.H>
// 延时函数
void Delay(unsigned int xms) {
unsigned char data i, j;
while (xms--) {
i = 2;
j = 239;
do {
while (--j);
} while (--i);
}
}
// 独立按键检测函数
unsigned char Key_Read() {
unsigned char temp = 0;
if (P3_4 == 0) temp = 1;
if (P3_5 == 0) temp = 2;
if (P3_6 == 0) temp = 3;
if (P3_7 == 0) temp = 4;
return temp;
}
// 全局变量声明
unsigned int Time = 500; // 流水灯切换时间
unsigned char System_Flag = 1; // 系统运行标志(1-运行,0-停止)
unsigned char mode = 1; // 当前模式(1-4)
unsigned char uLED = 0xFE; // 单灯流动的LED状态
unsigned char LED[4] = { // 四种特殊显示模式
0x7E, // 01111110 - 两端亮中间灭
0xBD, // 10111101 - 间隔亮
0xDB, // 11011011 - 成对亮
0xE7 // 11100111 - 中间亮两端灭
};
unsigned char LED_Count = 0; // 特殊模式显示计数器
// 按键检测相关变量
unsigned char Key_Val = 0, Key_Down = 0, Key_Up = 0, Key_Old = 0;
// 主函数
void main() {
while (1) {
// 按键检测与边沿判断
Key_Val = Key_Read();
Key_Down = Key_Val & (Key_Val ^ Key_Old); // 下降沿检测
Key_Up = ~Key_Val & (Key_Val ^ Key_Old); // 上升沿检测
Key_Old = Key_Val; // 保存当前状态
// 系统运行状态判断
if (System_Flag == 1) {
// 根据当前模式选择显示方式
switch (mode) {
case 1: // 模式1:单灯左移
P1 = uLED;
Delay(Time);
uLED = _crol_(uLED, 1);
break;
case 2: // 模式2:单灯右移
P1 = uLED;
Delay(Time);
uLED = _cror_(uLED, 1);
break;
case 3: // 模式3:特殊模式正序
P1 = LED[LED_Count];
Delay(Time);
LED_Count++;
if (LED_Count > 3) LED_Count = 0;
break;
case 4: // 模式4:特殊模式逆序
P1 = LED[LED_Count];
Delay(Time);
if (LED_Count == 0) LED_Count = 3;
else LED_Count--;
break;
default:
break;
}
} else {
// 系统停止,所有LED熄灭
P1 = 0xFF;
}
// 按键响应处理
if (Key_Down) {
switch (Key_Down) {
case 1: // 按键1:启动系统
System_Flag = 1;
break;
case 2: // 按键2:停止系统
System_Flag = 0;
break;
case 3: // 按键3:切换到下一个模式
mode++;
if (mode > 4) mode = 1;
break;
case 4: // 按键4:切换到上一个模式
mode--;
if (mode < 1) mode = 4;
break;
default:
break;
}
Key_Down = 0; // 清除按键标志
}
}
}
4. 系统功能说明
四种显示模式:
- 模式1:单灯从左向右流动
- 模式2:单灯从右向左流动
- 模式3:四种特殊效果正序循环
- 模式4:四种特殊效果逆序循环
操作指南:
- 按下按键1启动系统
- 按下按键2停止系统
- 按下按键3切换到下一个模式
- 按下按键4切换到上一个模式
1774

被折叠的 条评论
为什么被折叠?



