使用74LS164和74LS165实现简单I/O扩展
使用74LS164和74LS165实现简单I/O扩展
1、I/O扩展:
如题,本人尝试使用74LS164和74LS165实现简单I/O扩展,使用Keil C51编写程序,并使用Proteus搭建模型进行验证。
1)、74LS164:8位串入、并出移位寄存器
①、DSA和DSB:其中之一接高电平做使能端,另一个接输入数据;
②、CP:时钟,每个上升沿数据右移一位;
③、MR:主复位,高电平对输出无影响,低电平强制所有输出为0;
④、Q0~Q7:8位并行输出。
2)、74LS165:8位并入、串出移位寄存器
①、SH/LD:移位与置位控制端;SH/LD置0,并行口的8位数据将被置入其内部的8个触发器,在SH/LD为1时,并行输入被封锁,移位操作开始;
②、INH:低电平时充许时钟输入,高电平时禁止时钟输入;
③、CLK:时钟输入,上升沿有效;
①、D0~D7:并行输入端。
⑤、SI:串行输入,用于扩展多个74LS165 的首尾连接端;
⑥、SO(QH):串行输出;
QH(反):也是串行输出端,它与 SO(QH)是反相的关系;
2、Proteus模型:
使用4片74LS164级联,作I/O扩展输出,共扩展32位;使用4片74LS165级联,作作I/O扩展输入。
实现功能:①、74LS164扩展I/O输出点亮4个数码管;
②、74LS165读取扩展I/O引脚状态;
③、在LCD1602中同步显示数码管显示的数字。
3、Keil C51程序:
1)、工程文件结构:
2)、main.c
/****************************************************************************************** 文 件:工程主函数源文件* 芯 片:AT89S52* 晶 振:12MHz* 创建人:hug567* 时 间:2018-4-27****************************************************************************************/#include <regx52.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显示的数字为jbreak;}}}
}/****************************************************************************************** 函 数:指定数码管显示指定数字函数* 参 数: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个数码管显示数字numstate &= 0xFFFFFF00;state |= tube[num];break;}case 2:{ //指定第2个数码管显示数字numstate &= 0xFFFF00FF;state |= (((unsigned long)tube[num])<<8);break;}case 3:{ //指定第3个数码管显示数字numstate &= 0xFF00FFFF;state |= (((unsigned long)tube[num])<<16);break;}case 4:{ //指定第4个数码管显示数字numstate &= 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); //延时}}
}
3)、lcd1602.h
/****************************************************************************************** 文 件:LCD1602模块实现头文件* 创建人:hug567* 时 间:2018-4-27****************************************************************************************/sbit LCD1602_RS = P2^0; //LCD1602线
sbit LCD1602_RW = P2^1; //LCD1602线
sbit LCD1602_E = P2^2; //LCD1602线#define LCD1602_DATA P3 //LCD1602模块8位数据线void LCD1602_isBusy (void); //LCD1602判断忙函数
void LCD1602_WriteCmd (unsigned char); //LCD1602写指令、写显示地址函数
void LCD1602_WriteData (unsigned char); //LCD1602写数据函数
void LCD1602_DispChar (unsigned char,unsigned char,unsigned char); //LCD1602指定行列位置显示字符函数
void LCD1602_Init (void); //LCD1602初始化函数
4)、lcd1602.c
/****************************************************************************************** 文 件:LCD1602模块实现源文件* 创建人:hug567* 时 间:2018-4-27****************************************************************************************/#include "reg52.h" //52系列单片机头文件
#include "delay.h" //延时函数实现头文件
#include "lcd1602.h" //LCD1602实现头文件/****************************************************************************************** 函 数:LCD1602判断忙函数,忙则循环等待* 参 数:无* 返回值:无****************************************************************************************/
void LCD1602_isBusy(void) //LCD1602判断忙函数
{unsigned char busy; //忙标志LCD1602_RS = 0; //RS = 0LCD1602_RW = 1; //RW = 1LCD1602_E = 0; //E = 0do{LCD1602_E = 1; //E = 1delay_ms(5); //延时5毫秒busy = LCD1602_DATA & 0x80; //读忙标志LCD1602_E = 0; //E = 0}while(busy); //忙则循环等待
}/****************************************************************************************** 函 数:LCD1602写指令、写显示地址函数* 参 数:cmd:要写入的指令或显示地址* 返回值:无****************************************************************************************/
void LCD1602_WriteCmd(unsigned char cmd) //LCD1602写指令、写显示地址函数
{LCD1602_isBusy(); //判断忙,忙则循环等待LCD1602_RS = 0; //RS = 0LCD1602_RW = 0; //RW = 0LCD1602_E = 0; //E = 0LCD1602_DATA = cmd; //写入指令或显示地址LCD1602_E = 1; //E = 1delay_ms(5); //延时5毫秒LCD1602_E = 0; //E = 0
}/****************************************************************************************** 函 数:LCD1602写数据函数* 参 数:num:要写入的8位数据* 返回值:无****************************************************************************************/
void LCD1602_WriteData(unsigned char num) //LCD1602写数据函数
{LCD1602_isBusy(); //判断忙,忙则循环等待LCD1602_RS = 1; //RS = 1LCD1602_RW = 0; //RW = 0LCD1602_E = 0; //E = 0LCD1602_DATA = num; //写入数据LCD1602_E = 1; //E = 1delay_ms(5); //延时5毫秒LCD1602_E = 0; //E = 0
}/****************************************************************************************** 函 数:LCD1602指定行列位置显示字符函数* 参 数:x:行,1~2* 参 数:y:列,1~16* 参 数:chr:显示的字符,ASCII字符* 返回值:无****************************************************************************************/
void LCD1602_DispChar (unsigned char x,unsigned char y,unsigned char chr) //LCD1602指定行x列y位置显示字符chr函数
{LCD1602_WriteCmd(0x80+0x40*(x-1)+(y-1)); //显示字符位置:第x行第y列LCD1602_WriteData(chr); //显示指定字符chr
}/****************************************************************************************** 函 数:LCD1602初始化函数* 参 数:无* 返回值:无****************************************************************************************/
void LCD1602_Init(void) //LCD1602初始化函数
{LCD1602_WriteCmd(0x38); //显示模式:8位数据接口,两行显示,5*7点阵字符LCD1602_WriteCmd(0x08); //显示关,光标关,闪烁关LCD1602_WriteCmd(0x01); //清除DDRAM,清除AC(清屏)LCD1602_WriteCmd(0x06); //读数据后AC自动加1,读数据后画面不动LCD1602_WriteCmd(0x0c); //显示开,光标关,闪烁关
}
5)、delay.h
/****************************************************************************************** 文 件:延时函数实现头文件* 芯 片:AT89S52* 晶 振:12MHz* 创建人:hug567* 时 间:2018-4-27****************************************************************************************/void delay_ms(unsigned long t); //延时ms函数
6)、delay.c
/****************************************************************************************** 文 件:延时函数实现源文件* 芯 片:AT89S52* 晶 振:12MHz* 创建人:hug567* 时 间:2018-4-27****************************************************************************************/#include "delay.h" //延时函数实现头文件/****************************************************************************************** 函 数:延时ms函数* 参 数:t:延时ms值,0~4294967295* 返回值:无****************************************************************************************/
void delay_ms(unsigned long t) //延时ms函数
{unsigned char i; //计数变量for(;t>0;t--)for(i=200;i>0;i--); //不精确,此处循环值需测试
}
4、程序下载地址:
1)、74LS164、74LS165实现I/O扩展的C程序:https://download.csdn.net/download/qtyt567/10377537
2)、74LS164、74LS165实现I/O扩展的Proteus程序:https://download.csdn.net/download/qtyt567/10377540
使用74LS164和74LS165实现简单I/O扩展相关推荐
- 使用行动列表去创造简单且可扩展的游戏AI
作为人类,我们似乎总倾向于使用自己所熟悉的解决方法.我们总是会按照我们所知道的方式去做某些事,而不是按照做这些事的"最佳"方式.因为总是带着这种想法,所以我们很容易使用一些过时的技 ...
- vue 右键菜单插件 简单、可扩展、样式自定义的右键菜单
今天分享的不是技术,今天给大家分享个插件,针对现有的vue右键菜单插件,大多数都是需要使用插件本身自定义的标签,很多地方不方便,可扩展性也很低,所以我决定写了一款自定义指令调用右键菜单(vuerigh ...
- 简单句的扩展----成分角度扩展-----非谓语动词作定语,状语 和 同位语 插入语
前绪:简单的扩展分为两种 1.词性的扩展:用来限定,补充,说明 扩展-----> 2.成分的扩展: 定语,状语,同位语,插入语 第一节:非谓语作为作为定语或者状语 概念:弄清三个问题 1.什么是 ...
- php 动态加载扩展,仿照PHP的实现简单的扩展动态加载
PHP通过扩展机制,可以方便的实现对PHP的动态扩展,在PHP扩展加载过程中简单的分析了PHP扩展的加载过程,下面可以继续根据PHP的相关实现,实现一个自己的简单的支持扩展的程序. 在PHP中,有个非 ...
- xmake入门,构建项目原来可以如此简单
为什么80%的码农都做不了架构师?>>> 前言 在开发xmake之前,我一直在使用gnumake/makefile来维护个人C/C++项目,一开始还好,然而等项目越来越庞大后, ...
- 大型运输行业实战_day14_1_webserivce简单入门
1.简单使用 1.1.服务端 1.编写接口 1 package com.day02.sation.ws; 2 3 /** 4 * Created by Administrator on 1/12. 5 ...
- php jquery 全选删除,jQuery+php简单实现全选删除的方法
jQuery+php简单实现全选删除的方法 发布于 2017-08-06 10:13:21 | 66 次阅读 | 评论: 0 | 来源: 网友投递 PHP开源脚本语言PHP(外文名: Hypertex ...
- 深入解析 Kubebuilder:让编写 CRD 变得更简单
原文连接:https://developer.aliyun.com/article/719215 作者 | 刘洋(炎寻) 阿里云高级开发工程师 导读:自定义资源 CRD(Custom Resource ...
- Web Services简单介绍
Web Services简单介绍 Web Services入门 一.Web Services简介 1.什么是Web Services? Web Services 是应用程序组件 Web Service ...
最新文章
- Docker学习(七)-----Docker安装nginx
- EasyTouch初步使用
- python小游戏代码大全-Python实现打砖块小游戏代码实例
- 继BERT之后,这个新模型再一次在11项NLP基准上打破纪录
- ASP.NET跨页面传值技巧
- HALCON示例程序check_blister.hdev药品胶囊检测
- java可选项_在Java中链接可选项8
- 面向对象 —— 类设计(八)
- 统计知识 | 中心极限定理及偏差
- F检验(ANOVA)
- 离开阿里加盟复旦!大牛纷纷离职回归学界,撕下了国内大厂AI的最后遮羞布!大厂AI名存实亡?...
- 蓝桥杯单片机—— PCF8591的基本原理及A/D转换应用(14)
- HDFS 系列二:HFDS 命令行操作
- JTAG和SWD定义
- Google Chrome 浏览器常用快捷键
- java学习输出文档
- WBO第一届世界区块链高峰论坛在香港国际亚洲博览馆正隆重举行
- 【IPD】敏捷开发与IPD结合的实践培训课程「3月11-12日」
- 更改电脑ip地址的方法
- 动态域名解析服务系统简介
热门文章
- Python遍历多个列表:ValueError: too many values to unpack (expected 2)
- Django大咖之路: 如何对付学习Django过程中所遇到的挫败感?
- Kafka原理篇:图解kakfa架构原理
- vivado综合出现“PID not specified”问题的参考解决方法
- 转:阿里CEO张勇:领导者要善于“从后排把人往前拨”
- 【sqoop2】创建job报错There are issues with entered data, please revise your input
- Unit elasticsearch.service entered failed state
- 大数据能力提升项目|学生成果展系列之五
- 深度学习笔记(五) 代价函数的梯度求解过程和方法
- 深度学习模型的构建三、优化函数optimizer