快速掌握

您所在的位置:网站首页 源程序例子 快速掌握

快速掌握

2023-07-14 19:35| 来源: 网络整理| 查看: 265

快速掌握—— LCD1602液晶显示 一、 LCD1602 简介实物图:Proteus器件图:简介:引脚介绍:指令集(11条指令): 二、显示原理字模库: 三、显示位置四、LCD1602 操作①写操作时序图:②读操作时序图:③时序时间参数:1、忙检测为什么需要忙检测??代码: 2、初始化为什么初始化?代码: 3、写命令代码: 4、写数据代码: 实验一:显示Hello World !结果展示:代码: 实验二:两行显示结果展示:代码: 实验三:温度单位显示确定字模:结果展示:代码: 实验四:单行滚动显示结果展示:代码: 实验五:一行不动,一行动结果展示:代码: 实验六:自定义字模显示确定字模:结果展示:代码:

一、 LCD1602 简介

简介部分资料来源于百度百科:

实物图:

在这里插入图片描述

Proteus器件图:

器件号: LM016L

在这里插入图片描述

简介:

LCD1602

16——表示每行显示16个字符 02——表示显示两行

LCD1602是一种字符点阵型显示模块,如下图 ,每个字符是由 5X8 的点阵组成。 在这里插入图片描述

引脚介绍:

这里是引用

引脚1:VSS为地电源。 引脚2:VDD接5V正电源。 引脚3:VL为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高。

引脚4:RS为寄存器选择脚,高电平时选择数据寄存器、低电平时选择指令寄存器。

引脚5:R/W为读/写信号线,高电平时进行读操作,低电平时进行写操作。 当RS和R/W共同 为低电平时可以写入指令或显示地址;当RS为低电平,R/W为高电平时,可以读忙信号;当 RS为高电平,R/W为低电平时,可以写入数据。

引脚6:E端为使能端,当E端由高电平跳变为低电平时(下降沿有效),液晶模块执行命令。

引脚7 ~ 14:D0~D7为8位双向数据线。

引脚15:背光源正极。 引脚16:背光源负极

指令集(11条指令):

表1这里是引用

(1)指令1:清屏。指令码01H,光标复位到地址00H。

(2)指令2:光标复位。光标复位到地址00H。

(3)指令3:输入方式设置。 其中,I/D表示光标的移动方向,高电平右移,低电平左移;S表示显示屏上所有文字是否左移或右移,高电平表示有效,低电平表示无效。

(4)指令4:显示开关控制。 其中,D用于控制整体显示的开与关,高电平表示开显示,低电平表示关显示;C用于控制光标的开与关,高电平表示有光标,低电平表示无光标;B用于控制光标是否闪烁,高电平闪烁,低电平不闪烁。

(5)指令5:光标或字符移位控制。 其中,S/C表示在高电平时移动显示的文字,低电平时移动光标。

(6)指令6:功能设置命令。 其中,DL表示在高电平时为4位总线,低电平时为8位总线;N表示在低电平时为单行显示,高电平时双行显示;F表示在低电平时显示5×7的点阵字符,高电平时显示5×10的点阵字符。

(7)指令7:字符发生器RAM地址设置。

(8)指令8:DDRAM地址设置。

(9)指令9:读忙信号和光标地址。 其中,BF为忙标志位,高电平表示忙,此时模块不能接收命令或数据,如果为低电平则表示不忙。

(10)指令10:写数据。

(11)指令11:读数据。

常用指令:

0x80+0xdd:dd为地址,这条命令用于设置显示起点坐标

0x0c :开显示,无光标,光标不闪烁 。一般做带键盘输入的才加入光标,如计算器。常用的计量显示不显示光标。

0x06 :写一个数据,地址指针加1,由1602地址表可以看出,实际上就是设置成从左往右写数据而已。

0x38 : 设置显示模式,16x2显示 5x7点阵,8位数据接口。端口不够用时,这个命令也可以换用4位数据接口的。

0x01 :清屏。

表2在这里插入图片描述

二、显示原理

在这里插入图片描述

如上图,每个字符由 5X8 点阵组成(也可选用 5X10),想要实现显示,只需如下图:

例:以 5X7 点阵为例, 显示字符 A

0 代表灭,1 代表亮 只需将想要显示的字符的对应位置1,就能显示该字符 在这里插入图片描述

LCD1602 固化了字模寄存器,即 CGROM 和 CGRAM,存储了192个常用字符的字模。

字模库:

该表 行是低四位,列是高四位

想要显示哪个字符,只需查表,换算为十六进制,写入LCD1602即可。 在这里插入图片描述

例: 想要显示字符 A

需要向 LCD1602 写入 0x41(0100 0001)

三、显示位置

LCD1602 实际有80个字节的DDRAM,

只不过 LCD1602 只有 16X2 个位置,后面很多位置显示不出来,可以使用 指令5“光标或显示移动指令” 使字符慢慢移动到可见的显示范围内,看到字符的移动效果。

所以LCD1602的实际显示位置是,第一行:00 ~ 0F,第二行:40 ~ 4F 在这里插入图片描述

注意:

如图, 指令8,D7位恒为 1,

在实际向LCD1602传入数据显示地址时,需要 < 地址+0x80 >

例:向LCD1602的第一行第一列写数据,传入的地址应为: (0x00+0x80) 在这里插入图片描述

四、LCD1602 操作 ①写操作时序图:

在这里插入图片描述

②读操作时序图:

在这里插入图片描述

③时序时间参数:

在这里插入图片描述

1、忙检测 为什么需要忙检测??

单片机和 LCD1602 的工作速度存在差异,单片机速度快,所以单片机向 LCD1602 传数据时,LCD1602 可能正在处理上一次的数据,处在忙状态,为了防止数据丢失或出错,所以单片机就需要等待,待 LCD1602 处理完时在进行下一次数据的传送。

代码:

由指令9,需判断 BF 的状态

/****************** 忙检测 ********************* LCD_Data 与 0x80 进行或运算,判断 bit7 位状态 若 LCD_Data 的 bit7 位是 0,则 LCD 不忙 若 LCD_Data 的 bit7 位是 1,则 LCD 忙 ***********************************************/ void LCD_Check_Busy(){ uchar temp; LCD_Data = 0xff // 十六进制:1111 1111 LCD_RS = 0; // 0 指令 LCD_RW = 1; // 1 读 do{ LCD_E = 1; // 拉高 temp = LCD_Data; // 将 LCD 状态保存在 temp 中,用于判忙 LCD_E = 0; // 负跳变使能 }while(temp & 0x80); // 结果为 1,LCD 忙,继续循环;结果为 0,LCD 不忙,可以进行后面的操作 } 2、初始化 为什么初始化?

在 LCD1602 进行显示前,需要进行输入方式设置,显示开关设置,光标、画面移位设置,功能设置等,确定 LCD1602 的工作方式。

代码: /****************** 初始化 ********************* 指令1 ——清屏 指令3 ——AC加1,画面不动 指令4 ——显示开,光标关,闪烁关 指令6 ——8位数据接口,两行显示,5X7点阵 指令8 ——从第一行第一列开始显示 ***********************************************/ void LCD_Init(){ LCD_Write_Cmd(0x01); // 指令1 ——清屏 LCD_Write_Cmd(0x06); // 指令3 ——AC加1,画面不动 LCD_Write_Cmd(0x0c); // 指令4 ——显示开,光标关,闪烁关 LCD_Write_Cmd(0x38); // 指令6 ——8位数据接口,两行显示,5X7点阵 LCD_Write_Cmd(0x80); // 指令8 ——从第一行第一列开始显示 } 3、写命令 代码: /****************** 写命令 ********************* RS=0 指令 RW=0 写操作 E=0 开始为 0 写入指令(给单片机 P3 端口) 延时 2ms E=1 拉高 延时5ms,写入指令有效 E=0 负跳变,指令写入LCD ***********************************************/ void LCD_Write_Cmd(uchar Cmd){ LCD_Check_Busy(); // 判忙 LCD_RS = 0; // 0 指令 LCD_RW = 0; // 0 写 LCD_E = 0; LCD_Data = Cmd; // 送指令 delay_1ms(2); LCD_E = 1; // 拉高 delay_1ms(5); LCD_E = 0; } 4、写数据 代码: /****************** 写数据 ********************* RS=1 数据 RW=0 写操作 E=0 开始为 0 写入数据(给单片机 P3 端口) 延时 2ms E=1 拉高 延时 7ms,写入数据有效 E=0 负跳变,数据写入LCD ***********************************************/ void LCD_Write_Data(uchar Data){ LCD_Check_Busy(); // 判忙 LCD_RS = 1; // 1 数据 LCD_RW = 0; // 0 写 LCD_E = 0; LCD_Data = Data; // 送数据 delay_1ms(2); LCD_E = 1; // 拉高 delay_1ms(7); LCD_E = 0; } 实验一:显示Hello World ! 结果展示:

在这里插入图片描述

代码: #include #define uchar unsigned char #define uint unsigned int #define LCD_Data P3 // 数据端口 sbit LCD_RS = P2^0; // 数据(1)/ 指令(0) sbit LCD_RW = P2^1; // 读(1) / 写(0) sbit LCD_E = P2^2; // 使能(负跳变起作用) void delay_1ms(uint c){ // 延时函数,无误差 uchar a,b; for(;c>0;c--) { for(b=199;b>0;b--) { for(a=1;a>0;a--); } } } /****************** 忙检测 ********************* LCD_Data 与 0x80 进行或运算,判断 bit7 位状态 若 LCD_Data 的 bit7 位是 0,则 LCD 不忙 若 LCD_Data 的 bit7 位是 1,则 LCD 忙 ***********************************************/ void LCD_Check_Busy(){ uchar temp; LCD_Data = 0xff; // 十六进制:1111 1111 LCD_RS = 0; // 0 指令 LCD_RW = 1; // 1 读 do{ LCD_E = 1; // 拉高 temp = LCD_Data; // 将 LCD 状态保存在 temp 中,用于判忙 LCD_E = 0; // 负跳变使能 }while(temp & 0x80); // 结果为 1,LCD 忙,继续循环;结果为 0,LCD 不忙,可以进行后面的操作 } /****************** 写指令 ********************* RS=0 指令 RW=0 写操作 E=0 开始为 0 写入指令(给单片机 P3 端口) 延时 2ms E=1 拉高 延时5ms,写入指令有效 E=0 负跳变,指令写入LCD ***********************************************/ void LCD_Write_Cmd(uchar Cmd){ LCD_Check_Busy(); // 判忙 LCD_RS = 0; // 0 指令 LCD_RW = 0; // 0 写 LCD_E = 0; LCD_Data = Cmd; // 送指令 delay_1ms(2); LCD_E = 1; delay_1ms(5); LCD_E = 0; } /****************** 写数据 ********************* RS=1 数据 RW=0 写操作 E=0 开始为 0 写入数据(给单片机 P3 端口) 延时 2ms E=1 拉高 延时 7ms,写入数据有效 E=0 负跳变,数据写入LCD ***********************************************/ void LCD_Write_Data(uchar Data){ LCD_Check_Busy(); // 判忙 LCD_RS = 1; // 1 数据 LCD_RW = 0; // 0 写 LCD_E = 0; LCD_Data = Data; // 送数据 delay_1ms(2); LCD_E = 1; delay_1ms(7); LCD_E = 0; } /****************** 初始化 ********************* 指令1 ——清屏 指令3 ——AC加1,画面不动 指令4 ——显示开,光标关,闪烁关 指令6 ——8位数据接口,两行显示,5X7点阵 指令8 ——从第一行第一列开始显示 ***********************************************/ void LCD_Init(){ LCD_Write_Cmd(0x01); // 指令1 ——清屏 LCD_Write_Cmd(0x06); // 指令3 ——AC加1,画面不动 LCD_Write_Cmd(0x0c); // 指令4 ——显示开,光标关,闪烁关 LCD_Write_Cmd(0x38); // 指令6 ——8位数据接口,两行显示,5X7点阵 LCD_Write_Cmd(0x80); // 指令8 ——从第一行第一列开始显示 } /****************** 主函数 ********************* ***********************************************/ void main() { uchar code Data[]="Hello World !"; // 要显示的数据 uchar i; LCD_Init(); // LCD1602 初始化 LCD_Write_Cmd(0x00+0x80); // 第一行第一列地址,0x00 可以省去,为了讲明白故加上 for(i=0; i // 延时函数,无误差 uchar a,b; for(;c>0;c--) { for(b=199;b>0;b--) { for(a=1;a>0;a--); } } } /****************** 忙检测 ********************* LCD_Data 与 0x80 进行或运算,判断 bit7 位状态 若 LCD_Data 的 bit7 位是 0,则 LCD 不忙 若 LCD_Data 的 bit7 位是 1,则 LCD 忙 ***********************************************/ void LCD_Check_Busy(){ uchar temp; LCD_Data = 0xff; // 十六进制:1111 1111 LCD_RS = 0; // 0 指令 LCD_RW = 1; // 1 读 do{ LCD_E = 1; // 拉高 temp = LCD_Data; // 将 LCD 状态保存在 temp 中,用于判忙 LCD_E = 0; // 负跳变使能 }while(temp & 0x80); // 结果为 1,LCD 忙,继续循环;结果为 0,LCD 不忙,可以进行后面的操作 } /****************** 写指令 ********************* RS=0 指令 RW=0 写操作 E=0 开始为 0 写入指令(给单片机 P3 端口) 延时 2ms E=1 拉高 延时5ms,写入指令有效 E=0 负跳变,指令写入LCD ***********************************************/ void LCD_Write_Cmd(uchar Cmd){ LCD_Check_Busy(); // 判忙 LCD_RS = 0; // 0 指令 LCD_RW = 0; // 0 写 LCD_E = 0; LCD_Data = Cmd; // 送指令 delay_1ms(2); LCD_E = 1; delay_1ms(5); LCD_E = 0; } /****************** 写数据 ********************* RS=1 数据 RW=0 写操作 E=0 开始为 0 写入数据(给单片机 P3 端口) 延时 2ms E=1 拉高 延时 7ms,写入数据有效 E=0 负跳变,数据写入LCD ***********************************************/ void LCD_Write_Data(uchar Data){ LCD_Check_Busy(); // 判忙 LCD_RS = 1; // 1 数据 LCD_RW = 0; // 0 写 LCD_E = 0; LCD_Data = Data; // 送数据 delay_1ms(2); LCD_E = 1; delay_1ms(7); LCD_E = 0; } /****************** 初始化 ********************* 指令1 ——清屏 指令3 ——AC加1,画面不动 指令4 ——显示开,光标关,闪烁关 指令6 ——8位数据接口,两行显示,5X7点阵 指令8 ——从第一行第一列开始显示 ***********************************************/ void LCD_Init(){ LCD_Write_Cmd(0x01); // 指令1 ——清屏 LCD_Write_Cmd(0x06); // 指令3 ——AC加1,画面不动 LCD_Write_Cmd(0x0c); // 指令4 ——显示开,光标关,闪烁关 LCD_Write_Cmd(0x38); // 指令6 ——8位数据接口,两行显示,5X7点阵 LCD_Write_Cmd(0x80); // 指令8 ——从第一行第一列开始显示 } /****************** 主函数 ********************* ***********************************************/ void main() { uchar code Data_1[]="0123456789012345"; // 第一行要显示的数据 uchar code Data_2[]="abcdefghABCDEFGH"; // 第二行要显示的数据 uchar i; LCD_Init(); // LCD1602 初始化 LCD_Write_Cmd(0x00+0x80); // 第一行第一列地址 for(i=0; i LCD_Write_Data(Data_2[i]); } while(1); } 实验三:温度单位显示 确定字模:

如图,查字模表得: 温度单位由 1101 1111 和 0100 0011 组成 换算位十六进制为:0xdf 和 0x43 组成 在这里插入图片描述

结果展示:

在这里插入图片描述

代码:

直接替换为以下主函数即可

/****************** 主函数 ********************* ***********************************************/ void main() { LCD_Init(); // LCD1602 初始化 LCD_Write_Cmd(0x00+0x80); // 第一行第一列地址 LCD_Write_Data(0xdf); LCD_Write_Data(0x43); while(1); } 实验四:单行滚动显示

**要求:**在第一行滚动显示字符串 “Good Good Study,Day Day Up !”

需要用到 指令5——0x18 //画面左移一个字符位,光标不动

结果展示:

在这里插入图片描述

代码:

直接替换位为以下主函数即可

/****************** 主函数 ********************* ***********************************************/ void main() { uchar i; uchar code Data[]="Good Good Study,Day Day Up !"; LCD_Init(); // LCD1602 初始化 LCD_Write_Cmd(0x00+0x80); // 第一行第一列地址 for(i=0; i delay_1ms(500); // 控制移动速度 LCD_Write_Cmd(0x18); // 指令5 ——画面左移一个字符位,光标不动 } } 实验五:一行不动,一行动

要求: 第一行显示 " I Love You “,固定不动 第二行显示"Good Good Study,Day Day Up !”, 实现向左移动效果

结果展示:

在这里插入图片描述

代码:

直接替换位为以下主函数即可

/****************** 主函数 ********************* 不使用整屏左移命令 使用指针进行右移 ***********************************************/ void main() { uchar i, j=0, n=0; uchar code Data_1[]=" I Love You "; // 第一行显示,共十六个字符 uchar code Data_2[]="Good Good Study,Day Day Up !"; // 第二行显示,共28个字符 LCD_Init(); // LCD1602 初始化 LCD_Write_Cmd(0x00+0x80); // 第一行第一列地址 for(i=0; i LCD_Check_Busy(); // 判忙,若忙,不继续执行 LCD_Write_Cmd(0x40+0x80); // 第二行第一列地址 for(j=n; j // 当数据移动到最后时,n 重置 0,停顿 500 ms,重新开始移动显示 n = 0; delay_1ms(500); } delay_1ms(200); // 控制移动速度 } } 实验六:自定义字模显示

要求: 自定义数模 在第一行第一列显示汉字 ——年 在第一行第三列显示汉字 ——月 在第一行第五列显示汉字 ——日

确定字模:

以 日 字为例 在这里插入图片描述

结果展示:

在这里插入图片描述

代码:

直接替换位为以下主函数即可

/****************** 主函数 ********************* ***********************************************/ void main(){ uchar i; uchar code Data_0[]={0x0f, 0x12, 0x0f, 0x0a, 0x1f, 0x02, 0x02, 0x02}; // 汉字 年 的字模 uchar code Data_1[]={0x0f, 0x09, 0x0f, 0x09, 0x0f, 0x09, 0x0b, 0x11}; // 汉字 月 的字模 uchar code Data_2[]={0x1f, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x1f, 0x00}; // 汉字 日 的字模 LCD_Init(); // LCD1602 初始化 LCD_Write_Cmd(0x40); // 0100 0000; 指令 0x40 向 CGRAM 地址0 写入自定义数据 for(i=0; i LCD_Write_Data(Data_1[i]); // 写入自定义字符字模 } LCD_Write_Cmd(0x50); // 0101 0000; 指令 0x50 向 CGRAM 地址2 写入自定义数据 for(i=0; i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3