74HC165芯片介绍

  74HC165 是 8位并行输入串行输出移位寄存器,它是一款高速 CMOS 器件,遵循JEDEC 标准。74HC165 引脚兼容低功耗肖特基TTL(LSTTL)系列。其管脚封装及功能如下:

  1. CLK、CLK INH:74HC165 的时钟输入是一个“或非门” 结构CLK和CLKINH功能是可以等效的可以互换使用的,一般采取相连在一起、上升沿时数据一位一位的串行输出。
  2. A-H:并行数据输入端
  3. SER:为串行输入端、将数据串行进入到寄存器中、在每一个时钟的上升沿向右移动一位,利用这种特性,只要把 QH 输出连接到下一级的 SER 输入既可实现并转串扩展。
  4. QH:串行输出端
  5. Q`H:互补串行输出端
  6. SH/LD:为低电平时并行数据进入移位寄存器中、为高电平时并行数据不能传进移位寄存器。

   当移位/置入控制端(SH/LD)为低电平时,并行数据(A-H)被置入寄存器,而时钟(CLK,CLK INH)及串行数据(SER)均无关。当 SH/LD为高电平时,并行置数功能被禁止。

  CLK 和CLK INK在功能上是等价的,可以交换使用。当CLK和CLK INK有一个为低电平并且SH/LD为高电平时,另一个时钟可以输入。当CLK和CLK INK有一个为高电平时,另一个时钟被禁止。只有在CLK为高电平时CLKINK才可变为高电平。

时序图

  当SH/LD为低电平时74HC165 并行输入口数据存储到寄存器中,要读取该数据只需保证时钟在上升沿时读取即可,如果需要读取8位即一个字节数据,只需要循环8次,先从最高位开始(74HC164 并行口的H就相当于最高位,A为最低位),每读取一次就移1位,在串行数据读取的程序中,通常先移位后读取数据,8次循环后就将一个字节数据读取出来。从时序图中可以看出,74HC165的串行输出与输入正好是对应的,即H-A按高到低位依次输出

硬件设计

  本实验使用到硬件资源如下:

  1. LED模块(D1~D8)
  2. 独立按键模块
  3. 74HC165模块

  74HC165芯片的控制管脚QH、CLK、SH/LD并未直接连接到51单片机的IO上,而是连接到J5端子上。芯片的并口输入端连接在JP2。

软件设计

  本实验要实现的功能是:独立按键K1~K8按下对应控制D1~D8亮

实物接线图
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/**************************************************************************************
实验名称:IO扩展(并转串)实验-74HC165
接线说明:
实验现象:下载程序后,独立按键模块的K1-K8键按下控制对应LED模块D1-D8指示灯
注意事项:
***************************************************************************************/
#include "reg52.h"

typedef unsigned int u16; //对系统默认数据类型进行重定义
typedef unsigned char u8;

//定义74HC165控制管脚
sbit HC165_QH=P1^7; //串行数据输出
sbit HC165_CLK=P1^6;//时钟输入
sbit HC165_SHLD=P1^5;//寄存器存储控制

#define LED_PORT P2 //LED模块控制


/*******************************************************************************
* 函 数 名 : delay_10us
* 函数功能 : 延时函数,ten_us=1时,大约延时10us
* 输 入 : ten_us
* 输 出 : 无
*******************************************************************************/
void delay_10us(u16 ten_us)
{
while(ten_us--);
}

/*******************************************************************************
* 函 数 名 : delay_ms
* 函数功能 : ms延时函数,ms=1时,大约延时1ms
* 输 入 : ten_us
* 输 出 : 无
*******************************************************************************/
void delay_ms(u16 ms)
{
u16 i,j;
for(i=ms;i>0;i--)
for(j=110;j>0;j--);
}

/*******************************************************************************
* 函 数 名 : hc165_read_data(u8 dat)
* 函数功能 : 从74HC165中读取一个字节数据
* 输 入 : 无
* 输 出 : 一个字节数据
*******************************************************************************/
u8 hc165_read_data(void)
{
u8 i=0;
u8 value=0;

HC165_SHLD=0;//SHLD拉低,165并口数据传入到移位寄存器中
delay_10us(5);//短暂延时
HC165_SHLD=1;//SHLD拉高,禁止165并口数据传入到移位寄存器中

for(i=0;i<8;i++)//循环8次读取一个字节
{
value<<=1;//左移1位,先读取的数据是高位,经过8次循环则将第一次读取的位放到字节高位
HC165_CLK=0;//CLK INH为低电平开始读取数据
delay_10us(5);
value|=HC165_QH;
HC165_CLK=1;//上升沿读取数据
delay_10us(5);
}
return value;
}


/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
u8 value=0;

LED_PORT=0xff;//保证LED默认是熄灭的
while(1)
{
value=hc165_read_data();
if(value!=0xff)LED_PORT=value;
}
}

  实验代码比较简单,首先将LED模块控制脚输出高电平,保证LED默认是熄灭状态,然后进入循环,读取74HC165存储器中数据,然后保存到变量value中,从硬件电路中可知,在74HC165并行口中有上拉电阻,所以当按键未按下时,默认输出数据为0XFF,只有当按键按下时不为0XFF。最后将读取的值通过LED模块展示。