蓝桥杯单片机组备赛指南·第二讲 -按键
·
蓝桥杯单片机组备赛指南·第二讲 -按键
按键检测全攻略:独立按键 + 矩阵按键(省赛、国赛常考模块)
继第一讲掌握LED与流水灯后,本讲我们正式进入“输入”环节。
蓝桥杯单片机组近5年真题中,按键模块出现率接近100%,独立按键+矩阵按键组合更是高频考点。学完本讲,你将彻底解决按键抖动、误触发、矩阵漏键三大难题,为后续数码管、定时器、综合系统题打下最扎实基础。
一、独立按键详解
1. 硬件原理
独立按键采用上拉结构:
- 未按下 → 引脚通过上拉电阻保持高电平(1)
- 按下 → 引脚直接接地,变为低电平(0)
| 单片机引脚 | 对应按键 |
|---|---|
| P3_4 | 按键1 |
| P3_5 | 按键2 |
| P3_6 | 按键3 |
| P3_7 | 按键4 |
2. 基础电平检测(最简版)
#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; //松开熄灭
}
}
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;
}
// 全局变量
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 = ~P1_0; // 按键1每按一次翻转LED1
if(Key_Down == 2) P1 = 0x00; // 按键2按下八灯全亮
if(Key_Down == 3) P1 = 0xFF; // 按键3按下八灯全灭
}
}
三种触发方式总结:
| 触发方式 | 变量 | 触发时机 | 典型应用 |
|---|---|---|---|
| 下降沿 | Key_Down | 松开→按下瞬间 | 切换、计数 |
| 上升沿 | Key_Up | 按下→松开瞬间 | 确认、保存 |
| 电平触发 | Key_Val/Key_Old | 持续按下期间 | 长按加速、保持 |
二、4×4 矩阵按键详解
1. 按键编号对应关系
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
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; // 0表示无按键
}
三、综合实战:按键控制四模式流水灯
#include <REGX52.H>
#include <INTRINS.H>
// 延时函数(原样保留)
void Delay(unsigned int xms)
{
unsigned char 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, 0xBD, 0xDB, 0xE7}; // 四种特殊显示模式
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;
}
}
else
{
// 系统停止,所有LED熄灭
P1 = 0xFF;
}
// 按键响应处理
if(Key_Down)
{
switch(Key_Down)
{
case 1: System_Flag = 1; break; // 按键1:启动系统
case 2: System_Flag = 0; break; // 按键2:停止系统
case 3: mode++; if(mode > 4) mode = 1; break; // 按键3:下一个模式
case 4: mode--; if(mode < 1) mode = 4; break; // 按键4:上一个模式
}
}
}
}
}
功能说明:
- 按键1 → 启动系统
- 按键2 → 停止系统(全灭)
- 按键3 → 下一模式(1→2→3→4→1)
- 按键4 → 上一模式(1→4→3→2→1)
四、本讲总结
| 模块 | 关键技巧 |
|---|---|
| 独立按键 | 4路if + 边沿触发 |
| 矩阵按键 | 逐行拉低行线检测列线 |
| 防抖与消抖 | 边沿检测最优,其次软件延时 |
| 综合系统设计 | 模式切换 + 启停控制 |
所有代码均已实板验证,可直接复制用于训练与比赛。
继续加油,蓝桥杯我们一起拿下!
更多推荐

所有评论(0)