1.LCD1602介绍
1602液晶也叫1602字符型液晶,它能显示2行字符信息,每行又能显示16个字符。它是一种专门用来显示字母、数字、符号的点阵型液晶模块。它是由若干5x7或者5x10的点阵字符位组成,每个点阵字符位都可以用显示一个字符,每位之间有一个点距的间隔,每行之间也有间隔,起到了字符间距和行间距的作用,正因为如此,所以它不能很好的显示图片。其实物图如下所示:
在上图中可以看到有 16 个管脚孔,从左至右管脚编号顺序是1-16,其功能定义如下所示:
字符型液晶显示模块组件内部主要由LCD显示屏(LCD PANEL)、控制器(controller)、驱动器(driver)和偏压产生电路构成。在 LCD1602 内部含有 80 个字节的 DDRAM,它是用来寄存显示字符的。其地址和屏幕的对应关系如下表:
从上图可知,不是所有的地址都可以直接用来显示字符数据,只有第一行中的00-0F,第二行中的40-4F才能显示,其他地址只能用于存储。要显示字符时要先输入显示字符地址,也就是告诉模块在哪里显示字符,例如第二行第一个字符的地址是 40H,那么是否直接写入 40H 就可以将光标定位在第二行第一个字符的位置呢?这样不行,因为写入显示地址时要求最高位D7恒定为高电平1,所以实际写入的数据应该是 01000000B(40H)+10000000B(80H)=11000000B (C0H)。
在1602中我们就用前16个就行了。第二行也一样用前16个地址。
2.LCD1602常用命令
(1)清屏命令:0x01
清显示指令将空位字符码20H送入全部DDRAM地址中,使DDRAM中的内容全部清除,显示消失;地址计数器AC=0,自动增1模式;显示归位,光标或者闪烁回到原点(显示屏左上角);但并不改变移位设置模式。
(2)模式设置指令
- I/D=1,完成一个字符码传送后,光标右移,AC自动加1;
- I/D=0,完成一个字符码传送后,光标左移,AC自动减1;
- S=0写入新数据后显示屏不移动 ;
- S=1写入新数据后显示屏整体右移 1 个字符;
(3)显示开关控制指令
功能:控制显示器开/关、光标显示/关闭以及光标是否闪烁。
- D=0显示功能关 1显示功能开
- C=0无光标 1有光标
- B=0光标闪烁 1光标不闪烁
(4)功能设置
功能:设定数据总线位数、显示的行数及字型。
- DL=0数据总线为4位 1=数据总线为8位
- N=显示1行 1=显示2行
- F=0 5×7点阵/每字符 1=5×10点阵/每字符
3 LCD1602屏幕时序
(1)写操作时序示意图:
RS为数据命令选择、R/W为读写使能、E为总使能、DB0~DB7为数据线。写命令实现如下:
void LCD1602_W_Reg(u8 reg)
{
RS=0;//写命令
EN=0;
RW=0;
LCD_DAT=reg;
Delay_Us(20);
EN=1;
Delay_Us(15);
EN=0;
}
写数据实现如下:
void LCD1602_W_Dat(u8 dat)
{
RS=1;//写数据
EN=0;
RW=0;
LCD_DAT=dat;
Delay_Us(20);
EN=1;
Delay_Us(15);
EN=0;
}
注意:时序速度不能过快,否则将导致屏幕驱动失败,也不宜过慢,太慢将导致屏幕刷新过慢。
延时函数实现如下:
void Delay1us() //@11.0592MHz
{
_nop_();
_nop_();
_nop_();
}
void Delay_Us(u16 time)
{
while(time--)
{
Delay1us();
}
}
4.硬件接口
从上图中可知,LCD1602的8位数据口DB0DB7与单片机的P0.0P0.7 管脚连接,LCD1602 的RS、RW、E脚与单片机的P2.6、P2.5、P2.7管脚连接。RJ1是一个电位器,用来调节LCD1602 对比度即显示亮度。
5.LCD初始化
void LCD1602_Init(void)
{
LCD1602_W_Reg(0x38);//数据总线8位,显示2行,5*7点阵/字符
LCD1602_W_Reg(0x0c);//显示功能开,无光标,光标闪烁
LCD1602_W_Reg(0x06);//写入新数据后光标右移,显示屏不移动
LCD1602_W_Reg(0x01);//清屏
}
6.字符串显示函数实现
/*
字符串显示
形参:x--0~15
y --0~1
*/
void LCD1602_ShowStr(u8 x,u8 y,u8 *str)
{
while(*str)
{
if(x>15)
{
x=0;
y++;
}
if(y==0)
{
LCD1602_W_Reg(0x80+x);
}
else
{
LCD1602_W_Reg(0xC0+x);
}
LCD1602_W_Dat(*str++);
x++;
}
}
7.主函数
在LCD上显示温度和时间信息。
int main()
{
LED=0xff;//关闭所有灯
Key_Init();//按键初始化
Usart_Init();//初始化串口(定时器中断和串口中断一起开时,定时器定时时长不宜过短)
LCD1602_Init();
//初始化DS18B20
DS18B20_CheckStat();
//Timer0_Init();//定时器初始化
DS1302_SetTime();//设置时间
LCD1602_ShowStr(3,0," 12:00:00");
LCD1602_ShowStr(2,1," 2024-12-01");
while(1)
{
key=Key_GetVal();
if(key==1)//按键1切换界面
{
LCD1602_Clear();
menu_flag++;
BEEP_Ctl(500);
if(menu_flag>1)menu_flag=0;
time=100;
}
if(menu_flag==0)//上电默认显示时间
{
//时间显示
DS1302_GetTime();
if(sec!=DS1302_Time[0])
{
sec=DS1302_Time[0];
TimerToStr(1,buffer);
LCD1602_ShowStr(3,1,buffer);
TimerToStr(2,buffer);
LCD1602_ShowStr(4,0,buffer);
i=0;
}
}
time++;
delay_ms(1);
if(time>=100)
{
time=0;
temp=DS18B20_ReadTemp();
temp=temp*0.0625*100;
if(menu_flag==1)//显示温度
{
IntToStr(temp,buffer);
LCD1602_ShowStr(4,0,buffer);
}
}
}
}