用74HC595和74HC165搞定Arduino引脚扩展:手把手教你串并转换与按键扫描
用74HC595和74HC165搞定Arduino引脚扩展手把手教你串并转换与按键扫描在嵌入式开发中微控制器的IO引脚资源常常捉襟见肘。当你的项目需要控制多个LED、读取矩阵键盘或驱动数码管时Arduino有限的引脚数量很快就会成为瓶颈。本文将带你深入理解两种经典的数字逻辑芯片——74HC595串行转并行和74HC165并行转串行通过实际案例演示如何用它们扩展Arduino的IO能力。1. 认识我们的工具74HC595与74HC1651.1 74HC595串行转并行的魔术师74HC595是一款8位串行输入、并行输出的移位寄存器它能将Arduino的3个数字引脚扩展为8个输出引脚。其核心特性包括8位移位寄存器可存储8位二进制数据串行输入(DS)一次一位地接收数据时钟输入(SHCP)控制数据移位的节奏存储寄存器时钟(STCP)将移位寄存器中的数据锁存到输出并行输出(Q0-Q7)同时输出8位数据级联能力多个芯片可串联使用扩展更多输出// 典型引脚连接示例 const int dataPin 8; // DS (14) const int latchPin 9; // STCP (12) const int clockPin 10; // SHCP (11)1.2 74HC165并行转串行的采集专家与74HC595相反74HC165是一款8位并行输入、串行输出的移位寄存器它能将8个输入信号通过串行方式送回Arduino。主要特点8位并行输入(A-H)同时采集8路信号串行输出(Q7)将数据一位一位输出时钟输入(CLK)控制数据移位并行加载(PL)低电平时加载并行数据级联能力多个芯片可串联扩展输入// 典型引脚连接示例 const int loadPin 5; // PL (1) const int clockPin 6; // CLK (2) const int dataPin 7; // Q7 (9)提示两种芯片都采用5V供电与Arduino电压兼容但要注意输出电流限制74HC595每个引脚最大35mA2. 硬件连接与电路设计2.1 74HC595驱动LED阵列让我们构建一个8位LED控制电路将74HC595的VCC接5VGND接地连接Arduino引脚数字8 → DS (14)数字9 → STCP (12)数字10 → SHCP (11)每个输出引脚(Q0-Q7)通过220Ω电阻连接LED正极LED负极接地电平转换注意事项信号类型74HC595输入Arduino输出高电平≥3.15V4.5-5V低电平≤1.35V0-0.5V2.2 74HC165读取按键矩阵构建4x4矩阵键盘读取电路将74HC165的VCC接5VGND接地连接Arduino引脚数字5 → PL (1)数字6 → CLK (2)数字7 → Q7 (9)将16个按键按4行4列排列使用两个74HC165级联分别连接行和列注意按键需加上拉电阻(10kΩ)确保稳定状态3. 软件实现与Arduino代码3.1 74HC595控制LED流水灯void setup() { pinMode(dataPin, OUTPUT); pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT); } void loop() { for(int i 0; i 8; i) { digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, LSBFIRST, 1 i); digitalWrite(latchPin, HIGH); delay(200); } }代码解析latchPin拉低准备数据传输shiftOut()函数发送数据LSBFIRST表示最低位先发送latchPin拉高更新输出循环实现LED流水效果3.2 74HC165读取按键状态byte readShiftRegister() { byte data 0; digitalWrite(loadPin, LOW); delayMicroseconds(5); digitalWrite(loadPin, HIGH); for(int i 0; i 8; i) { data | digitalRead(dataPin) (7 - i); digitalWrite(clockPin, HIGH); delayMicroseconds(1); digitalWrite(clockPin, LOW); } return data; }关键时序参数参数最小值典型值PL脉冲宽度20ns50nsCLK上升/下降时间6ns15ns数据建立时间10ns20ns4. 高级应用与故障排除4.1 多芯片级联技术当需要更多IO时可以级联多个芯片74HC595级联连接第一片的DS接Arduino第一片的Q7接第二片的DS所有芯片共享SHCP和STCP74HC165级联连接第一片的Q7接第二片的SER所有芯片共享CLK和PL只读取最后一片的Q74.2 常见问题与解决方案问题1输出信号不稳定检查电源滤波在VCC和GND间加0.1μF电容确保时钟信号干净缩短连线避免交叉干扰问题2按键读取错误增加去抖动处理if(currentState ! lastState) { lastDebounceTime millis(); } if((millis() - lastDebounceTime) debounceDelay) { if(currentState ! buttonState) { buttonState currentState; } }问题3级联时序错乱降低时钟频率尝试将delayMicroseconds(1)增加到5或10检查芯片使能端(CE)是否正确连接4.3 性能优化技巧使用SPI硬件加速SPI.begin(); SPI.transfer(value); // 替代shiftOut并行更新技术// 准备所有数据后再锁存 digitalWrite(latchPin, LOW); for(int i0; ichipCount; i) { shiftOut(dataPin, clockPin, MSBFIRST, data[i]); } digitalWrite(latchPin, HIGH);中断驱动读取attachInterrupt(digitalPinToInterrupt(buttonPin), readKeys, FALLING);5. 实战项目可编程LED显示板结合两种芯片我们构建一个能显示图案和响应按键的完整系统硬件配置主控Arduino Uno显示8x8 LED矩阵使用2片74HC595输入16键键盘使用2片74HC165系统架构Arduino → 74HC595×2 → LED矩阵 Arduino ← 74HC165×2 ← 键盘矩阵核心代码结构void displayPattern(byte pattern[8]) { for(int row0; row8; row) { digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, ~pattern[row]); // 行数据 shiftOut(dataPin, clockPin, MSBFIRST, 1 row); // 列选择 digitalWrite(latchPin, HIGH); delayMicroseconds(300); // 控制亮度 } } byte readKeypad() { byte rows readShiftRegister(); byte cols readShiftRegister(); return rows | (cols 4); }在调试这类项目时逻辑分析仪是极有价值的工具它能直观显示移位寄存器的时钟和数据信号帮助验证时序是否正确。