ESP32 + Arduino 学习笔记:74HC595 移位寄存器与按键检测

一、前言

在嵌入式开发中,常会遇到 I/O 口不够用的情况,74HC595 移位寄存器能帮我们解决这个问题,它可以通过少量 I/O 口控制多个输出设备。同时,按键检测是交互功能的基础,这次就结合 ESP32(用 Arduino 框架),学习 74HC595 用法和按键消抖检测,让你轻松上手硬件交互开发!

二、74HC595 移位寄存器基础

(一)芯片介绍

74HC595 是 8 位串行输入、并行输出的移位寄存器,工作电压 2.2V - 5.5V 。内部有移位寄存器和数据寄存器,串行输入数据逐位移入,最后并行输出,能帮我们节省 ESP32 的 I/O 口,比如用 3 个 I/O 就能控制 8 个输出设备(像数码管、LED 等 )。

(二)引脚功能(常用关键引脚)

引脚标识 功能说明
DS 串行数据输入,往移位寄存器传数据
SH - CP 移位时钟,每来一个上升沿(电平从低变高),数据移一位
ST - CP 锁存时钟,上升沿时,移位寄存器数据送到并行输出寄存器锁存
Q0 - Q7 并行数据输出引脚,连接外部设备(如数码管段选)
VCC、GND 接电源正、负极

(三)工作流程(以控制数码管为例)

  1. 数据串行输入:把要显示的数据(比如数码管段选编码 ),通过 DS 引脚一位一位传进去,配合 SH - CP 上升沿,数据逐位移入移位寄存器。
  2. 数据锁存输出:所有数据移完后,给 ST - CP 一个上升沿,移位寄存器里的数据就会锁存到并行输出寄存器,Q0 - Q7 输出对应电平,控制数码管显示。

三、硬件连接(以控制共阴数码管 + 按键检测为例 )

(一)材料准备

  • ESP32 开发板
  • 74HC595 芯片
  • 共阴数码管
  • 按键、10kΩ 电阻(上拉/下拉用 )
  • 面包板、杜邦线

(二)接线图(简化示意)

  • 74HC595 与 ESP32
    • DS → ESP32 任意 GPIO(如 GPIO14 )
    • SH - CP → ESP32 任意 GPIO(如 GPIO12 )
    • ST - CP → ESP32 任意 GPIO(如 GPIO13 )
    • VCC → ESP32 3.3V 或 5V(看 74HC595 工作电压,一般 3.3V 也可 )
    • GND → ESP32 GND
  • 74HC595 与共阴数码管
    Q0 - Q7 对应连数码管的段选引脚(a - g、dp ),比如 Q0 连 a 段、Q1 连 b 段……
  • 按键与 ESP32
    按键一端接 ESP32 GPIO(如 GPIO34 ),另一端接 GND ,同时在 GPIO 引脚和 3.3V 之间接 10kΩ 上拉电阻(也可用 ESP32 内部上拉,代码里设置 ),这样按键按下时引脚电平变低,松开变高。

四、代码实现(分步讲解 )

(一)基础按键检测(消抖处理 )

先写个简单按键检测代码,包含消抖,让串口打印按键状态。

// 定义按键引脚
const int keyPin = 34;  

void setup() {
  // 设置按键引脚为输入模式,启用内部上拉电阻
  pinMode(keyPin, INPUT_PULLUP);  
  // 初始化串口,波特率 9600
  Serial.begin(9600);  
}

void loop() {
  // 读取按键引脚电平
  int buttonValue = digitalRead(keyPin);  

  // 按键按下时(电平为 LOW ,因为内部上拉,按下接地 )
  if (buttonValue == LOW) {  
    Serial.println("按键按下");
    delay(20);  // 跳过前沿抖动(机械按键按下时电平会抖几下 )
    // 等待按键松开,避免一直触发
    while (digitalRead(keyPin) == LOW) {}  
    delay(20);  // 跳过后沿抖动
    Serial.println("按键松开");
  }

  delay(20);  // 主循环稍作延时,避免太频繁检测
}

代码说明

  • INPUT_PULLUP 启用 ESP32 内部上拉电阻,这样按键没按下时引脚默认是高电平,按下接地变低电平,省了外部上拉电阻。
  • 消抖用了简单的 delay ,实际项目也可用定时器、状态机更高级方法,这里先学基础的。

五、实际调试与拓展

(一)调试注意事项

  1. 硬件接线检查:尤其 74HC595 引脚别接反,VCC、GND 接对,数码管段选和 Q0 - Q7 对应好,不然可能显示乱或者不亮。
  2. 串口调试:打开 Arduino IDE 串口监视器,看按键按下、松开时打印的信息,判断程序逻辑对不对。要是数码管显示异常,检查编码对不对(共阴、共阳编码不同 ),还有 74HC595 工作电压。

(二)拓展玩法

  1. 显示多位数码管:多个 74HC595 级联(把前一个的 Q7’ 接后一个的 DS ),就能控制更多数码管,实现多位数字显示,比如做个简易计数器、时钟。
  2. 按键控制更多功能:除了控制数码管显示数字,还能让按键切换显示内容(数字、字母、符号 ),或者结合 ESP32 蓝牙、WiFi 功能,按键触发发送数据。

六、总结

通过这次学习,你应该掌握了:

  • 74HC595 移位寄存器基本原理和 ESP32 接线、控制方法,能节省 I/O 口扩展输出。
  • Arduino 框架下 ESP32 按键检测(含消抖 ),实现简单交互。
  • 把按键和 74HC595 结合,做出有交互的硬件小实验,后续可以拓展更多创意项目,比如用多个按键控制数码管显示不同内容、做个简易密码锁等等,动手试试吧!

1 条评论

  • @ 2025-7-15 17:05:41

    (二)结合 74HC595 控制数码管显示(以显示数字 8 为例 )

    先给数码管段选编码(共阴数码管,“1” 亮 ),数字 8 对应 0b11111110(二进制 ,a - g 全亮,dp 灭 ,具体看前面数码管编码表 ),然后通过 74HC595 输出控制。

    // 74HC595 引脚定义
    const int dsPin = 14;   // 串行数据输入
    const int shcpPin = 12; // 移位时钟
    const int stcpPin = 13; // 锁存时钟
    
    // 按键引脚
    const int keyPin = 34;  
    
    // 数码管编码(共阴,数字 8 )
    const byte num8 = 0b11111110;  
    
    void setup() {
      // 设置 74HC595 控制引脚为输出
      pinMode(dsPin, OUTPUT);  
      pinMode(shcpPin, OUTPUT);
      pinMode(stcpPin, OUTPUT);
    
      // 按键引脚设置,启用内部上拉
      pinMode(keyPin, INPUT_PULLUP);  
      Serial.begin(9600);
    }
    
    // 往 74HC595 写一个字节数据的函数
    void shiftOutByte(byte data) {
      for (int i = 7; i >= 0; i--) { 
        // 取出第 i 位数据,从高位到低位传
        digitalWrite(dsPin, (data >> i) & 0x01);  
        // 给移位时钟上升沿,数据移位
        digitalWrite(shcpPin, HIGH);  
        digitalWrite(shcpPin, LOW);
      }
      // 给锁存时钟上升沿,数据锁存输出
      digitalWrite(stcpPin, HIGH);  
      digitalWrite(stcpPin, LOW);
    }
    
    void loop() {
      int buttonValue = digitalRead(keyPin);
    
      if (buttonValue == LOW) {
        Serial.println("按键按下,数码管显示 8");
        delay(20);
        while (digitalRead(keyPin) == LOW) {}
        delay(20);
        Serial.println("按键松开");
    
        // 写数据到 74HC595 ,控制数码管显示 8
        shiftOutByte(num8);  
      } else {
        // 按键没按下时,数码管可以灭或者显示其他,这里让它灭(全 0 )
        shiftOutByte(0b00000000);  
      }
    
      delay(20);
    }
    

    代码说明

    • shiftOutByte 函数:循环 8 次,把一个字节数据从高位到低位,通过 dsPin 串行输出,配合 shcpPin 移位时钟,最后用 stcpPin 锁存,让 74HC595 并行输出数据控制数码管。
    • 按键按下时让数码管显示 8 ,松开后可以让数码管灭(传全 0 ),也能改成显示其他数字,自己灵活改编码就行。
    • 1