LCD1602原理与应用
LCD1602原理
写程序要遵循硬件电路->硬件接口->软件编程三部分。
LCD1602可以显示2行16个字符,用用16个引脚,主要控制端口为RS,R/W,EN。
通过RS,R/W可以选择不同的读写操作:
| RS | R/W | 操作 |
|---|---|---|
| 0 | 0 | 写命令 |
| 0 | 1 | 读取BUSY Flag及AC地址 |
| 1 | 0 | 写数据 |
| 1 | 1 | 读数据 |
结合EN,可分为下面三种操作:
读Flag:RS=0,RW=1,EN高电平
写命令:RS=0,RW=0,EN高脉冲
写数据:RS=1,RW=0,EN高脉冲
LCD1602的时序图
写操作:

根据RS的不同,写操作分为写指令和写数据两种:
- 写指令:
- RS置为0
- R/W置为0
- EN置为0
- 输入CMD
- 延时
- EN置为1
- 延时
- EN置为0
- 写数据:
- RS置为1
- R/W置为0
- EN置为0
- 输入DAT
- 延时
- EN置为1
- 延时
- EN置为0
读操作一般不常见,因此在本文中就不提及了。
LCD1602的常用指令

数据指针:指令码为0x80+地址码,地址码范围为0x00-0x27,0x40-0x67。
整屏左移:0x18
整屏右移:0x1c
根据常用指令,需要先将LCD1602初始化:
- 写指令0x38:表示为8位数据,两行显示,5*7点阵
- 延时
- 写入0x38,显示模式设置
- 写指令0x0f:显示开关控制
- 写指令0x06:输入方式
LCD1602在单片机上的原理图

LCD实验
Q:初始化和写数据/指令完成之后,进行测试,第一位出现空白,即字符从第二位开始
A:数据指针需要初始化。在初始化中加入写指令0x80(数据地址为0x80)
PS:同时为了防止一开始LCD就显示多余的数据,在写数据地址指令前,加入清屏指令,即写指令0x01.
Q:写入数据之后,该字符不停的闪烁。
A:忘记加 while(1);该语句的功能是保持LCD的设置不变。
1. LCD显示一行字符
初始化完成之后,只需要按顺序输出字符就可:
for(i =0;i<11;i++){
Write_Data(table[i]);
Delay(1);
}
2. LCD显示两行字符
跟实验1基本步骤一致,但是需要显示第二行前,把位置指针指向0x80+0x40,即第二行的位置
3. LCD移位
需要先将LCD显示的字符放置到显示屏的后端,然后再通过左移指令进行整体左移:
Write_Cmd(0x80+0x13);
for(i =0;i<11;i++){
Write_Data(table[i]);
Delay(1);
}
Write_Cmd(0xc0+0x13);
for(i =0;i<10;i++){
Write_Data(second[i]);
Delay(1);
}
for(i = 0;i<16;i++){
Write_Cmd(0x18);
Delay(500);
}
while(1);
4. 完成动态LCD,实现动态秒表
思路:用定时器来确定时长,然后记录秒数,再通过LCD动态显示
#include <REGX52.H>
#include "Delay.h"
#define uchar unsigned char
#define uint16 unsigned int
sbit RW = P2^5;
sbit RS = P2^6;
sbit EN = P2^7;
uchar cnt=0;
uchar num,min,sec1,sec2;
void display(uchar min,sec1,sec2);
void Write_Cmd(uchar command){
RS = 0;
RW = 0;
Delay(1);
P0 = command;
Delay(1);
EN = 1;
Delay(5);
EN =0;
}
void Write_Data(uchar dat){
RS = 1;
RW = 0;
Delay(1);
P0 = dat;
Delay(1);
EN = 1;
Delay(5);
EN =0;
}
void Timer0Init(){
TMOD =0x01;
TL0 = 0XCD;
TH0 = 0XD4;
EA = 1;
ET0 = 1;
TR0 = 1;
}
void Init(){
EN = 0;
Delay(1);
Write_Cmd(0x38);
Write_Cmd(0x0e);
Write_Cmd(0x06);
Write_Cmd(0x01);
Write_Cmd(0x80);
Delay(1);
}
void main(){
Timer0Init();
Init();
while(1){
display(min,sec1,sec2);
}
while(1);
}
void Timer0() interrupt 1{
TL0 = 0XCD;
TH0 = 0XD4;
cnt++;
if(cnt==100){
cnt = 0;
num++;
if(num==120) num =0;
min = num/60;
sec1 = (num%60)%10;
sec2 = (num%60)/10;
}
}
void display(uchar min,sec1,sec2){
Write_Cmd(0x80);
Write_Data(0x30+min);
Write_Data(':');
Write_Data(0x30+sec2);
Write_Data(0x30+sec1);
}

浙公网安备 33010602011771号