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的不同,写操作分为写指令和写数据两种:

  1. 写指令:
    1. RS置为0
    2. R/W置为0
    3. EN置为0
    4. 输入CMD
    5. 延时
    6. EN置为1
    7. 延时
    8. EN置为0
  2. 写数据:
    1. RS置为1
    2. R/W置为0
    3. EN置为0
    4. 输入DAT
    5. 延时
    6. EN置为1
    7. 延时
    8. EN置为0

读操作一般不常见,因此在本文中就不提及了。

LCD1602的常用指令


数据指针:指令码为0x80+地址码,地址码范围为0x00-0x27,0x40-0x67。
整屏左移:0x18
整屏右移:0x1c
根据常用指令,需要先将LCD1602初始化:

  1. 写指令0x38:表示为8位数据,两行显示,5*7点阵
  2. 延时
  3. 写入0x38,显示模式设置
  4. 写指令0x0f:显示开关控制
  5. 写指令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);

}

posted @   zxkic  阅读(720)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
点击右上角即可分享
微信分享提示