51单片机第二讲之按键

单片机按键控制详解:从独立按键到矩阵按键

一、独立按键控制

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. 矩阵按键原理

矩阵按键通过行列交叉的方式连接,可以有效减少引脚占用:

矩阵按键电路1

矩阵按键电路2

2. 矩阵按键扫描原理

采用逐行扫描的方式检测按键:

  1. 将某一行置为低电平,其余行置为高电平
  2. 检测各列的电平状态
  3. 根据行和列的组合确定按下的按键
// 矩阵按键检测函数
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. 模式1:单灯从左向右流动
  2. 模式2:单灯从右向左流动
  3. 模式3:四种特殊效果正序循环
  4. 模式4:四种特殊效果逆序循环

操作指南

  1. 按下按键1启动系统
  2. 按下按键2停止系统
  3. 按下按键3切换到下一个模式
  4. 按下按键4切换到上一个模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值