尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

深入解析:51单片机基础-IO扩展(并转串 74HC165)

深入解析:51单片机基础-IO扩展(并转串 74HC165)
📅 发布时间:2026/6/19 21:20:43

深入解析:51单片机基础-IO扩展(并转串 74HC165)

第二十二章 IO扩展(并转串 74HC165)

1. 导入

上一章用 74HC595 实现“串→并”输出来扩展LED等。本章介绍与之互补的“并→串”输入扩展芯片 74HC165。它能把多路并行输入(如开关、按键、光耦量)用极少的MCU引脚串行读回,常与 74HC595 搭配实现“少线控多I/O”。

目标:

  • 理解 74HC165 引脚与装载/移位时序。
  • 连接单片机,读取 8/16/32 路输入。
  • 实现消抖与稳定扫描,打印或控制逻辑。
  • 了解多片级联、与 SPI 的配合技巧。

2. 硬件设计

2.1 74HC165 引脚速览(并转串)

  • D0~D7:8路并行输入(通常接按键/开关,建议上拉或下拉确定默认电平)
  • SH/LD(或 /PL):并行装载,低有效
  • CLK(CP):移位时钟,上升沿移位
  • CLK INH(CE):时钟禁止,高电平禁止移位,常接地(0)以使能
  • Q7:串行输出(接MCU输入)
  • Q7’:串行输出的反相信号,同时用于多片级联的串行输入(接下一片的SER)

常用接法建议:

  • 多数输入为“按下=低”,则每路输入加上拉电阻(到VCC,10kΩ左右),按键另一端接GND。
  • CLK INH 直接接GND(启用时钟);若要“冻结”移位可接MCU控制。
  • 多片级联:前一片 Q7’ 接后一片 SER;CP、SH/LD 并联。

2.2 与 51 单片机连接示例

以 P1.0~P1.2 控制:

  • P1.0 ← Q7(数据输入,MCU读)
  • P1.1 → CLK(时钟输出)
  • P1.2 → SH_LD(并装,低有效)
  • CLK INH → GND(常使能)
  • D0~D7 → 8个按键(到GND),每路10k上拉至VCC

两片级联(16路):

  • 第1片 Q7’ → 第2片 SER
  • 时钟、装载线并联到两片
  • 读取时得到16位数据,先出的是“最后一级”的最高位(注意位序,代码处理)

3. 时序与读取流程

  • 并行装载:保持 CLK=0,将 SH/LD 拉低≥t_w,芯片把 D0~D7 锁存到移位寄存器。
  • 移位输出:将 SH/LD 拉高,之后每个 CLK 上升沿把数据向 Q7 移一位。
  • 读法建议(稳妥顺序):
    1. 置 CLK=0;
    2. SH/LD=0(装载)→ 短延时 → SH/LD=1;
    3. 循环8次:先读 Q7,再 CLK 上升沿→下降沿,进入下一位。

说明:首次读取的 Q7 对应 D7(常见版本),随后依次 D6…D0。


4. 软件实现(C51)

4.1 引脚与基础延时

#include <reg52.h>#include <intrins.h>sbit HC165_DATA = P1^0;   // Q7 → MCU输入sbit HC165_CLK  = P1^1;   // CP 时钟sbit HC165_LD   = P1^2;   // SH/LD(低有效并装)static void tiny_delay(void) { _nop_(); _nop_(); _nop_(); _nop_(); }void delay_ms(unsigned int ms){unsigned int i,j;for(i=0;i<ms;i++) for(j=0;j<125;j++);}

4.2 读8位(1片 74HC165)

// 读取1片(8位),返回bit7..bit0(bit7是D7)
unsigned char hc165_read8(void)
{
unsigned char i, val = 0;
HC165_CLK = 0;         // 保证时钟低
HC165_LD  = 0;         // 并装
tiny_delay();
HC165_LD  = 1;         // 转换为移位模式
tiny_delay();
for (i = 0; i < 8; i++) {
// 先读当前Q7
val <<= 1;
if (HC165_DATA) val |= 0x01;
// 再移位到下一位
HC165_CLK = 1; tiny_delay();
HC165_CLK = 0; tiny_delay();
}
return val;
}

4.3 读16位(2片级联)

// 读取2片级联(16位):高字节为“后级”那片
unsigned int hc165_read16(void)
{
unsigned char i;
unsigned int val = 0;
HC165_CLK = 0;
HC165_LD  = 0; tiny_delay();  // 并装两片
HC165_LD  = 1; tiny_delay();
for (i = 0; i < 16; i++) {
val <<= 1;
if (HC165_DATA) val |= 0x0001;
HC165_CLK = 1; tiny_delay();
HC165_CLK = 0; tiny_delay();
}
return val; // bit15..bit0
}

说明:

  • 具体“哪片是高字节”取决于Q7’链路方向与布局,若与你的板卡相反,交换高低字节或在循环内倒序组装即可。
  • 若你的按键为“按下=低电平”,读回位为0表示被按,后续逻辑可按需取反。

4.4 消抖与稳定检测

简易两次一致法:

// 读取并简单消抖:两次一致才认定
unsigned char hc165_read8_debounced(void)
{
unsigned char a = hc165_read8();
delay_ms(5);
unsigned char b = hc165_read8();
return (a == b) ? a : 0xFF;  // 0xFF表示抖动/不稳定(按下=低时)
}

更稳妥可读N次做“多数票”或状态机消抖(按需扩展)。


5. 应用示例

5.1 示例A:8按键 → 串口打印键值(按下为低)

// 串口初始化(9600bps)
void uart_init(void){
TMOD |= 0x20; TH1=0xFD; TL1=0xFD; TR1=1;
SCON = 0x50; EA=1; ES=0;
}
void uart_putc(char c){ SBUF=c; while(!TI); TI=0; }
void uart_puts(const char* s){ while(*s) uart_putc(*s++); }
void uart_put_hex8(unsigned char v){
const char hx[]="0123456789ABCDEF";
uart_putc(hx[(v>>4)&0xF]); uart_putc(hx[v&0xF]);
}
void main(){
unsigned char last = 0xFF; // 默认全高(未按)
uart_init();
uart_puts("74HC165 Key Scan Start\r\n");
while(1){
unsigned char cur = hc165_read8_debounced(); // 低=按下
if (cur != 0xFF && cur != last) {
uart_puts("KEYS=0x"); uart_put_hex8(cur); uart_puts("\r\n");
last = cur;
}
}
}
  • 若 D0 对应“最右键”,当按下它时 KEYS 的最低位变为0。
  • 需要“哪个键被按下”的索引,可遍历每一位检测从1→0的边沿。

5.2 示例B:16按键(2片)→ 亮灭板载LED

假设某位被按下(读到0)则翻转 P1.7 指示灯:

sbit LED = P1^7;
void main(){
unsigned int last = 0xFFFF;
LED = 1;
while(1){
unsigned int cur = hc165_read16();
// 简单消抖
delay_ms(5);
if (cur == hc165_read16() && cur != last){
// 任一位从1→0代表有新按下
unsigned int changed = (last ^ cur);
unsigned int pressed = changed & (~cur); // 由1变0
if (pressed) {
LED = !LED;
}
last = cur;
}
}
}

6. 与 74HC595 组合(节省I/O的键盘面板)

  • 用 74HC595 驱动行/列(或LED显示),用 74HC165 读入另一维的键值,MCU端只占 5~6 根线即可实现“显示+按键输入”面板。
  • 扫描流程:通过 595 逐列输出(1列为有效),经 165 读回行线状态;列→行的机械按键仍需消抖。
  • 注意时序:行切换与行稳定之间加短延时;避免显示切换引入的串扰影响读取。

7. SPI方式的小技巧

若MCU具备 SPI 外设:

  • 将 Q7 → MISO,CP → SCK(模式0),SH/LD 用GPIO控制,CLK INH 接GND。
  • 读流程:SH/LD=0→1 后,发出 8(或16/24/32)个SCK,并在 SPI 接收缓冲中取回数据,吞掉发送字节(一般发0x00)。
  • 这样可显著减轻软件位操作负担,提高采样速率与稳定性。

8. 常见问题与排查

  • 读值抖动/随机:
    • 输入悬空:务必上拉/下拉;线长用更小阻值或加RC滤波。
    • 时序不当:装载/移位时保证 CLK 在规范状态,读Q7与打时钟的先后顺序一致。
  • 位序与预期相反:
    • 74HC165 默认 Q7 先出 D7,若你希望D0在最低位,代码里倒序装配或硬件交换 D0…D7。
  • 级联顺序混乱:
    • 确保 Q7’ → SER 串接方向正确;读多位时对应地高位/低位拼装。
  • 多片干扰:
    • 共地良好、去耦靠近芯片、CLK/SH/LD 线尽量短且加小电阻串联阻尼(如33~100Ω)以抑制过冲。

9. 小结

  • 74HC165 提供“并→串”输入扩展,极大节省 MCU 引脚,适合多按键、多开关回读。
  • 掌握了装载与移位时序、单片/级联读取、基础消抖与应用示例。
  • 与 74HC595 组合可形成“少线多I/O”的整机面板输入输出方案;有 SPI 更佳。

相关新闻

  • 实用指南:如何在 React 中实现键盘快捷键管理器以提升用户体验
  • 2025年十大GEO源头厂家口碑排行榜,南方网通GEO源头厂
  • 修正开源控件kcontrols不能在linux使用中文输入法的bug

最新新闻

  • 全国学历提升继续教育学习体验实录
  • 验证码绕过实战:从Pikachu靶场剖析客户端与服务端漏洞原理
  • Mission Planner终极指南:5步掌握开源无人机地面站专业飞行控制
  • Gemini大模型系列技术解析与真实能力边界
  • 修复kkFileView XSS漏洞与POI文件预览兼容性问题实战
  • 弱监督学习与概率提示技术在3D目标检测中的应用

日新闻

  • 5分钟掌握Python进化算法:Geatpy高性能优化工具完全指南
  • Microchip 24AA044 EEPROM选型与应用全指南:从参数解析到实战编程
  • 华为的鸿蒙到底有多牛?为什么称作遥遥领先?

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号