一、LCD 1602液晶显示
(1)引脚包括8条数据线、3条控制线和3条电源线,见表5-2。通过单片机向模块写入命令和数据,就可对显示方式和显示内容做出选择。
(2)2.LCD1602字符的显示及命令字:
显示字符首先要解决待显示字符的ASCII码产生。用户只需在C51程序中写入欲显示的字符常量或字符串常量,C51程序在编译后会自动生成其标准的ASCII码,然后将生成的ASCII码送入显示用数据存储器DDRAM,内部控制电路就会自动将该ASCII码对应的字符在LCD1602显示出来。 让液晶显示器显示字符,首先对其进行初始化设置:对有、无光标、光标移动方向、光标是否闪烁及字符移动方向等进行设置,才能获得所需显示效果。
对LCD 1602的初始化、读、写、光标设置、显示数据的指针设置等,都是单片机向LCD 1602写入命令字来实现。命令字见表5-3。
表5-3中11个命令功能说明如下:
命令1:清屏,光标返回地址00H位置(显示屏的左上方)。
命令2:光标返回到地址00H位置(显示屏的左上方)。
命令3:光标和显示模式设置。
I/D—地址指针加1或减1选择位。
I/D=1,读或写一个字符后地址指针加1;
I/D=0,读或写一个字符后地址指针减1。
S—屏幕上所有字符移动方向是否有效的控制位。
S=1,当写入一字符时,整屏显示左移(I/D=1)或右移(I/D=0);
S=0,整屏显示不移动。
命令4:显示开/关及光标设置。
D—屏幕整体显示控制位,D=0关显示,D=1开显示。
C—光标有无控制位,C=0无光标,C=1有光标。
B—光标闪烁控制位,B=0不闪烁,B=1闪烁。
命令5:光标或字符移位。
S/C—光标或字符移位选择控制位。
0:移动光标,1:移动显示的字符。
R/L—移位方向选择控制位。
0:左移,1:右移,
命令6:功能设置命令。
DL—传输数据的有效长度选择控制位。
1:8位数据线接口;0:4位数据线接口。
N—显示器行数选择控制位。
0:单行显示,1:两行显示。
F—字符显示的点阵控制位。
0:显示5×7点阵字符,1:显示5×10点阵字符。
命令7:CGRAM地址设置。
命令8:DDRAM地址设置。
LCD内部有一个数据地址指针,用户可通过它访问内部全部80字节的数据显示RAM。
命令格式:80H+地址码。其中,80H为命令码。
命令9:读忙标志或地址。
BF—忙标志。
1:LCD忙,此时LCD不能接受命令或数据;0:表示LCD不忙。
命令10:写数据。
命令11:读数据。
(3)LCD1602基本操作
LCD为慢显示器件,所以在写每条命令前,一定要查询忙标志位BF,即是否处于“忙”状态。如LCD正忙于处理其他命令,就等待;如不忙,则向LCD写入命令。标志位BF连接在8位双向数据线的D7位上。如果BF=0,表示LCD不忙;如果BF=1,表示LCD处于忙状态,需等待。
二、原理图:
三、源程序:
#include <reg51.h> // 包含8051寄存器定义的头文件
#include <intrins.h> // 包含内部函数的头文件,如_nop_()
#define uchar unsigned char // 定义uchar为unsigned char类型
#define uint unsigned int // 定义uint为unsigned int类型
#define out P3 // 定义P3口作为输出端口
sbit RS=P2^0; // 定义LCD的RS引脚连接到P2.0
sbit RW=P2^1; // 定义LCD的RW引脚连接到P2.0
sbit E=P2^2; // 定义LCD的E引脚连接到P2.0
// 函数声明
void check_busy(void); // 检查LCD忙标志的函数
void write_command(uchar com); // 向LCD写入命令的函数
void write_data(uchar dat); // 向LCD写入数据的函数
void string(uchar ad, uchar *s);// 在LCD指定位置显示字符串的函数
void lcd_test(void); // 测试LCD的函数(未实现)
void delay(uint); // 延时函数
void lcd_initial(void); // LCD初始化函数
void main(void) // 主函数
{
lcd_initial(); // 初始化LCD
while(1) // 无限循环
{
string(0x85,"Welcome"); // 在第一行第5列显示字符串"Welcome"
string(0xC2,"Ningbo CHINA"); // 在第二行第2列显示字符串"Ningbo CHINA"
delay(100); // 延时100毫秒
write_command(0x01); // 写入清屏命令
delay(100); // 延时100毫秒
}
}
void delay(uint j) // 延时函数
{
uchar i=250;
for(;j>0;j--) // 根据传入的j值进行循环延时
{
while(--i); // 内部循环延时
i=249;
while(--i); // 另一个内部循环延时
i=250;
}
}
void check_busy(void) // 检查LCD是否忙的函数
{
uchar dt;
do
{
dt=0xff;
E=0; // 使能信号拉低
RS=0; // RS信号拉低,表示操作指令寄存器
RW=1; // RW信号拉高,表示读操作
E=1; // 使能信号拉高,开始读取
dt=out; // 读取数据线上的状态
}while(dt&0x80); // 如果最高位为1(忙),则继续循环等待
E=0; // 使能信号拉低
}
void write_command(uchar com) // 向LCD写入命令的函数
{
check_busy(); // 检查LCD是否忙
E=0; // 使能信号拉低
RS=0; // RS信号拉低,表示操作指令寄存器
RW=0; // RW信号拉低,表示写操作
out=com; // 将命令写入数据线
E=1; // 使能信号拉高,开始写入
_nop_(); // 空操作,延时一个机器周期
E=0; // 使能信号拉低
delay(1); // 延时1毫秒
}
void write_data(uchar dat) // 向LCD写入数据的函数
{
check_busy(); // 检查LCD是否忙
E=0; // 使能信号拉低
RS=1; // RS信号拉高,表示操作数据寄存器
RW=0; // RW信号拉低,表示写操作
out=dat; // 将数据写入数据线
E=1; // 使能信号拉高,开始写入
_nop_(); // 空操作,延时一个机器周期
E=0; // 使能信号拉低
delay(1); // 延时1毫秒
}
void lcd_initial(void) // LCD初始化函数
{
write_command(0x38); // 设置LCD为8位两行显示,5×7点阵字符
write_command(0x0C); // 开整体显示,光标关,无黑块
write_command(0x06); // 设置光标右移
write_command(0x01); // 清屏
delay(1); // 延时1毫秒
}
void string(uchar ad, uchar *s) // 在LCD指定位置显示字符串的函数
{
write_command(ad); // 发送地址命令
while(*s>0) // 循环直到字符串结束
{
write_data(*s++); // 写入数据并移动指针
delay(100); // 延时100毫秒
}
}
四、仿真结果:
本次实验的代码相比于前几次的代码更多并且更难理解,其中最主要的是要学会LCD1602的工作原理、读写操作规定以及命令字。LCD是多种多样的,在实际应用中,应参考LCD的技术手册或数据手册来获取准确的操作指南。
五、思考题
1、LCD有哪些类型,各自的主要应用场合是什么?
答:TN,扭曲向列型:TN LCD是最基本的LCD技术,具有较低的成本和较快的响应时间。它们通常用于简单的数字或文字显示,如计算器、电子手表和低端笔记本电脑屏幕。
STN,超扭曲向列型:STN LCD提供了比TN更好的对比度和视角,但响应时间较慢。它们常用于早期的便携式设备,如掌上游戏机和早期的手机。
TFT,薄膜晶体管:TFT LCD是目前最常见的LCD技术,它通过每个像素上的薄膜晶体管来控制电流,从而实现高分辨率、高亮度和良好的色彩表现。TFT LCD广泛应用于电视、计算机显示器、智能手机和平板电脑等高端显示设备。
IPS,平面转换:IPS是一种改进的TFT技术,它提供了更宽的视角和更准确的颜色再现。IPS LCD常用于需要高色彩准确度的专业显示器和高端消费类电子产品。
VA,垂直排列:VA LCD提供了良好的对比度和深黑色水平,适用于家庭影院和高清电视。
OLED,有机发光二极管:虽然不是传统意义上的LCD,但OLED显示屏因其自发光特性而非常受欢迎,提供极高的对比度、鲜艳的色彩和快速的响应时间。OLED屏幕常用于高端智能手机、电视和可穿戴设备。
2、LCD初始化完成后,每次写命令、读写数据操作均需检测忙标志?如何检测忙标志?
答:(1)在LCD初始化完成后,为了确保数据能够正确无误地写入到LCD中,通常需要在每次写命令或读写数据之前检测忙标志。忙标志是LCD内部的一个状态信号,用来指示LCD是否正在处理前一个命令或数据。如果忙标志为高电平(1),则表示LCD正在忙碌,不能接受新的命令或数据;如果忙标志为低电平(0),则表示LCD已准备就绪,可以接收新的命令或数据。
(2)忙标志检测步骤
将数据总线(DB)清零。
将寄存器选择(RS)设为低电平,选择数据寄存器。
将读/写选择(RW)设为高电平,准备读取数据。
将使能信号(EN)设为高电平,启动读取操作。
读取数据总线(DB)上的值,并将其存储在变量中。
将使能信号(EN)设为低电平,结束读取操作。
检查读取的值,如果最高位(D7)为1,则表示LCD处于忙状态;如果最高位(D7)为0,则表示LCD处于空闲状态。