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

- 74LS164
8位串入、并出移位寄存器.
- 逻辑图

- 引脚图

引脚功能说明

示例程序
使用4片74LS164级联,作I/O扩展输出,共扩展32位;使用4片74LS165级联,作作I/O扩展输入。
实现功能:
- 74LS164扩展I/O输出点亮4个数码管;
- 74LS165读取扩展I/O引脚状态;
- 在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
|
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!