【51单片机系列】LCD1602液晶模块

本文是关于液晶显示屏的相关介绍。相对于静态数码管、动态数码管、LED点阵等,LCD1602液晶显示器能够显示更多的字符数字信息,并且也是常用的一种显示装置。

文章目录

  • 一、LCD1602介绍
    • 1.1、LCD1602简介
    • 1.2、LCD1602常用指令
    • 1.3、LCD1602使用
  • 二、LCD1602使用示例
  • 三、LCD扩展实验:使用LCD1602显示时钟

一、LCD1602介绍

1.1、LCD1602简介

1602液晶,也叫做1602字符型液晶,可以显示2行字符信息,每行可以显示16个字符,是一种专门用来显示字母、数字、符号的点阵型液晶模块。

LCD1602由若干个5x7或者5x10的点阵字符位组成,每个点阵字符位都可以显示一个字符,每位之间有一个点距地间隔,每行之间也有间隔,起到了字符间距和行间距的作用。

LCD1602实物如下:

LCD1602实物图

从实物图中可以看到16个管脚孔,从左至右管脚编号顺序是1-16,管脚功能定义如下表:

管脚编号符号管脚说明
1VSS电源地
2VDD电源正极
3VL液晶显示偏压信号
4RS数据/命令选择端 H/L
5R/W读/写选择端 H/L
6E使能信号
7~14D0~D7Data I/O
15BLA背光源正极
16BLK背光源负极

管脚详细说明:

  • 3脚-VL:液晶显示偏压信号,该管脚用来调整LCD1602的显示对比度,一般会外接电位器用以调整偏压信号。需要注意的是,该管脚电压为0时可以得到最强的对比度。
  • 4脚-RS:数据/命令选择端,当该管脚为高电平时,可以对1602进行数据字节的传输操作;该管脚为低电平时,对1602进行命令字节的传输操作。所谓命令字节,就是对LCD1602的一些工作方式设置的字节;数据字节,用来在1602上显示的字节。LCD1602的数据是8位的
  • 5脚-R/W:读写选择端。当该管脚为高电平时可对LCD1602进行读数据操作,该管脚为低电平时对LCD1602进行写数据操作。
  • 6脚-E:使能信号,实际上是LCD1602的数据控制时钟信号,使用该管脚的上升沿实现对LCD1602的数据传输。
  • 7~14脚-8位并行数据口:51单片机一组IO也是8位,方便了对LCD1602的数据读写。

LCD1602内部含有80字节的DDRAM,是用来存储显示字符的。其地址和屏幕的对应关系如下:

显示位置123456740
DDRAM地址第一行00H01H02H03H04H05H06H27H
DDRAM地址第二行40H41H42H43H44H45H46H67H

LCD602地址和屏幕对应关系

从上图可以看到,并不是所有的地址都能直接用来显示字符。只有第一行中的00-0F,第二行中的40-4F才能显示,其它地址只能用于存储

要显示字符时首先要输入显示字符地址,即明确在哪里显示字符。比如第二行第一个字符地址是40H,不能够直接写入40H,因为写入显示地址时要求最高位D7为1,所以第二行第一个字符地址应该是40H|80H=C0H。

1.2、LCD1602常用指令

LCD1602有一些常用指令,这些指令对于初始化是必须的。

LCD1602常用指令

1.3、LCD1602使用

要使用LCD1602,首先需要对其初始化,即通过写入一些特定的指令实现;然后选择要在LCD1602的哪个位置显示并将所要显示的数据发送到LCD的DDRAM。

使用LCD1602通常用于写数据进去,比较少使用读功能。

LCD1602操作步骤如下:

① 初始化

② 写命令,RS=L,设置显示坐标;

③ 写数据,RS=H;

这里不需要读数据,所以只需要两个写时序。

  • 第一个是写指令字时序。设置LCD1602的工作方式时,需要把RS置为低电平,RW置为低电平,然后将指令字送到数据口D0~D7,最后E使能引脚一个高脉冲将数据写入。
  • 第二个是写数据字时序。LCD1602实现显示时,需要把RS置为高电平,RW置为低电平,然后将数据字送到数据口D0~D7,最后E使能引脚一个高脉冲将数据写入。

从上面两个时序可以看出,写指令和写数据只是RS电平不一样。

LCD1602时序图如下:

LCD1602时序图

LCD1602时序图时间

从上图中可以看到时序图中的时间参数全部是ns级别的,51单片机的机器周期是1us,指令周期是2~4个机器周期,所以在程序中可以不加延时程序,也能适配LCD1602的时序要求。

当要写命令字时,时间由左往右,RS变为低电平,R/W变为低电平,RS的状态先变化完成;然后DB0~DB7上数据进入有效阶段,接着E引脚有一个正脉冲的跳变,接着维持时间最小值为tpw=400ns的E脉冲宽度;然后引脚E负跳变,RS电平变化,R/W电平变化。这便是一个完整的LCD1602写命令的时序。

二、LCD1602使用示例

本示例实现的功能:系统运行时,在LCD1602液晶上显示字符信息。使用到的资源是LCD1602液晶显示屏。

proteus中设计原理图如下:

PROTEUS设计LCD1602液晶显示模块

从上面的原理图可以看出该电路不是独立的,LCD1602的8位数据口DB0-DB7与单片机的P0.0-P0.7管脚链接;LCD1602的RS、RW、E脚与单片机的P2.6、P2.5、P2.7管脚链接;RV1是一个电位器,用来调节LCD1602显示亮度。

软件设计:

LCD发送命令和数据代码如下:

#include <reg52.h>
#include "lcd1602.h"// 延时函数,延时ims,12MHz晶振下,12分频单片机的延时
void lcd1602_Delay1ms(uint i)
{uchar a,b;for(;i>0;i--){for(b=199;b>0;b--){for(a=1;a>0;a--);}}
}#ifndef LCD1602_4PINS  // 8位数据线
// 向LCD写入一个字节的命令
void lcd1602_WriteCom(uchar com)
{LCD_EN=0;  // 使能LCD_RS=0;  // 发送命令LCD_RW=0;  // 选择写命令LCD_DATA=com;  // 放入数据lcd1602_Delay1ms(1);  // 等待数据稳定LCD_EN=1;  // 写入时序lcd1602_Delay1ms(5);  // 保持稳定LCD_EN=0;  
}// 向LCD写入一个字节的数据
void lcd1602_WriteData(uchar dat)
{LCD_EN=0;  // 使能LCD_RS=1;  // 发送数据LCD_RW=0;  // 选择写命令LCD_DATA=dat;  // 放入数据lcd1602_Delay1ms(1);  // 等待数据稳定LCD_EN=1;  // 写入时序lcd1602_Delay1ms(5);  // 保持稳定LCD_EN=0;   
}// LCD1602初始化
void lcd1602_Init()
{lcd1602_WriteCom(LCD_MODE_8_2_5X7);  // 8位数据,显示2行,5x7点阵/每字符 38Hlcd1602_WriteCom(LCD_CURSOR_RIGHT);  // 写入数据后光标右移 06Hlcd1602_WriteCom(LCD_CLEAR);  // 清屏 01Hlcd1602_WriteCom(LCD_OPENSHOW);  // 显示开 0CHlcd1602_WriteCom(LCD_START_ADDR1);  // 设置数据指针地址起始点是第一行第一列,80H=00H|80H
}#else  // 4位数据线
// 向LCD写入一个字节的命令
void lcd1602_WriteCom(uchar com)
{LCD_EN=0;  // 使能LCD_RS=0;  // 发送命令LCD_RW=0;  // 选择写命令LCD_DATA=com;  // 放入数据,4位数据,接线到P0的高四位,传送高四位不用改lcd1602_Delay1ms(1);  // 等待数据稳定LCD_EN=1;  // 写入时序lcd1602_Delay1ms(5);  // 保持稳定LCD_EN=0;  LCD_DATA=com<<4;lcd1602_Delay1ms(1);  // 等待数据稳定LCD_EN=1;  // 写入时序lcd1602_Delay1ms(5);  // 保持稳定LCD_EN=0;  
}// 向LCD写入一个字节的数据
void lcd1602_WriteData(uchar dat)
{LCD_EN=0;  // 使能LCD_RS=1;  // 发送数据LCD_RW=0;  // 选择写命令LCD_DATA=dat;  // 放入数据,4位数据,接线到P0的高四位,传送高四位不用改lcd1602_Delay1ms(1);  // 等待数据稳定LCD_EN=1;  // 写入时序lcd1602_Delay1ms(5);  // 保持稳定LCD_EN=0;  LCD_DATA=dat<<4;lcd1602_Delay1ms(1);  // 等待数据稳定LCD_EN=1;  // 写入时序lcd1602_Delay1ms(5);  // 保持稳定LCD_EN=0;  
}// LCD1602初始化
void lcd1602_Init()
{lcd1602_WriteCom(0x32);  // 将8位总线转为4位总线lcd1602_WriteCom(LCD_MODE_8_2_5X7);  // 8位数据,显示2行,5x7点阵/每字符28Hlcd1602_WriteCom(LCD_CURSOR_RIGHT);  // 写入数据后光标右移 06Hlcd1602_WriteCom(LCD_CLEAR);  // 清屏 01Hlcd1602_WriteCom(LCD_OPENSHOW);  // 显示开 0cHlcd1602_WriteCom(LCD_START_ADDR1);  // 设置数据指针地址起始点是第一行第一列,80H=00H|80H
}
#endif

主函数调用:

/*实现功能:系统运行后,LCD1602液晶显示屏显示字符[2024-01-03] zoya
*/#include <reg52.h>
#include "lcd1602.h"typedef unsigned char u8;
typedef unsigned int u16;u8 Disp[]="Pechin Science:";void delay(u16 i)
{while(i--);
}
void main()
{u8 i;lcd1602_Init();  // LCD初始化for(i=0;i<16;i++){lcd1602_WriteData(Disp[i]);delay(5000);}while(1);
}

proteus仿真结果:

LCD1602液晶显示屏仿真结果

三、LCD扩展实验:使用LCD1602显示时钟

LCD扩展实验实现的功能:系统运行时,LCD1602显示时间,显示格式:第一行显示年-月-日 星期“xxxx-xx-xx xth”,第二行显示时:分:秒"xx:xx:xx"。使用EEPROM记录是否已经初始化(读取EEPROM中0x00地址的数据,如果数据为0xff表示未进行初始化,如果为0x01表示已经进行初始化)。用到的资源有DS1302时钟芯片、AT24C02 EEPROM芯片、LCD1602液晶显示器。

proteus原理图设计如下:

proteus原理图设计使用LCD1602显示时间信息

设计思路,首先读取eeprom中0x00地址的数据,根据数据判断DS1302是否进行初始化,然后初始化LCD1602,在循环中读取时间并将其显示到LCD中。主程序编写如下:

void main()
{u8 i;u8 dat;dat=AT24C02Read(EN_INIT_ADDR);if(0xff==dat){DS1302Init();AT24C02Write(EN_INIT_ADDR, 0x01);}lcd1602_Init();while(1){DataPros();lcd1602_WriteCom(LCD_START_ADDR1);  // 年月日星期显示在第一行for(i=0;i<14;i++){lcd1602_WriteData(Disp1Row[i]);}lcd1602_WriteCom(LCD_START_ADDR2);  // 时分秒显示在第二行for(i=0;i<8;i++){lcd1602_WriteData(Disp2Row[i]);}delay(500);}
}

数据处理函数:

uchar szTime[]="0123456789 -th:";
uchar Disp2Row[16];
uchar Disp1Row[16];
void DataPros()
{DS1302ReadTime();Disp1Row[0]=szTime[2];  // 2Disp1Row[1]=szTime[0];  // 0Disp1Row[2]=szTime[TIME[6]>>4];  // 年的十位Disp1Row[3]=szTime[TIME[6]&0x0f];  // 年的个位Disp1Row[4]=szTime[11];  // -Disp1Row[5]=szTime[TIME[4]>>4&0x01];  // 月的十位Disp1Row[6]=szTime[TIME[4]&0x0f];  // 月的个位Disp1Row[7]=szTime[11];  // -Disp1Row[8]=szTime[TIME[3]>>4&0x03];  // 日的十位Disp1Row[9]=szTime[TIME[3]&0x0f];  // 日的个位Disp1Row[10]=szTime[10];  // 空格Disp1Row[11]=szTime[(TIME[5]&0x0f) - 1];  // 星期几Disp1Row[12]=szTime[12];  // tDisp1Row[13]=szTime[13];  // hDisp2Row[0]=szTime[TIME[2]/16];  // 时的十位Disp2Row[1]=szTime[TIME[2]&0x0f];  // 时的个位Disp2Row[2]=szTime[14];  // : 冒号Disp2Row[3]=szTime[TIME[1]/16];  // 分的十位Disp2Row[4]=szTime[TIME[1]&0x0f];  // 分的个位Disp2Row[5]=szTime[14];  // : 冒号Disp2Row[6]=szTime[TIME[0]>>4&0x07];  // 秒的十位Disp2Row[7]=szTime[TIME[0]&0x0f];  // 秒的个位
}

仿真结果:

LCD1602显示时间信息仿真结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/596000.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

openGauss学习笔记-174 openGauss 数据库运维-备份与恢复-导入数据-管理并发写入操作

文章目录 openGauss学习笔记-174 openGauss 数据库运维-备份与恢复-导入数据-管理并发写入操作174.1 事务隔离说明174.2 写入和读写操作174.3 并发写入事务的潜在死锁情况 openGauss学习笔记-174 openGauss 数据库运维-备份与恢复-导入数据-管理并发写入操作 174.1 事务隔离说…

Parallels虚拟机启动后,Mac主机无法上网怎么办

文章目录 1.问题2.解决&#xff1a; 1.问题 部分用户在运行Parallels Desktop的Windows 11打开后&#xff0c;Windows上网没有问题 &#xff0c;但是Mac主机不能访问带域名的网站&#xff0c;而访问带ip的网站没问题&#xff0c;退出parallels虚拟机以后&#xff0c;mac网络恢…

docker 部署来自Hugging Face下机器翻译模型

机器翻译模型(Hugging Face官网) 模型翻译api服务代码 # 离线翻译服务代码 # -*-coding:utf-8-*-import os import json import logging from logging.handlers import RotatingFileHandler from datetime import datetime from flask import Flask, request,jsonify from geve…

HarmoryOS Ability页面的生命周期

接入穿山甲SDK app示例&#xff1a; android 数独小游戏 经典数独休闲益智 广告接入示例: Android 个人开发者如何接入广告SDK&#xff0c;实现app流量变现 Ability页面的生命周期 学习前端&#xff0c;第一步最重要的是要理解&#xff0c;页面启动和不同场景下的生命周期的…

内联函数的作用

目的 主要为了提升程序运行速度。 分析 当程序调用一个函数时&#xff0c;程序暂停执行当前指令&#xff0c;跳到函数体处执行&#xff0c;在函数执行完后&#xff0c;返回原来的位置继续执行。如果该函数为内联函数&#xff0c;则不需跳&#xff0c;是因为该内联函数直接插…

基于TIC6000的DSP教学实验箱操作教程:5-18 RGB24图像灰度转换(LCD显示)

一、实验目的 学习RGB24图像灰度转换的原理&#xff0c;掌握图像的读取方法&#xff0c;并实现在LCD上显示灰度转换前后的图像。 二、实验原理 RGB24图像灰度转换 RGB颜色空间作为一种常用的彩色图像表示模型&#xff0c;分别用红&#xff08;R&#xff09;、绿&#xff08…

《代码整洁之道之程序员的职业素养》-专业主义

专业主义有很深的含义&#xff0c;它不但象征着荣誉和骄傲&#xff0c;而且明确意味着责任和义务担当责任&#xff0c;“为了按时交付软件&#xff0c;没测例行程序&#xff0c;测试例行程序需要几个小时&#xff0c;当时必须交付软件&#xff0c;因为故障修复部分都不涉及例行…

文件摆渡系统如何实现网络隔离后的数据交换、业务流转?

近年来全球网络安全威胁态势的加速严峻&#xff0c;使得企业对于网络安全有了前所未有的关注高度。即便没有行业性的强制要求&#xff0c;但在严峻的安全态势之下&#xff0c;企业的网络安全体系建设正从“以合规为导向”转变到“以风险为导向”&#xff0c;从原来的“保护安全…

鸿蒙系列--动态共享包的依赖与使用

一、前言 HarmonyOS的共享包相当于Android的Library&#xff0c;在HarmonyOS中&#xff0c;给开发者提供了两种共享包&#xff0c;HAR&#xff08;Harmony Archive&#xff09;静态共享包&#xff0c;和HSP&#xff08;Harmony Shared Package&#xff09;动态共享包 区别&…

Python从入门到网络爬虫(函数详解)

前言 函数是变成语言中最常见的语法&#xff0c;函数的本质就是功能的封装。使用函数可以大大提高编程效率与程序的可读性。函数是能够实现特定功能的计算机代码而已&#xff0c;他是一种特定的代码组结构。 函数的作用 1.提升代码的重复利用率&#xff0c;避免重复开发相同代…

js——json对象相互转化——js基础积累

js——json对象相互转化——js基础积累 需求场景解决步骤1&#xff1a;定义一个变量接收此字段&#xff0c;方便处理解决步骤2&#xff1a; { 外面的双引号要去掉解决步骤3&#xff1a;使用正则去除参数中的\\解决步骤4&#xff1a;如果此参数必须以{开头&#xff0c;以}结尾解…

一文快速了解超声功率放大器基础知识

超声功率放大器是一种电子设备&#xff0c;用于放大超声信号的能量。它在多个领域中发挥重要作用&#xff0c;包括医疗、工业、科学研究等。超声功率放大器通过将输入信号的能量放大到所需的级别&#xff0c;以便更好地驱动其他设备或实现特定的应用。下面就给大家介绍一下超声…

C++ 多态向上转型详解

文章目录 1 . 前言2 . 多态3 . 向上转型4 . 总结 【极客技术传送门】 : https://blog.csdn.net/Engineer_LU/article/details/135149485 1 . 前言 此篇博文详解C的多态向上转型平台 : Qt 2 . 多态 【Q】什么是多态&#xff1f; 【A】解释如下 : 通俗来说,就是多种形态,具体…

2024,这将是量子计算的真正挑战

2023年&#xff0c;一项项量子计算纪录被打破。 谷歌量子AI团队证明了将多个量子比特分组合成为一个逻辑量子比特的纠错方法可以提供更低的容错率。以往的纠错研究随着比特数的增加&#xff0c;错误率会提高&#xff0c;都是“越纠越错”&#xff0c;而这次谷歌首次实现了“越纠…

【springboot+mybatis实现CURD模版项目-Jesus】

springbootmybatis实现CURD模版项目-Jesus STEP 1 项目创建 1.1 新建Spring Initializr项目   1.2 选择需要的依赖 springboot有2.7.2直接选272STEP 2 配置更改 2.1更改maven配置   2.2 检查项目配置jdk、sdk、jre版本一致   2.3 检查pom文件&#xff0c;Maven-Reload pr…

grep笔记240103

常用选项&#xff1a;&#xff1a; -i&#xff1a;忽略大小写进行匹配。 -v&#xff1a;反向匹配&#xff0c;只打印不匹配的行。 -n&#xff1a;显示匹配行的行号。 -r&#xff1a;递归查找子目录中的文件。 -l&#xff1a;只打印匹配的文件名。 -c&#xff1a;只打印匹配的行…

11-2 RHEL8配置YUM软件仓库及安装拼音输入法

配置本地YUM源 一、虚拟机关机>>虚拟机设置>>CD/DVD&#xff0c;关联ISO镜像文件&#xff0c;勾选“启动时连接”&#xff0c;点确定 二、开启虚拟机&#xff0c; 使用root用户登录。用df -h 命令可以看到光驱已经正常连接了。如果看不到/dev/sr0&#xff0c;需…

探索 Vue 实例方法的魅力:提升 Vue 开发技能(下)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

铁塔基站数字化管理监测解决方案

截至2023年10月&#xff0c;我国5G基站总数达321.5万个&#xff0c;占全国通信基站总数的28.1%。然而&#xff0c;随着5G基站数量的快速增长&#xff0c;基站的能耗问题也逐渐日益凸显&#xff0c;基站的用电给运营商带来了巨大的电费开支压力&#xff0c;降低5G基站的能耗成为…