【MCU51&74HC165】使用74HC165移位寄存器实现矩阵键盘的扫描

【MCU51&74HC165】使用74HC165移位寄存器实现矩阵键盘的扫描

前述

在闲暇的时候逛B站发现某UP使用了移位寄存器实现1*N矩阵键盘,就想着蛮简单的自己也动手弄一弄才发现踩的坑还挺多的。

今天就从图的设计到程序的编写来实现

今天所使用的单片机型号是MCU51,至于为什么不用STM32等其他主流主控芯片。因为懒的配置GPIO。直接修改寄存器就好了。但是其他单片机也是一样的方法

需要准备的工具

Proteus主要用于仿真

Keil5主要用于开发编写程序

74HC165芯片手册

芯片手册分析

打开芯片手册就可以直接的看到芯片的基本功能

该芯片工作电压在2v ~ 6v

并行输入转串行输出

主要应用在 视频的驱动,输出扩展,和今天要做的矩阵键盘

内部逻辑图

从图中可以看出使用的是RS锁存器进行数据的存储

前面的了解一下即可,重要的还是芯片的管脚

可以从下图看到每个管脚对应的作用

A-G:并行输入端

SER:串行输入端

Qh:串行输出端

Vcc:电源

GND:地线

CLK:时钟信号

芯片的真值表也是很重要的

真值表可以让我们编写程序来操作芯片工作

仿真部分

仿真使用的是Proteus,从芯片手册可以看到如果需要使用时钟上升沿当作移位信号那么CLK INH就直接接地即可。下面是Proteus的连接

画叉叉的地方就是一个多输出端的电阻

这里我将两个芯片级联了,达到扩展16个输入端。还可以不断级联扩展并且还是只需要3根线也就是说不管级联多少都只需要3个IO口读取数据

上面那个芯片的Qh连接到了P10口,P10就是数据的输入主要用来扫描寄存器里的数据

根据真值表,两个INH连接地线即可,用于配合工作

SH/LD非是用来控制输入还是移位,连接到了P12

CLK用于控制操作芯片工作,连接到了P11

最上面的示波器只是为了方便我们分析程序找出问题

程序编写

引入头文件和定义宏用于后面方便移植

12345678#include #define SH_LD P1_2#define CLK P1_1#define OUT P1_0typedef unsigned int u16;typedef unsigned char u8;

主要部分,扫描键盘输入

123456789101112131415161718192021222324u16 KEY_Scan(void){ u8 i; u16 key; key = 0; CLK = 1; //Set clock to 1 SH_LD = 0; //Read input SH_LD = 1; // Stop reead input key |= OUT; for(i=0;i<15;i++){ CLK = 0; // Set clock to 0 to read data CLK = 1; // Set clock to 1 to prefer next scan for data key <<= 1; key |= OUT; } CLK = 0; return key;}

代码逻辑

置时钟为高电平

根据真值表设置SH/LD非获取用户输入的数据

将数据锁起来,停止用户输入

获取最高位数据存放到key中

循环依次获取每个寄存器的值放到key中,每循环一次左移1是为了不让后面的数据把当前数据替换掉。CLK = 0,CLK = 1是为了产生一个上升沿的信号

最后停止芯片的时钟

返回key,key存放的就是用户输入键盘的状态每一个比特位为一个按键的状态

这里key我使用了一个u16的数据类型是因为刚好有16个按键,每个按键的状态刚好对应了每一位比特位

如果是要扩展32个按键可以使用unsigned long要是64个按键或更多按键可以使用一个unsigned long的数组存放

主函数,对按键状态取反是因为由于按键是低电平有效,反转后变成到高电平有效方便后期处理

123456789101112int main(void){ while(1){ u16 key = ~KEY_Scan(); u8 num = KeyToNum(key); if (num != -1) LED_ShowNum(num); Delayms(10); }}

完整代码

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980#include #define SH_LD P1_2#define CLK P1_1#define OUT P1_0typedef unsigned int u16;typedef unsigned char u8;void Delayms(unsigned char x) //@12.000MHz{ unsigned char i, j; do{ i = 2; j = 239; do { while (--j); } while (--i); } while(--x);}void LED_ShowNum(u8 num){ u8 i,j; i = num / 10; j = num % 10; P2 &= 0; P2 |= j; P2 <<= 4; P2 |= i;}u16 KEY_Scan(void){ u8 i; u16 key; key = 0; CLK = 1; //Set clock to 1 SH_LD = 0; //Read input SH_LD = 1; // Stop reead input key |= OUT; for(i=0;i<15;i++){ CLK = 0; // Set clock to 0 to read data CLK = 1; // Set clock to 1 to prefer next scan for data key <<= 1; key |= OUT; } CLK = 0; return key;}u8 KeyToNum(u16 key){ u8 i; for(i=0;i<16;i++) if (((key >> i) & 0x01) == 0x01) return i+1; return -1;}int main(void){ while(1){ u16 key = ~KEY_Scan(); u8 num = KeyToNum(key); if (num != -1) LED_ShowNum(num); Delayms(10); }}

相关推荐

陈嘉明:我们为什么不能独立地发现新现象,提出新问题
日锻月炼的意思

日锻月炼的意思

01-30 👁️ 6939
2023年女足世界杯海报插画图片素材
河北科技大学是一本还是二本学校?是几本?在全国排名多少名?
为什么黑坑禁用红虫,老板说红虫会污染水质,其实这才是根本原因
QQ飞车机甲车多少钱?不同型号价格对比!
照片排版看板软件有哪些
PS、PE、PP、PVC、ABS、POM、PA尼龙、PET性能、注塑温度
揭秘天文奇观,为什么有的星月没有月?