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

2023-11-03

如下图:红框就是LCD1602液晶显示屏,他是可插拔的,插上去后数码管就会乱码无效了,因为他两共用了MCU的8个P0口
在这里插入图片描述

LCD1602原理图
在这里插入图片描述
在这里插入图片描述
从上面两幅图可以看出来

  • LCD1602的LCD_D0~LCD_D7分别对应MCU的P00-P07
  • LCD1602的LCD_RS对应MCU的P26
  • LCD1602的LCD_RW对应MCU的P25
  • LCD1602的LCD_E对应MCU的P27

LCD1602的16个引脚
在这里插入图片描述

A在5*7点阵的字模
在这里插入图片描述
在这里插入图片描述
PC收到41H的代码后就去字模文件中将代表A字的这一组数据送到显卡去点亮屏幕上相应的点,你就看到“A”这个字符了。

LCD1602指令集:
在这里插入图片描述
显示A的步骤

  • 第一步:功能设置,八位数据接口,两行显示,5*7点阵,写指令0x38

  • 第二步:显示设置,显示开,光标关,闪烁关,写指令0x0c

  • 第三步:输入方式设置,数据读写操作后,光标自动加一,画面不动,写指令0x06

  • 第四步:清屏,写指令0x01

  • 第五步:设置光标位置,即DDRAM地址设置
    如果是第一行,写指令0x80|(col-1)
    如果是第二行,写指令0x80|(col-1+0x40)
    这里做下解释,如下图所示,LCD1602只能显示两行,每行16个。
    所以第一行写指令0x80|(col-1),假设col=1,即用户想在第一行第一列写数据,我们只需要写指令0x80|0x00即可,第一行第二列写数据,我们写指令0x80|0x01。
    在这里插入图片描述

  • 第六步:写A这个数据,把P0口直接赋值为A即可

例程:显示A
Delay.h

#ifndef __DELAY_H__
#define __DELAY_H__

void Delay(unsigned int xms);

#endif

Delay.c


void Delay(unsigned int xms)
{
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}

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

LCD1602.c

#include <REGX52.H>
#include <Delay.h>
//引脚配置:
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
#define LCD_DataPort P0


/**
  * @brief  LCD1602写命令
  * @param  Command 要写入的命令
  * @retval 无
  */
void LCD_WriteCommand(unsigned char Command)
{
	LCD_RS=0;
	LCD_RW=0;
	LCD_DataPort=Command;
	LCD_EN=1;
	Delay(1);
	LCD_EN=0;
	Delay(1);
}

/**
  * @brief  LCD1602写数据
  * @param  Data 要写入的数据
  * @retval 无
  */
void LCD_WriteData(unsigned char Data)
{
	LCD_RS=1;
	LCD_RW=0;
	LCD_DataPort=Data;
	LCD_EN=1;
	Delay(1);
	LCD_EN=0;
	Delay(1);
}

/**
  * @brief  LCD1602设置光标位置
  * @param  Line 行位置,范围:1~2
  * @param  Column 列位置,范围:1~16
  * @retval 无
  */
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));
	}
}

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

/**
  * @brief  在LCD1602指定位置上显示一个字符
  * @param  Line 行位置,范围:1~2
  * @param  Column 列位置,范围:1~16
  * @param  Char 要显示的字符
  * @retval 无
  */
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
{
	LCD_SetCursor(Line,Column);
	LCD_WriteData(Char);
}

/**
  * @brief  在LCD1602指定位置开始显示所给字符串
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  String 要显示的字符串
  * @retval 无
  */
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]);
	}
}

/**
  * @brief  返回值=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;
}

/**
  * @brief  在LCD1602指定位置开始显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~65535
  * @param  Length 要显示数字的长度,范围:1~5
  * @retval 无
  */
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');
	}
}

/**
  * @brief  在LCD1602指定位置开始以有符号十进制显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:-32768~32767
  * @param  Length 要显示数字的长度,范围:1~5
  * @retval 无
  */
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');
	}
}

/**
  * @brief  在LCD1602指定位置开始以十六进制显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~0xFFFF
  * @param  Length 要显示数字的长度,范围:1~4
  * @retval 无
  */
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');
		}
	}
}

/**
  * @brief  在LCD1602指定位置开始以二进制显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~1111 1111 1111 1111
  * @param  Length 要显示数字的长度,范围:1~16
  * @retval 无
  */
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');
	}
}

main.c

#include <REGX52.H>
#include "LCD1602.h"	//包含LCD1602头文件
void main()
{
	LCD_Init();
	LCD_ShowChar(1,1,'A');
}

结果:
在这里插入图片描述

百度网盘
51单片机系列文章所有文件内容都在此处
链接:https://pan.baidu.com/s/1iVir85WO_usDPxmyZ0qDIg
提取码:4spe

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

51单片机——LCD1602液晶显示屏 的相关文章

  • linux驱动37:kmalloc内存分配

    kmalloc和malloc类似 可被阻塞 分配的内存保持原有数据 分配的区域在物理内存中也是连续的 头文件
  • 卡尔曼滤波-卡尔曼滤波全篇讲解

    卡尔曼滤波 个人理解 两种信号 状态变量 按照人类经验预测的状态 观测变量 根据生活工具测量的实际状态 噪声 噪声分布 噪声表达 滤波器的计算原型 先验估计 后验估计与测量状态变量 计算增益系数K 数据融合基础变量 先验估计 测量状态变量
  • Apache Beam构建流处理任务

    最近做的一个项目需要用到Google云平台的Dataflow来进行数据处理 因此研究了一下相关的文档 了解到Dataflow是基于Apache beam来进行流程的编排 Beam支持多种不同的Runner 除了Dataflow Beam还支
  • 基于Docker安装及运行Mongodb

    1 拉取镜像 docker pull mongo latest 2 运行mongodb docker run itd name mongo p 27017 27017 mongo auth 3 进入mongodb容器 docker exec

随机推荐

  • 《只管去做》-如何做靠谱的年度计划

    五年后的一封信 调动五感去写 要找到怦然心动的感觉 世界上的人4种状态 空想家 这些人总是有很多想法 但真正落实去做的很少 回应者 这样的人对未来没有任何想法 对现状也没有掌控力 是一种混吃等死的状态 每一天都过得差不多 也安于现状 执行者
  • leecode刷题:1.两数之和

    给定一个整数数组 nums 和一个整数目标值 target 请你在该数组中找出 和为目标值 target 的那 两个 整数 并返回它们的数组下标 你可以假设每种输入只会对应一个答案 但是 数组中同一个元素在答案里不能重复出现 你可以按任意顺
  • Java基础:序列化与反序列化

    Java序列化是指把Java对象转换为字节序列的过程 而Java反序列化是指把字节序列恢复为Java对象的过程 序列化的使用场景 永久性保存对象 保存对象的字节序列到本地文件或者数据库中 通过序列化以字节流的形式使对象在网络中进行传递和接收
  • 2.移植uboot-添加2440单板,并实现NOR、NAND启动

    1 首先在uboot里新建单板2440 1 1将2410的单板文件夹拷贝成2440 cd board samsung cp smdk2410 smdk2440 rf 拷贝文件夹 然后将smdk2440下的smdk2410 c改为smdk24
  • 内存映射原理

    一 物理地址 物理地址是处理器在系统总线上看到的地址 使用RISC的处理器通常只实现一个物理地址空间 外围设备和物理内存使用统一的物理地址空间 有些处理器架构把分配给外围设备的物理地址区域称为设备内存 处理器通过外围设备控制器的寄存器访问外
  • springsecurity登录后返回token字符串和刷新token代码实例

    文章目录 1 登录接口 登陆成功则返回token 2 登录方法 3 刷新token的接口 4 生成token和刷新token的工具类 1 登录接口 登陆成功则返回token yml文件 jwt tokenHeader Authorizati
  • 特征选择relief算法介绍

    特征选择relief算法介绍 特征选择的基础了解 可以参考 一篇关于特征选择的博客 特征选择过程一般包括 特征子集产生过程 评价函数 停止准则 验证过程 1 特征子集选择过程 根据搜索过程的方法的不同 可以将特征选择分为穷举 启发式 随机几
  • clover引导修改默认启动

    不修改或配置不对默认就前面分区的windows了 config plist里如下就能默认启动macos了
  • 将CAD文件导入AD软件

    1 第一步 将cad中的dxf或dwg文件保存好 2 打开AD 新建PCB文件 3 点击左上角文件flie gt import导入 gt DXF DWG文件 4 选择DXF DWG打开 设置线宽 设置选择原点 选择PCB层 打开条件为ALL
  • 训练集(离线)与测试集(上线)效果差距很大怎么办?

    前言 相信各位童鞋在跑模型的时候时不时会遇到一个尴尬的现象 就是你在训练集或者验证集的模型效果好到令人发指 一时间以为 哼 就这 游戏结束 结果当你在测试集或者上线后发现真的就游戏结束了 指标低的没眼看 本人还是一个算法菜鸟时就遇到过这种情
  • Go语言编程思想6——Channel

    Go语言编程思想6 Channel Channel goroutine和goroutine之间双向的通道 一 基本语法 创建int类型的channel c make chan int 发送数据 c lt 1 接受数据 n lt c func
  • OpenMV激光打靶

    题目要求识别形状并且键盘设置控制激光笔走A B C等轨道 OpenMV需要识别图形形状 激光笔位置 以及提高要求中的识别形状的面积等 这里介绍一下识别激光的方法 主要使用的是色块识别 但是激光点面积很小 而且在黑色区域容易被吞掉 因此对图像
  • 可自动读取水果成熟度的ai识别系统

    基于5G的水果成熟判断及采收系统 背景技术 随着物流和国际贸易经济的快速发展 国内外水果生产 储运和销售市场越来越大 目前 北果南运 南果北运以及外果内运已占物流运输的近半江山 目前 在水果采摘 储运和销售过程中常会出现一些问题 比如 为了
  • 推荐系统公平性论文阅读(五)

    这几天我的主要任务是对论文 Towards Long term Fairness in Recommendation 1 中所描述的算法进行编程实现 然后测试该算法的效果并记录 以下分模型算法细节实现 数据集 模型评估准则 测试结果记录四个
  • vue 自定义 el-cascader 展示文字及样式

    首先 自定义 popper class 因为设置的样式需要全局设置才生效 使用定义的类 可以避免影响到其他页面的效果
  • 第十七篇 PyTorch学习率调整策略

    文章目录 摘要 1 对不同层设置不同的学习率 应用举例 2 等间隔调整学习率 StepLR 应用举例 3 按需调整学习率 MultiStepLR 应用举例 4 指数衰减调整学习率 ExponentialLR 应用举例 5 余弦退火调整学习率
  • nvm安装node.js失败原因之一

    最近真的是频繁的换电脑 每次都要重新配置环境 然后同一个坑踩两次 哈哈哈 还是写一个记录一下吧 1 第一步是在给官网下载nvm安装包然后next一路安装 2 第二步使用nvm install 版本号 安装node js 然后就出现问题咯 然
  • M.2接口NVMe SSD固态硬盘安装win10

    M 2接口NVMe SSD固态硬盘使用了新接口 所以目前市面上的U盘win pe系统基本都不能识别硬盘 无法安装 但 win10原生系统默认能够识别NVMe固态盘的 所以 我们可以从微软官网https www microsoft com z
  • 大数据电商数据仓库系统搭建 附离线安装包

    一 数仓理论 1 数据仓库概念 数据仓库 Data Warehouse 是为企业所有决策制定过程 提供所有系统数据支持的战略集合 通过对数据仓库中数据的分析 可以帮助企业 改进业务流程 控制成本 提高产品质量等 数据仓库 并不是数据的最终目
  • 51单片机——LCD1602液晶显示屏

    如下图 红框就是LCD1602液晶显示屏 他是可插拔的 插上去后数码管就会乱码无效了 因为他两共用了MCU的8个P0口 LCD1602原理图 从上面两幅图可以看出来 LCD1602的LCD D0 LCD D7分别对应MCU的P00 P07