MENU

30 LCD1602液晶

July 30, 2020 • 51单片机

--- 当前时间: ---

30 LCD1602液晶

1602液晶资料

30.1 LCD1602液晶工作原理

30.1.1 LCD1602简介

1602液晶也叫1602字符型液晶,它是一种专门用来显示字母、数字、符号的点阵型液晶模块

它是由若干个$5\rtimes7$或者$5\times10$的点阵字符位组成,每个点阵字符位都可以用显示一个字符,每位之间有一个点距的间隔,每行之间也有间隔,起到了字符间距和行间距的作用,正因为如此,所以它<u>不能很好的显示图片</u>

注意:

  1. 无法显示汉字,显示汉字需要使用LCD12864或者TFT彩屏等
  2. 1602的意思是,横16字符,共两行

30.1.2 LCD1602的引脚

液晶显示偏压信号可以改变其亮度,开发板上使用了电位器调节亮度

一般情况下不会用到R/W的读功能,会直接接地

30.2 LCD1602操作相关

30.2.1 LCD1602操作步骤

  1. 初始化
  2. 写命令(RS = L)设置显示坐标
  3. 写数据(RS = H

30.2.2 LCD1602关键性的指令设置

注意此处使用的是<u>8位数据总线</u>

30.2.2.1 清屏指令

指令功能 指令编码 执行时间/ms
RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
清屏 0 0 0 0 0 0 0 0 0 1 1.64

功能:

  1. 清除液晶显示器,即将DDRAM的内容全部填入“空白”的ASCII码20H
  2. 光标归位,即将光标撤回液晶显示屏的左上方
  3. 将地址计数器(AC)的值设为0

30.2.2.2 进入模式设置指令

指令功能 指令编码 执行时间/us
RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
进入模式设置 0 0 0 0 0 0 0 1 I/D S 40

功能:设定每次定入1位数据后光标的移位方向,并且设定每次写入的一个字符是否移动

参数设定的情况如下所示:

位名设置
I/D0:写入新数据后光标左移;1:写入新数据后光标右移
S0:写入新数据后显示屏不移动;1:写入新数据后显示屏整体右移1个字符

30.2.2.3 显示开关控制指令

指令功能 指令编码 执行时间/us
RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
显示开关控制 0 0 0 0 0 0 1 D C B 40

功能:控制显示器开/关、光标显示/关闭以及光标是否闪烁

参数设定的情况如下:

位名设置
D0:显示功能关;1:显示功能开
C0:无光标;1:有光标
B0:光标闪烁;1:光标不闪烁

30.2.2.4 功能设定指令

指令功能 指令编码 执行时间/us
RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
功能设定 0 0 0 0 1 DL N F X X 40

功能:设定数据总线位数、显示的行数及字型

参数设定的情况如下:

位名设置
DL0:数据总线为4位;1:数据总线为8位
N0:显示1行;1:显示2行
F0:$5\times7$点阵/字符;1:$5\times10$点阵/字符

30.2.3 LCD1602显示内容设置

在设置完成之后我们就要明白具体是在哪显示,在哪个位置显示

在对液晶模块的初始化中要先设置其显示模式,在液晶模块显示字符时光标是自动右移的,无需人工干预

每次输入指令前都要判断液晶模块是否处于忙的状态(1602比单片机处理速度快,这一步可以不需要)

DDRAM就是显示数据RAM,用来寄存待显示的字符代码,共 80 个字节,其地址和屏幕的对应关系如下表:

  显示位置 1 2 3 4 5 6 7 …… 40
DDRAM
地址
第一行 00H 01H 02H 03H 04H 05H 06H …… 27H
第二行 40H 41H 42H 43H 44H 45H 46H …… 67H

要显示字符时要先输入显示字符地址,也就是告诉模块在哪里显示字符

例如第二行第一个字符的地址是40H,那么是否直接写入40H就可以将光标定位在第二行第一个字符的位置呢?

这样不行,因为写入显示地址时要求最高位D7恒定为高电平1,所以实际写入的数据应该是:

$$ \Large\tag{30.1}0100\,\,0000\text B\,\,(40\text H)+1000\,\,0000\text B\,\,(80\text H)=1100\,\,0000\text B\,\,(C0\text H) $$

在1602中我们就用前16个(00H~0FH)就行了,第二行也一样用前16个地址(40H~4FH),也可以实现滚动

【RAM地址映射图】

30.3 LCD1602模块电路

30.4 实例代码

lcd.h

#ifndef _LCD_H_
#define _LCD_H_

// #define LCD1602_4PINS

#include <reg52.h>

#ifndef uchar
#define uchar unsigned char
#endif

#ifndef uint
#define uint unsigned int
#endif

#define LCD1602_DATAPINS P0
sbit LCD1602_E  = P2^7;
sbit LCD1602_RW = P2^5;
sbit LCD1602_RS = P2^6;

void LCD1602_Delay1ms(uint c);
void LCDWriteCmd(uchar cmd);
void LCDWriteData(uchar dat);
void LCDInit();

#endif

lcd.c

#include "lcd.h"

void LCD1602_Delay1ms(uint c)
{
    uchar a, b;
    for(; c > 0; c--)
        for(b = 199; b > 0; b--)
            for(a = 1; a > 0; a--);
}

// There are two types of LCD1602: four-wire and eight-wire
// Thus, use #ifndef
#ifndef LCD1602_4PINS

void LCDWriteCmd(uchar cmd)
{
    LCD1602_E  = 0;
    LCD1602_RS = 0;
    LCD1602_RW = 0;
    
    LCD1602_DATAPINS = cmd;
    LCD1602_Delay1ms(1);
    
    LCD1602_E = 1;
    LCD1602_Delay1ms(5);
    LCD1602_E = 0;
}

void LCDWriteData(uchar dat)
{
    LCD1602_E  = 0;
    LCD1602_RS = 1;
    LCD1602_RW = 0;
    
    LCD1602_DATAPINS = dat;
    LCD1602_Delay1ms(1);
    
    LCD1602_E = 1;
    LCD1602_Delay1ms(5);
    LCD1602_E = 0;
}

void LCDInit()
{
    LCDWriteCmd(0x38);        // Function setting instruction
    LCDWriteCmd(0x0C);        // Display switch control instruction
    LCDWriteCmd(0x06);        // Entry mode setting instruction
    LCDWriteCmd(0x01);        // Screen clearing instruction
    // 00H + 80H = 80H
    LCDWriteCmd(0x80);        // Sets the data pointer starting point
}

#else

void LCDWriteCmd(uchar cmd)
{
    LCD1602_E  = 0;
    LCD1602_RS = 0;
    LCD1602_RW = 0;
    
    // first: H
    LCD1602_DATAPINS = cmd;
    LCD1602_Delay1ms(1);
    
    LCD1602_E = 1;
    LCD1602_Delay1ms(5);
    LCD1602_E = 0;
    
    // second: L
    LCD1602_DATAPINS = cmd << 4;
    LCD1602_Delay1ms(1);
    
    LCD1602_E = 1;
    LCD1602_Delay1ms(5);
    LCD1602_E = 0;
}

void LCDWriteData(uchar dat)
{
    LCD1602_E  = 0;
    LCD1602_RS = 1;
    LCD1602_RW = 0;
    
    // first: H
    LCD1602_DATAPINS = dat;
    LCD1602_Delay1ms(1);
    
    LCD1602_E = 1;
    LCD1602_Delay1ms(5);
    LCD1602_E = 0;
    
    // second: L
    LCD1602_DATAPINS = dat << 4;
    LCD1602_Delay1ms(1);
    
    LCD1602_E = 1;
    LCD1602_Delay1ms(5);
    LCD1602_E = 0;
}

void LCDInit()
{
    LCDWriteCmd(0x32);        // Function setting instruction
    LCDWriteCmd(0x28);        // Four-wire LCD1602 init
    LCDWriteCmd(0x0C);        // Display switch control instruction
    LCDWriteCmd(0x06);        // Entry mode setting instruction
    LCDWriteCmd(0x01);        // Screen clearing instruction
    LCDWriteCmd(0x80);        // Sets the data pointer starting point
}

#endif

main.c

#include <reg52.h>
#include "lcd.h"

typedef unsigned char u8;        // 0 ~ 255
typedef unsigned int u16;        // 0 ~ 65535

void main()
{
    u8 i;
    // ASCII
    u8 displayWords1[] = " Linkat Horizon ";
    u8 displayWords2[] = " Happy Coding!! ";
    
    LCDInit();
    
    for(i = 0; i < 16; i++)
    {
        LCDWriteData(displayWords1[i]);
    }
    
    // new line
    LCDWriteCmd(0x40 + 0x80);
    
    for(i = 0; i < 16; i++)
    {
        LCDWriteData(displayWords2[i]);
    }
    
    while(1);
}
Last Modified: August 21, 2020
Archives QR Code
QR Code for this page
Tipping QR Code