51单片机基础-独立按键

第七章 独立按键

1. 导入

在前几章中,我们学习了单片机的输出控制,包括LED、蜂鸣器和数码管。本章将引入输入设备 ------独立按键,实现人机交互的基本功能。

独立按键是最简单的输入装置,广泛应用于各种嵌入式系统中。通过本章学习,你将掌握:

  • 按键的硬件连接与消抖原理;
  • 如何检测按键按下与释放;
  • 实现按键控制LED、数码管等输出设备;
  • 编写可靠的按键检测函数;
  • 为后续学习矩阵键盘、中断按键打下基础。

2. 硬件设计

2.1 按键工作原理

按键是一个机械开关,按下时导通,松开时断开。但在机械接触瞬间会产生抖动(Bounce),导致电平快速变化,可能被误判为多次按下。

2.2 硬件消抖

最简单的消抖方式是使用RC滤波电路,但教学中常用软件消抖,成本低、灵活性高。

2.3 按键连接方式

典型电路(共4个独立按键):
  • 按键一端接地(GND);
  • 另一端接单片机I/O口(如P3.0);
  • I/O口内部或外部接上拉电阻(10kΩ),使未按下时为高电平。

51单片机P0、P1、P2口有弱上拉,P3口也有上拉能力,可直接使用。

引脚分配示例:
按键 连接引脚 功能
K1 P3.0 启动/停止
K2 P3.1 加1
K3 P3.2 减1
K4 P3.3 模式切换

注意:P3.2和P3.3也可用于外部中断,后续可扩展。


3. 软件设计

3.1 按键检测原理

  • 未按下:I/O口为高电平(上拉);
  • 按下:I/O口被拉低,为低电平;
  • 检测到低电平 → 可能按下 → 延时消抖 → 再次检测 → 确认按下。

3.2 简单按键检测函数

c 复制代码
#include <reg52.h>

sbit KEY1 = P3^0;
sbit KEY2 = P3^1;

// 延时函数
void delay_ms(unsigned int ms) {
    unsigned int i, j;
    for (i = 0; i < ms; i++)
        for (j = 0; j < 125; j++);
}

// 检测按键是否按下(返回1:按下,0:未按下)
unsigned char key_press(sbit key) {
    if (key == 0) {           // 电平为低,可能按下
        delay_ms(10);         // 软件消抖延时
        if (key == 0) {       // 仍为低,确认按下
            while(key == 0);  // 等待释放(防止重复触发)
            return 1;
        }
    }
    return 0;
}

说明:while(key == 0)用于等待按键释放,避免一次按下触发多次。


3.3 按键控制LED

实现:按下K1,LED状态翻转。

c 复制代码
sbit LED = P1^0;
sbit KEY1 = P3^0;

void main() {
    while(1) {
        if (key_press(KEY1)) {
            LED = ~LED;  // 翻转LED状态
        }
    }
}

3.4 多按键检测

c 复制代码
unsigned char key_scan() {
    if (P3 == 0xFE) {  // K1按下(P3.0=0,其余=1)
        delay_ms(10);
        if (P3 == 0xFE) {
            while(P3 != 0xFF);  // 等待释放
            return 1;
        }
    }
    else if (P3 == 0xFD) { // K2按下(P3.1=0)
        delay_ms(10);
        if (P3 == 0xFD) {
            while(P3 != 0xFF);
            return 2;
        }
    }
    return 0;
}

优点:可同时检测多个按键状态;缺点:占用P3口全部引脚。


3.5 按键控制数码管数字增减

目标:K2加1,K3减1,数码管显示当前值。

c 复制代码
#include <reg52.h>

sbit KEY_ADD = P3^1;
sbit KEY_SUB = P3^2;

unsigned char code seg_code[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
unsigned char num = 0;

void delay_ms(unsigned int ms) {
    unsigned int i, j;
    for (i = 0; i < ms; i++)
        for (j = 0; j < 125; j++);
}

void display_digit(unsigned char n) {
    P0 = seg_code[n];
    P2 = 0x0E;  // 选中第一位数码管
    delay_ms(5);
}

void key_action() {
    if (KEY_ADD == 0) {
        delay_ms(10);
        if (KEY_ADD == 0) {
            num++;
            if (num > 9) num = 0;
            while(KEY_ADD == 0);
        }
    }
    if (KEY_SUB == 0) {
        delay_ms(10);
        if (KEY_SUB == 0) {
            num--;
            if (num > 9) num = 9;  // 防止溢出(无符号数)
            while(KEY_SUB == 0);
        }
    }
}

void main() {
    while(1) {
        key_action();
        display_digit(num);
    }
}

说明:num--后若为-1,无符号数变为255,故用 if(num > 9) num = 9; 拦截。


3.6 支持长按功能(扩展)

c 复制代码
void key_long_press() {
    static unsigned char count = 0;
    if (KEY_ADD == 0) {
        delay_ms(10);
        if (KEY_ADD == 0) {
            count++;
            if (count >= 50) {  // 长按500ms
                num++;          // 连续加
                count = 40;     // 控制加速度
            }
        }
    } else {
        count = 0;
    }
}

可结合定时器实现更精准长按检测。


3.7 编译与下载

  • Keil中创建工程;
  • 确认按键与I/O连接正确;
  • 编译生成HEX文件;
  • 下载至单片机;
  • 按下按键,观察LED或数码管是否响应。

若无响应:

  • 检查按键是否接地;
  • 确认上拉电阻存在;
  • 测量按下时引脚是否为低电平。

##4. 小结

本章通过引入独立按键,实现了人机交互的基本功能,主要内容包括:

  • 硬件连接:掌握按键的上拉接法与消抖电路设计;
  • 软件检测:编写可靠的按键检测函数,支持单击、消抖、等待释放;
  • 应用实例:实现按键控制LED翻转、数码管数字增减;
  • 扩展功能:支持多按键识别与长按操作;
  • 开发流程:完成输入-处理-输出的完整闭环。

4.1 常见问题与解决

问题 原因 解决方法
按键无反应 未接上拉电阻、接地不良 检查电路,确保默认高电平
误触发多次 消抖不充分 增加延时或改进检测逻辑
按键卡死 未等待释放 加入while(key == 0)等待松手
数码管闪烁 显示时间过长 缩短display_digit延时至1~2ms

4.2 下一步学习建议

  • 学习外部中断,实现按键快速响应;
  • 设计矩阵键盘,节省I/O资源;
  • 结合定时器,实现非阻塞按键扫描;
  • 应用于电子钟、密码锁等综合项目。

本章标志着你已掌握基本输入能力,下一章将进入定时器/计数器模块的深入学习,实现精准时间控制与中断响应。


相关推荐
无畏jh17 小时前
TLE5012B磁阻芯片解读
嵌入式硬件·汽车嵌入式·磁阻芯片
培林将军17 小时前
Altium Designer 22的安装与汉化
嵌入式硬件·ad工具安装
idcardwang17 小时前
xl9555-IO拓展芯片
stm32·单片机·嵌入式硬件
Y1rong18 小时前
STM32之EXTI
stm32·单片机·嵌入式硬件
兆龙电子单片机设计18 小时前
【STM32项目开源】STM32单片机智能语音家居控制系统
stm32·单片机·嵌入式硬件·物联网·开源·自动化
TaidL18 小时前
茂捷M1020电感式编码器芯片赋能工业智能升级,适用于工业及机器人等领域的各种应用场景
单片机·嵌入式硬件
意法半导体STM3218 小时前
【官方原创】SAU对NSC分区的影响 LAT1578
stm32·单片机·嵌入式硬件·mcu·信息安全·trustzone·stm32开发
SmartRadio18 小时前
MK8000(UWB射频芯片)与DW1000的协议适配
c语言·开发语言·stm32·单片机·嵌入式硬件·物联网·dw1000
LDR00618 小时前
芯片电路的引脚标识代表什么?
stm32·单片机·嵌入式硬件
恒锐丰小吕19 小时前
屹晶微 EG3116 600V高压、2A/2.5A驱动、双高有效输入逻辑的半桥栅极驱动芯片技术解析
嵌入式硬件·硬件工程