51单片机STC89C52RC——5.1 LCD1602液晶显示屏

目录

目的

一,STC单片机模块

二,LCD1602

2.1 模块简介

2.2 针脚

2.3 DDRAM地址与显示器对应关系

2.4 标准字库表

2.5 常用指令

2.6 读写操作

三,创建Keil项目

四,代码 

五,代码编译、下载到51单片机

六,效果


目的

将LCD1602做成一个调试显示器使用。实现以下功能

LCD_Init();                                          初始化
LCD_ShowChar(1,1,'A');                     显示一个字符
LCD_ShowString(1,3,"Hello");             显示字符串
LCD_ShowNum(1,9,123,3);                显示十进制数字
LCD_ShowSignedNum(1,13,-66,2);    显示有符号十进制数字
LCD_ShowHexNum(2,1,0xA8,2);        显示十六进制数字
LCD_ShowBinNum(2,4,0xAA,8);         显示二进制数字

一,STC单片机模块

二,LCD1602

2.1 模块简介

 

LCD ( Liquid Crystal Display 的简称)液晶显示器。能够同时显示16x2,32个字符,是一种专门用来显示字母、数字、符号等的点阵型液晶模块。

LCD1602液晶显示器是广泛使用的一种字符型液晶显示模块。它是由字符型液晶显示屏(LCD)、控制驱动主电路HD44780及其扩展驱动电路HD44100,以及少量电阻、电容元件和结构件等装配在PCB板上而组成。该显示屏的优点是耗电量低、体积小、辐射低。

LCD1602主要用来显示数字、字母、图形以及少量自定义字符。可以显示2行16个字符,拥有16个引脚,其中8位数据总线D0-D7,和RS、R/W、EN三个控制端口,工作电压为5V,并且带有字符对比度调节V0和背光源AK。

注:
我们所用的LCD屏的命名,基本都是按照其分辨率来进行命名的 比如lcd1602 就是分辨率为16×2 lcd12864 就是分辨率为128×64

接线方式

板子上我们要将LCD1602插在右上角的插槽中。注意方向 

2.2 针脚

2.3 DDRAM地址与显示器对应关系

2.4 标准字库表

这个ROM中固化了一些我们常用的ASCII字符以及部分日文字符的点阵数据,需要写入那个字符,就直接设置对应进制码就可以,比如大写的字母A,代码是0100 0001(41H) 与ASCII码一致。也就是表中的ASCII码字符的地址和实际的ASCII码字符是一样的 

2.5 常用指令

1:清屏指令

  • 光标复位到地址00H位置,
  • LCD显示DDRAM的内容全部写入” “的ASCII码20H

2:模式设置指令 

  • I/D,写入新数据后光标移动方向,高电平右移,低电平左移,
  • S:写入新数据后显示屏字符是否整体左移或右移一个字符,高电平表示有效,低电平表示无效 

3:显示开关控制指令

  • D(Dispaly):控制整体的显示开与关,高电平表示开显示屏,低电平表示关显示屏
  • C(Cursor):控制光标的开与关,高电平表示有光标,低电平表示无光标
  • B(Blink):控制光标是否闪烁,高电平闪烁,低电平不闪烁

4:功能设定指令

  • DL:DL=1代表数据长度为8位,DL=0代表数据长度为4位
  • N:低电平时只有一行可以显示,高电平时两行都可以显示,
  • F:低电平时一个字符大小为5X7的点阵字符,高电平时一个字符大小为5X10的点阵字符。

5:光标或显示移位 

  • SC=0,RL=0 :光标左移
  • SC=0,RL=1 : 光标右移
  • SC=1,RL=0时,字符和光标都左移
  • SC=1,RL=1时字符和光标都右移

 其他指令可参考《【常用传感器】LCD1602液晶工作原理详解及例程代码_lcd1602工作原理-CSDN博客》

2.6 读写操作

LCD1602分为读操作写操作

其中读操作可以分为读状态读数据,写操作可以分为写指令写数据

读状态: 读取LCD引脚状态,返回为状态字,D0-D6为当前LCD数据指针的地址 D7为是否允许读写操作(即检查LCD是否处于忙状态)

 

读数据:读取D0-07内的数据

写指令: 写入LCD的控制指令,比如清屏,显示开关等

写数据: 写入需要显示的数据,比方说要显示字符a,就写入0100 0001(41H)

读状态    引脚电平:RS=L,RW=H,E=H    输出:D0~D7=状态字
读数据    引脚电平:RS=H,RW=H,E=H    输出:D0~D7的数据
写指令    引脚电平:RS=L,RW=L,D0~D7=指令码,E=高脉冲    输出:无
写数据    引脚电平:RS=H,RW=L,D0~D7=数据,E=高脉冲    输出:无
以51单片机为例,D0-D7接到P0口 RW RW EN接到任意两个口

读写操作的时序图如下:

读操作时序:

写操作时序

时序时间值 

写命令


/**
 * 函    数:LCD1602写命令
 * 参    数:Command 要写入的命令
 * 返 回 值:无
 */
void LCD_WriteCommand(unsigned char Command)
{
	LCD_RS=0;
	LCD_RW=0;
	LCD_DataPort=Command;
	LCD_EN=1;
	LCD_Delay();
	LCD_EN=0;
	LCD_Delay();
}

 写数据


/**
 * 函    数:LCD1602写数据
 * 参    数:Data 要写入的数据
 * 返 回 值:无
 */
void LCD_WriteData(unsigned char Data)
{
	LCD_RS=1;
	LCD_RW=0;
	LCD_DataPort=Data;
	LCD_EN=1;
	LCD_Delay();
	LCD_EN=0;
	LCD_Delay();
}

初始化


/**
 * 函    数:LCD1602初始化函数
 * 参    数:无
 * 返 回 值:无
 */
void LCD_Init()
{
	LCD_WriteCommand(0x38);//八位数据接口,两行显示,5*7点阵
	LCD_WriteCommand(0x0c);//显示开,光标关,闪烁关
	LCD_WriteCommand(0x06);//数据读写操作后,光标自动加一,画面不动
	LCD_WriteCommand(0x01);//光标复位,清屏
}

三,创建Keil项目

详细参考:51单片机STC89C52RC——创建Keil项目-CSDN博客

四,代码 

main.c

#include <REGX52.H>
#include "LCD1602.h" 
/**
 * 函    数:主函数
 * 参    数:无
 * 返 回 值:无
 */
void main()
{	
	LCD_Init();
	LCD_ShowString(1,1,"Hello LCD1602");
	while(1)
	{
	
	}
}

LCD1602.c

#include <REGX52.H>

//引脚配置:
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
#define LCD_DataPort P0

/**
 * 函    数:LCD1602延时函数,12MHz调用可延时1ms
 * 参    数:无
 * 返 回 值:无
 */
void LCD_Delay()
{
	unsigned char i, j;

	i = 2;
	j = 239;
	do
	{
		while (--j);
	} while (--i);
}
/**
 * 函    数:LCD1602写命令
 * 参    数:Command 要写入的命令
 * 返 回 值:无
 */
void LCD_WriteCommand(unsigned char Command)
{
	LCD_RS=0;
	LCD_RW=0;
	LCD_DataPort=Command;
	LCD_EN=1;
	LCD_Delay();
	LCD_EN=0;
	LCD_Delay();
}
/**
 * 函    数:LCD1602写数据
 * 参    数:Data 要写入的数据
 * 返 回 值:无
 */
void LCD_WriteData(unsigned char Data)
{
	LCD_RS=1;
	LCD_RW=0;
	LCD_DataPort=Data;
	LCD_EN=1;
	LCD_Delay();
	LCD_EN=0;
	LCD_Delay();
}
/**
 * 函    数:LCD1602设置光标位置
 * 参    数:Line 行位置,范围:1~2
 * 返 回 值:Column 列位置,范围:1~16
 */
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
	if(Line==1)
	{
		LCD_WriteCommand(0x80|(Column-1));
	}
	else if(Line==2)
	{
		LCD_WriteCommand(0x80|(Column-1+0x40));
	}
}
/**
 * 函    数:LCD1602初始化函数
 * 参    数:无
 * 返 回 值:无
 */
void LCD_Init()
{
	LCD_WriteCommand(0x38);//八位数据接口,两行显示,5*7点阵
	LCD_WriteCommand(0x0c);//显示开,光标关,闪烁关
	LCD_WriteCommand(0x06);//数据读写操作后,光标自动加一,画面不动
	LCD_WriteCommand(0x01);//光标复位,清屏
}
/**
 * 函    数:在LCD1602指定位置上显示一个字符
 * 参    数:	Line 行位置,范围:1~2,
 *				Column 列位置,范围:1~16,
 *				Char 要显示的字符
 * 返 回 值:无
 */
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
{
	LCD_SetCursor(Line,Column);
	LCD_WriteData(Char);
}
/**
 * 函    数:在LCD1602指定位置开始显示所给字符串
 * 参    数:	Line 起始行位置,范围:1~2,
 * 				Column 起始列位置,范围:1~16,
 *				String 要显示的字符串
 * 返 回 值:无
 */
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=0;String[i]!='\0';i++)
	{
		LCD_WriteData(String[i]);
	}
}
/**
 * 函    数:返回值=X的Y次方
 * 参    数:X底数,Y指数
 * 返 回 值:X的Y次方
 */
int LCD_Pow(int X,int Y)
{
	unsigned char i;
	int Result=1;
	for(i=0;i<Y;i++)
	{
		Result*=X;
	}
	return Result;
}
/**
 * 函    数:在LCD1602指定位置开始显示所给数字
 * 参    数:	Line 起始行位置,范围:1~2
 *				Column 起始列位置,范围:1~16
 *				Number 要显示的数字,范围:0~65535
 *				Length 要显示数字的长度,范围:1~5
 * 返 回 值:无
 */
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');
	}
}
/**
 * 函    数:在LCD1602指定位置开始以有符号十进制显示所给数字
 * 参    数:	Line 起始行位置,范围:1~2
 *				Column 起始列位置,范围:1~16
 *				Number 要显示的数字,范围:-32768~32767
 *				Length 要显示数字的长度,范围:1~5
 * 返 回 值:无
 */
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)
{
	unsigned char i;
	unsigned int Number1;
	LCD_SetCursor(Line,Column);
	if(Number>=0)
	{
		LCD_WriteData('+');
		Number1=Number;
	}
	else
	{
		LCD_WriteData('-');
		Number1=-Number;
	}
	for(i=Length;i>0;i--)
	{
		LCD_WriteData(Number1/LCD_Pow(10,i-1)%10+'0');
	}
}
/**
 * 函    数:在LCD1602指定位置开始以十六进制显示所给数字
 * 参    数:	Line 起始行位置,范围:1~2
 *				Column 起始列位置,范围:1~16
 *				Number 要显示的数字,范围:0~0xFFFF
 *				Length 要显示数字的长度,范围:1~4
 * 返 回 值:无
 */
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i,SingleNumber;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		SingleNumber=Number/LCD_Pow(16,i-1)%16;
		if(SingleNumber<10)
		{
			LCD_WriteData(SingleNumber+'0');
		}
		else
		{
			LCD_WriteData(SingleNumber-10+'A');
		}
	}
}
/**
 * 函    数:在LCD1602指定位置开始以二进制显示所给数字
 * 参    数:	Line 起始行位置,范围:1~2
 *				Column 起始列位置,范围:1~16
 *				Number 要显示的数字,范围:0~1111 1111 1111 1111
 *				Length 要显示数字的长度,范围:1~16
 * 返 回 值:无
 */
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		LCD_WriteData(Number/LCD_Pow(2,i-1)%2+'0');
	}
}

 LCD1602.h

#ifndef __LCD1602_H__
#define __LCD1602_H__

//用户调用函数:
void LCD_Init();
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char);
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String);
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length);
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);

#endif

五,代码编译、下载到51单片机

代码编译请参考

《51单片机STC89C52RC——代码编译-CSDN博客》

代码下载请参考

《51单片机STC89C52RC——STCAI-ISP代码下载-CSDN博客》

六,效果

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据库精选题(二)(引言+关系代数)

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;数据库 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 前言 常见概念 一、什么是数据库&#xf…

面试突击:深入理解 Java 中的异常

本文已收录于&#xff1a;https://github.com/danmuking/all-in-one&#xff08;持续更新&#xff09; 前言 哈喽&#xff0c;大家好&#xff0c;我是 DanMu。今天想和大家聊聊 Java 中的异常。异常处理是一种重要的概念&#xff0c;因为程序总是会出现各种意料之外的问题&…

代码签名证书有什么作用?有哪些申请步骤?

代码签名证书是一种数字证书&#xff0c;它为软件开发者提供一种验证软件代码真实性和完整性的方法。通过使用代码签名证书&#xff0c;开发者可以确保他们的软件在发布后没有被篡改&#xff0c;并且用户可以信任软件的来源。 什么是代码签名证书&#xff1f; 代码签名证书是提…

同三维高清大屏多功能一体机简介——高清多能数字矩阵

产品简介 同三维高清多能数字矩阵&#xff08;硬件集软件于一体&#xff09;是依据当前高清视频正广泛应用于各类项目工程的整体形势而专门研发的、特点显著、优势诸多、极具创新性的专业级一体化监控产品。高清多能数字矩阵采用WINDOWS操作系统&#xff0c;基于高性能配置的刀…

换电脑后导入git本地仓库记录

导入本地仓库tig记录 换了新电脑&#xff0c;将旧电脑的数据盘查到新的笔记本之后发现&#xff0c;使用pycharm 读取不到本地的git提交记录了&#xff0c;我没有将本地git上传到远程仓库的习惯&#xff0c;这可抓马了&#xff0c;硬盘插回去的话也太麻烦了。试了 vscode 提示设…

【英伟达GPU的挑战者】Groq—AI大模型推理的革命者

目录 引言第一部分&#xff1a;Groq简介第二部分&#xff1a;Groq的特点与优势1、高性能推理加速2、近存计算技术3、专用ASIC芯片设计4、低延迟与高吞吐量5、成本效益分析6、易用性与集成性7、软件与硬件的协同设计 第三部分&#xff1a;Groq的使用指南1、准备工作2、简单使用样…

通过 Setapp 使用 240 多款 Mac 生产力工具以及 GPT-4o

Setapp 是一项革命性的订阅服务&#xff0c;可以使用 240 多款 Mac 应用程序的综合套件&#xff0c;并配有强大的人工智能助手。 通过 Setapp 为你的工作效率和生产力增添魔力。 Setapp 官网&#xff1a;访问&#xff08;提供 7 天试用&#xff09; Setapp 的主要功能 AI 助手…

高通安卓12-Input子系统

1.Input输入子系统架构 Input Driver(Input设备驱动层)->Input core(输入子系统核心层)->Event handler(事件处理层)->User space(用户空间) 2.getevent获取Input事件的用法 getevent 指令用于获取android系统中 input 输入事件&#xff0c;比如获取按键上报信息、获…

黑马苍穹外卖3 菜品管理 AOP+反射+阿里云OSS+基本增删改查

菜品管理 公共字段自动填充 对员工&#xff0c;菜品&#xff0c;套餐、、的设置时间等&#xff0c;导致代码冗余。 使用切面来为这些方法统一设置 枚举&#xff1a;标识当前操作的类型&#xff08;不同来类型操作的字段名不同&#xff09;。反射&#xff08;为公共字段赋值&a…

大模型自然语言生成自动驾驶可编辑仿真场景(其一 共十篇)

第一篇&#xff1a;LLM greater scene summarize 第二篇&#xff1a;LLM simulation Test effect 第三篇&#xff1a;LLM simulation driving scenario flow work 第四篇&#xff1a;LLM Algorithm flow description 第五篇&#xff1a;Configure the environment and back…

k8s离线部署nginx

1. 拉取nginx离线包到本地 sudo docker save nginx:latest -o nginx.tar 2. 导入nginx image到k8s命名空间中 sudo ctr -n k8s.io images import nginx.tar 3. 编辑nginx.yaml apiVersion: apps/v1 kind: Deployment metadata:name: nginx-deployment spec:selector:match…

yocto系列讲解[实战篇]94 - 添加libhybris库和测试示例

By: fulinux E-mail: fulinux@sina.com Blog: https://blog.csdn.net/fulinus 喜欢的盆友欢迎点赞和订阅! 你的喜欢就是我写作的动力! 目录 1. 概述2. 添加libhybris的recipe3.libhybris编译4.libhybris测试5.自制Android C++动态库6.自制Android C++动态库编译7.创建testhyb…

java基于ssm+jsp 高校二手交易平台

1前台首页功能模块 高校二手交易平台&#xff0c;在系统首页可以查看首页、商品信息、论坛信息、新闻资讯、我的、跳转到后台、客服等内容&#xff0c;如图1所示。 图1系统功能界面图 用户登录、用户注册&#xff0c;在注册页面可以填写账号、密码、姓名、手机、身份证等信息进…

故障诊断 | SABO-VMD-SVM轴承故障诊断(Matlab)

效果一览 文章概述 故障诊断 | SABO-VMD-SVM轴承故障诊断(Matlab) 模型描述 减法平均的优化算法(Subtraction-Average-Based Optimizer (SABO)),是于2023年提出的一种基于数学行为的智能优化算法,该算法具有寻优能力强,收敛速度快等特点。以最小包络熵、最小样本熵、最…

2024GLEE生活暨教育(上海)博览会,8月20-22日,国家会展中心(上海)

2024GLEE生活暨教育(上海)博览会将于8月20-22日在中国国家会展中心&#xff08;上海&#xff09;举行&#xff0c;博览会总面积近万平方米&#xff0c;设有美好生活和教育产品两大主力展区&#xff0c;全面覆盖婴幼儿、学龄前、小学、初中、高中、大学、中年、老年各个年龄段的…

机械师硬盘数据清空怎么办?机械师硬盘数据清空怎么恢复

机械师硬盘数据清空怎么恢复&#xff1f;随着数字化时代的到来&#xff0c;数据已成为我们生活和工作中不可或缺的一部分。然而&#xff0c;硬盘数据的意外清空往往会给我们带来极大的困扰。本文将探讨在机械师硬盘数据清空后&#xff0c;我们应该如何快速有效地恢复数据。 图片…

软件开发教学:在线教育系统源码解析及教育培训小程序搭建实战

本篇文章&#xff0c;笔者将以“从零开始的软件开发教学”为主题&#xff0c;详细解析在线教育系统的源码&#xff0c;并通过实际操作来搭建一个教育培训小程序。 一、在线教育系统概述 在线教育系统是一个综合性的网络平台&#xff0c;旨在通过互联网提供教育资源和服务。该系…

Docker开机自动重启及自动启动容器

Docker开机自动重启及自动启动容器 Windows开机自动重启设置容器自动启动 Windows开机自动重启 勾选 Start Docker Desktop when you sign in to your computer 设置容器自动启动 1.docker update 命令 Usage: docker update [OPTIONS] CONTAINER [CONTAINER...]Update co…

“迷你剧场新体验:探索短剧小程序系统的魅力!“

在移动互联网的时代背景下&#xff0c;短视频和短剧已经成为人们娱乐消费的新宠。短剧小程序系统&#xff0c;以其独特的互动形式、便捷的观看体验和丰富的内容生态&#xff0c;为迷你剧场带来了全新的体验。接下来将探讨这个系统的魅力所在&#xff0c;以及它如何改变着人们的…

plt绘制网格图

代码 obj "accu" for (epoch,lr) in config:with open(data/epoch_{}_lr_{}_Adam.pkl.format(epoch,lr),rb) as f:data pickle.load(f) plt.plot(range(1,epoch1),data[obj],labelflr{lr})plt.title(obj"-epoch") plt.xlabel("epoch"…