【Proteus仿真】51单片机74LS164+74LS165扩展 I/O示例

【Proteus仿真】51单片机74LS164+74LS165扩展 I/O示例


  • Proteus仿真
    在这里插入图片描述
  • 74LS164

8位串入、并出移位寄存器.

  • 逻辑图
    8位串入、并出移位寄存器
  • 引脚图
    在这里插入图片描述

引脚功能说明
在这里插入图片描述

  • 74LS165:8位并入、串出移位寄存器

示例程序

使用4片74LS164级联,作I/O扩展输出,共扩展32位;使用4片74LS165级联,作作I/O扩展输入。

实现功能:
  1. 74LS164扩展I/O输出点亮4个数码管;
  2. 74LS165读取扩展I/O引脚状态;
  3. 在LCD1602中同步显示数码管显示的数字。

主程序代码

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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/\*\*
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
74LS164扩展 I/O示例
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\*/

#include <reg52.h> //52系列单片机头文件
#include "delay.h" //延时函数实现头文件
#include "lcd1602.h" //LCD1602实现头文件

sbit LS164_DATA = P0^0; //74LS164数据线
sbit LS164_CLK = P0^1; //74LS164时钟线
sbit LS165_SH_LD = P0^2; //74LS165移位控制线
sbit LS165_DATA = P0^3; //74LS165数据线
sbit LS165_CLK = P0^4; //74LS165时钟线

//7段共阳极数码管段码,0~f,不带小数点
unsigned char tube[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};
unsigned char LED_Num[4]={0,0,0,0}; //存储4个数码管显示的数字

/\*\*
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\* 函 数:74LS164写32位扩展引脚函数
\* 参 数:state:要写入的32位数据
\* 返回值:无
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\*/
void LS164\_Write(unsigned long state) //74LS164写32位扩展引脚函数
{
unsigned char i;
for(i=0;i<32;i++) //循环写32位扩展引脚状态
{
LS164_CLK = 0;
if(state & 0x80000000)
{
LS164_DATA = 1;
}
else
{
LS164_DATA = 0;
}
LS164_CLK = 1;
state = state<<1;
}
}

/\*\*
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\* 函 数:74LS165读32位扩展引脚函数
\* 参 数:无
\* 返回值:state:读取的32位数据
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\*/
unsigned long LS165\_Read(void) //74LS165读32位扩展引脚函数
{
unsigned char i; //计数变量
unsigned long state = 0; //读取的32位数据
LS165_SH_LD = 0; //并行口的8位数据被置入内部的8个触发器
LS165_SH_LD = 1; //并行输入被封锁,移位操作开始
for(i=0;i<32;i++)
{
state = state<<1; //数据左移1位
if(LS165_DATA) //若引脚为高电平
{
state |= 0x01; //最低位置1
}
LS165_CLK = 0;
LS165_CLK = 1; //上升沿数据移位
}
return state; //返回读取的数据
}

/\*\*
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\* 函 数:读取当前4个数码管显示的数字
\* 参 数:无
\* 返回值:无
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\*/
void Tube\_Read(void) //读取当前4个数码管显示的数字
{
unsigned char i,j; //计数变量
unsigned long state; //32位扩展引脚状态
state = LS165\_Read(); //读取所有扩展引脚状态
LED_Num[0] = (unsigned char)(state&0xFF); //扩展引脚EPA0~8状态
LED_Num[1] = (unsigned char)((state>>8)&0xFF); //扩展引脚EPB0~8状态
LED_Num[2] = (unsigned char)((state>>16)&0xFF); //扩展引脚EPC0~8状态
LED_Num[3] = (unsigned char)((state>>24)&0xFF); //扩展引脚EPD0~8状态
for(i=0;i<4;i++)
{
for(j=0;j<16;j++)
{
if(LED_Num[i]==tube[j]) //根据引脚状态判断显示的数字
{
LED_Num[i] = j; //数码管i+1显示的数字为j
break;
}
}
}
}

/\*\*
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\* 函 数:指定数码管显示指定数字函数
\* 参 数:serial:数码管序号,1~4
\* 参 数:num:指定显示的数字,0~9
\* 返回值:无
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\*/
void Tube\_Write(unsigned char serial, unsigned char num) //指定数码管serial显示指定数字num函数
{
unsigned long state; //LS164需写的32位扩展引脚状态
if((serial>=1)&&(serial<=4)&&(num>=0)&&(num<=9))
{
state = LS165\_Read(); //LS165读取当前所有扩展引脚状态
switch(serial) //指定数码管serial
{
case 1:{ //指定第1个数码管显示数字num
state &= 0xFFFFFF00;
state |= tube[num];
break;
}
case 2:{ //指定第2个数码管显示数字num
state &= 0xFFFF00FF;
state |= (((unsigned long)tube[num])<<8);
break;
}
case 3:{ //指定第3个数码管显示数字num
state &= 0xFF00FFFF;
state |= (((unsigned long)tube[num])<<16);
break;
}
case 4:{ //指定第4个数码管显示数字num
state &= 0x00FFFFFF;
state |= (((unsigned long)tube[num])<<24);
break;
}
}
LS164\_Write(state); //输出所有32位扩展引脚状态
}
}

/\*\*
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\* 函 数:工程主函数
\* 参 数:无
\* 返回值:无
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\*/
void main(void) //工程主函数
{
unsigned char i,j; //计数变量
LS164\_Write(0xFFFFFFFF); //所有数码管灭
LCD1602\_Init(); //LCD1602模块初始化
while(1)
{
for(i=0;i<10;i++) //4个数码管同时循环显示0~9
{
for(j=0;j<4;j++) //分别指定4个数码管显示同一数字
{
Tube\_Write(j+1,i); //指定数码管显示数字
}
Tube\_Read(); //读取数码管显示的数字
for(j=0;j<4;j++) //在LCD1602中显示
{
LCD1602\_DispChar(1,j+1,LED_Num[j]+48); //LCD1602指定行列显示字符
}
delay\_ms(2000); //延时
}
}
}

本实例参考:https://blog.csdn.net/qtyt567/article/details/80102400

程序源码和仿真资源

1
2
3
链接:https://pan.baidu.com/s/1dzZ-V2Pv0n7YEmAykW7lqg 
提取码:eahk