51单片机74HC595驱动LCD1602扩展IO口

2023-11-07 16:30

本文主要是介绍51单片机74HC595驱动LCD1602扩展IO口,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

51单片机74HC595驱动LCD1602扩展IO口

一般我们用51驱动LCD1602的时候会选择P0口连接LCD1602的D0~D7,和另外三个IO控制RS,RW和EN。
只是驱动一个1602就占用了11个IO口。 而如果我们把1602的D0~D7用一个8位并行输出的芯片来传输数据不就节省了一部分IO口吗?

74HC595
74HC595是一个8位串行输入、并行输出的位移缓存器。
proteus仿真使用图如下
在这里插入图片描述
74HC595与单片机相接只需三条线。Q0~Q7与1602的 D0–D7相接。
DS是74HC595的8位数据串行输入端。SH_CP的8位串行数据输入的时钟线,在上升沿时把数据送到74HC595。当把数据传输完时,给ST_CP一个上升沿数据就从Q0–Q7并行输出。

74HC595的51驱动程序

/* 74HC595的51驱动程序 */
#include "reg52.h"
#include <intrins.h>sbit SH_CP = P2^0;
sbit DS    = P2^1;
sbit ST_CP = P2^2;//74HC595驱动程序
void HC595_Data(u8 sum){u8 k;_nop_();ST_CP = 0;for(k=0;k<8;k++){SH_CP = 0;       //先把SH_CP引脚拉低DS = (sum&0x80); //取高位SH_CP = 1; sum<<= 1;        //数据左移1位,把sum由高到低一位一位传输给74HC595}ST_CP = 1;         //给ST_CP一个上升沿,把数据并行输出}void main()
{HC595_Data(0x15); //让74HC595输出 0001 0101while(1){}
}

在这里插入图片描述
单独驱动74HC595的程序已经写好。那接下来就是驱动LCD1602了。

proteus仿真电路图如下
在这里插入图片描述
接下来废话不多说直接上程序

#include "reg52.h"
#include <intrins.h>sbit RS = P1^0;
sbit RW = P1^1;
sbit E = P1^2;sbit SH_CP = P2^0;
sbit DS    = P2^1;
sbit ST_CP = P2^2;void LCD1602_Write_DAT(u8 dat);
void LCD1602_Write_CMD(u8 cmd);
void LCD1602_Display_Char(bit x,u8 y,u8 *s);
void LCD1602_Position(bit x,u8 y);
void LCD1602_Display_Data(bit x,u8 y,u8 dat);
void HC595_Data(u8 sum);u16 num;
u16 i;
void main()
{num = 2021;i   = 1120 ;LCD1602_Write_CMD(0x06);	//指针自增LCD1602_Write_CMD(0x0C);	//显示开,光标关LCD1602_Write_CMD(0x38);	//8位接口,两行显示LCD1602_Write_CMD(0x01);	//清屏/* 关于这个LCD1602_Write_DAT('0'); 语句。我给大家解释一下。  
可能大家看完这个会有疑问。为什么要给1602发送一个0呢?而且也不指定位置呢?
这是因为不知道是我程序的问题还是电路的问题(严重怀疑是74HC595驱动程序的问题)
经过多次的调试发现给1602发送的第一个数据1602接收不到(给1602的第一个命令可以接收到)
第二次及以后的数据可以正常接收。
所以在显示字符串语句的前面,要有一个发送数据的函数。不然字符串的第一个字母则会显示不正常
本人水平有限请见谅*/LCD1602_Write_DAT('0');LCD1602_Display_Char(0,6,"TYQ");while(1){//显示2021年LCD1602_Display_Data(1,0,num/1000+'0'); //       显示千位 2LCD1602_Display_Data(1,1,num%1000/100+'0'); //   显示百位 0LCD1602_Display_Data(1,2,num%100/10+'0'); //     显示十位 2LCD1602_Display_Data(1,3,num%10+'0'); //         显示个位 1LCD1602_Display_Char(1,4,"year");//显示11 月LCD1602_Display_Data(1,8,i/1000+'0'); //       显示千位 1LCD1602_Display_Data(1,9,i%1000/100+'0'); //   显示百位 1LCD1602_Display_Char(1,10,"moon");							//显示20		LCD1602_Display_Data(1,14,i%100/10+'0'); //     显示十位 2LCD1602_Display_Data(1,15,i%10+'0'); //         显示个位 0}
}//LCD1602 位置显示指函数
void LCD1602_Position(bit x,u8 y)
{u8 position;if(x==0)position = 0x80 + y;elseposition = 0xC0 + y;LCD1602_Write_CMD(position);
}//LCD1602写数据函数
void LCD1602_Write_DAT(u8 dat)
{_nop_();_nop_();RS = 1;RW = 0;_nop_();HC595_Data(dat);_nop_();E = 0;E = 1;E = 0;
}//LCD1602写命令函数
void LCD1602_Write_CMD(u8 cmd)
{_nop_();_nop_();RS = 0;RW = 0;;HC595_Data(cmd);E = 1;E = 0;
}//LCD1602指定位置显示字符串函数
void LCD1602_Display_Char(bit x,u8 y,u8 *s) 
{LCD1602_Position(x,y);while(*s)LCD1602_Write_DAT(*s++);
}//LCD1602指定位置显示数字函数	
void LCD1602_Display_Data(bit x,u8 y,u8 dat)  
{LCD1602_Position( x, y);LCD1602_Write_DAT(dat);
}//74HC595驱动函数
void HC595_Data(u8 sum){u8 k;ST_CP = 0;for(k=0;k<8;k++){SH_CP = 0;DS = (sum&0x80);SH_CP = 1; sum<<= 1;}ST_CP = 1;}

在这里插入图片描述
相关程序和仿真电路存放至网盘
链接:https://pan.baidu.com/s/1yWkaex99k1dm1rkal-8E4w
提取码:TYQT

这篇关于51单片机74HC595驱动LCD1602扩展IO口的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/364859

相关文章

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

day-51 合并零之间的节点

思路 直接遍历链表即可,遇到val=0跳过,val非零则加在一起,最后返回即可 解题过程 返回链表可以有头结点,方便插入,返回head.next Code /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}*

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统         在产品将要上线之前,需要制作不同类型格式的根文件系统         在产品研发阶段,我们还是需要使用nfs的方式挂载根文件系统         优点:可以直接在上位机中修改文件系统内容,延长EMMC的寿命         【1】重启上位机nfs服务         sudo service nfs-kernel-server resta

Spring框架5 - 容器的扩展功能 (ApplicationContext)

private static ApplicationContext applicationContext;static {applicationContext = new ClassPathXmlApplicationContext("bean.xml");} BeanFactory的功能扩展类ApplicationContext进行深度的分析。ApplicationConext与 BeanF

基于51单片机的自动转向修复系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 单片机

Java IO 操作——个人理解

之前一直Java的IO操作一知半解。今天看到一个便文章觉得很有道理( 原文章),记录一下。 首先,理解Java的IO操作到底操作的什么内容,过程又是怎么样子。          数据来源的操作: 来源有文件,网络数据。使用File类和Sockets等。这里操作的是数据本身,1,0结构。    File file = new File("path");   字

单片机毕业设计基于单片机的智能门禁系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍程序代码部分参考 设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订

springboot体会BIO(阻塞式IO)

使用springboot体会阻塞式IO 大致的思路为: 创建一个socket服务端,监听socket通道,并打印出socket通道中的内容。 创建两个socket客户端,向socket服务端写入消息。 1.创建服务端 public class RedisServer {public static void main(String[] args) throws IOException {

Java基础回顾系列-第七天-高级编程之IO

Java基础回顾系列-第七天-高级编程之IO 文件操作字节流与字符流OutputStream字节输出流FileOutputStream InputStream字节输入流FileInputStream Writer字符输出流FileWriter Reader字符输入流字节流与字符流的区别转换流InputStreamReaderOutputStreamWriter 文件复制 字符编码内存操作流(