LCD12864介绍

  LCD12864 液晶屏结构上与 LCD1602一样,只是在行列数与显示像素上区别很大。LCD12864,以下简称12864,注意区分 LCD1602 和 LCD12864。12864是 64行128 列,当然也有可能会设计成 64 列 128 行,这里的行列不像 1602 那样,1602 是按照八行四列标准英文字符格式,以一行十六个字符,两列字符命名,而 12864 是以 128 列像素,64 行像素,也就是有 128*64 个像素点组成。就好比是 128 列 64 行的点阵。需要一行一列的去显示像素点。

  通常显示一个汉字需要1616个像素点,所以LCD12864一行最多能显示8个汉字,最多能显示4行。通常显示一个字符需要88个像素点,所以LCD12864一行最多能显示16个字符,最多能显示8行。当然这是不依靠后期取模的显示情况,如果通过取模软件取模,然后将LCD12864按照128*64个像素点来显示,显示的内容就可能超过之前的,就拿字符来说,可以选择小号字体,通过取模软件将字符数据取出,然后将这些数据通过在对应的像素点上点亮或熄灭实现不同字体的显示。图像的显示原理也是这样。

  常用的 12864 分为带字库和不带字库两种

带字库LCD12864

  上图左侧为带字库 12864 显示字符和汉字,右侧为图形模式显示。注意:这里图形模式虽然显示了字符和汉字,但是并不是使用字库里的,显示的方法也是多样化的。

  对于带字库 LCD12864,最常见的标志就是在屏幕背后,会有存放字库的芯片。如下图所示:

   LCD12864 带字库屏共有20个引脚,管脚功能如下:

引脚号 引脚名称 功能说明
1 VSS 电源地(0V)
2 VDD 电压输入(+5V)
3 V0 LCD驱动电压输入端(对比度调节)
4 RS 寄存器选择端  高:数据寄存器; 低:命令寄存器
5 R/W 读/写信号  高:读操作; 低:写操作
6 E 使能信号
7~14 DB0~DB7 数据总线
15 CS1 片选信号1,低有效,对应左半屏64×64点
16 CS2 片选信号2,低有效,对应右半屏64×64点
17 /RST 复位信号,低有效
18 VOUT 负压输入输出端
19 LED-A 背光正极
20 LED-K 背光负极

  LCD12864 的指令相对LCD1602要多一些,但常用指令基本上一样,下面来看下LCD12864 带字库常用的指令。

功能设定

  • 初始值:001 DL X100 B(DL=1,8BIT 并口;DL=0,4BIT 并口 X=0,1)
    • DL : 8/4 位接口控制位:1——8位接口;0——4位接口
    • RE :指令集选择控制位:1——扩充指令集;0——基本指令集
  • 同一指令的动作不能同时改变DL和RE,需先改变DL再改变RE才能确保设置正确

清屏指令

  • 将DDRAM填满“20H”(空格)代码,并且设定DDRAM的地址计数器(AC)位00H
  • 更新设置进入设定点将I/D设为1,游标右移AC加1

进入设定点

  • 进入设定点,初值:06H
  • 指定在显示数据的读取与写入时,设定游标的移动方向及指定显示的移位
    • I/D=1,游标右移,DDRAM地址计数器(AC)加1
    • I/D=1,游标左移,DDRAM地址计数器(AC)减1
  • S:显示画面整体位移
    S S 功能描述
    H H 画面整体左移
    H L 画面整体右移

显示状态开关设置

  • 显示状态开关设置

  • 显示开关设置,初始值:08H

  • 控制整体显示开关,游标开关,游标位置显示反白开关

    • D
      • D=1 整体显示开
      • D=0 整体显示关,但是不改变DDRAM内容
    • C
      • C=1 游标显示开
      • C=0 游标显示关
    • B
      • B=1 游标位置显示反白开,将游标所在地址上的内容反白显示
      • B=0 正常显示

  同LCD1602 一样,LCD12864内部也含有DDRAM,与其对应的地址如下:

  从上图可知,LCD12864能直接显示的地址范围如下(一个汉字占用2个直接):

  • 第一行,0x80~0x87
  • 第二行,0x90~0x97
  • 第三行,0x88~0x8F
  • 第四行,0x98~0x9F

  LCD12864 与 LCD1602 有太多的相似之处,包括通信时序,简直是一模一样,所以编写LCD12864的驱动程序时,可完全照搬LCD1602的。

不带字库LCD12864

  这种不带字库的 LCD12864 背面没有芯片,一般为转接板,将12864 显示屏转接到开发板。这种显示屏的操作就像带字库的 12864 操作图片形式一样。所有的显示都需要取模,取模方法和点阵取模一样。不带字库的LCD12864,从外形上看其体积比带字库LCD12864要小很多,因此也常称之为MiniLCD12864。

  对于MiniLCD12864,要想显示汉字或其他字符需通过取字模方式来实现。要让其显示首先还得初始化,这个和LCD1602原理类似,即通过对其内部一些特殊寄存器设置实现特定功能。MiniLCD12864内部驱动芯片有的是ST7565P,

硬件设计

  本实验使用到硬件资源如下:

  • 带字库LCD12864液晶

  从上图中可知,该接口是LCD12864与TFTLCD彩屏共用的,LCD12864占用下面20个管脚,MiniLCD12864是16脚,而带字库的LCD12864通常是20脚。这样可以兼容带字库的LCD12864和不带字库的LCD12864。

软件设计

  本实验所要实现的额功能时:LCD12864商显示汉字字符信息,程序框架如下:

  • LCD12864显示函数
  • 主函数
实物接线图
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**************************************************************************************
实验名称:LCD12864液晶显示实验(带字库)
接线说明:
实验现象:下载程序后,LCD12864上显示汉字字符信息
注意事项:
***************************************************************************************/
#include "public.h"
#include "lcd12864.h"


/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
lcd12864_init();//LCD12864初始化

lcd12864_show_string(0,0,"Hello World!");//第1行字符串显示
lcd12864_show_string(0,1,"大家好!");//第2行字符串显示
lcd12864_show_string(0,2,"欢迎使用51开发板");//第3行字符串显示
lcd12864_show_string(0,3,"好好学习天天向上");//第4行字符串显示
while(1)
{

}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include "lcd12864.h"


/*******************************************************************************
* 函 数 名 : lcd12864_write_cmd
* 函数功能 : LCD12864写命令
* 输 入 : cmd:指令
* 输 出 : 无
*******************************************************************************/
void lcd12864_write_cmd(u8 cmd)
{
LCD12864_RS=0;//选择命令
LCD12864_WR=0;//选择写
LCD12864_E=0;
LCD12864_DATAPORT=cmd;//准备命令
delay_ms(1);
LCD12864_E=1;//使能脚E先上升沿写入
delay_ms(1);
LCD12864_E=0;//使能脚E后负跳变完成写入
}

/*******************************************************************************
* 函 数 名 : lcd12864_write_data
* 函数功能 : LCD12864写数据
* 输 入 : dat:数据
* 输 出 : 无
*******************************************************************************/
void lcd12864_write_data(u8 dat)
{
LCD12864_RS=1;//选择数据
LCD12864_WR=0;//选择写
LCD12864_E=0;
LCD12864_DATAPORT=dat;//准备数据
delay_ms(1);
LCD12864_E=1;//使能脚E先上升沿写入
delay_ms(1);
LCD12864_E=0;//使能脚E后负跳变完成写入
}

/*******************************************************************************
* 函 数 名 : lcd12864_init
* 函数功能 : LCD12864初始化
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void lcd12864_init(void)
{
LCD12864_PSB=1;//选择8位或4位并口方式
lcd12864_write_cmd(0x30);//数据总线8位,基本指令操作
lcd12864_write_cmd(0x0c);//整体显示关,游标显示关,游标正常显示
lcd12864_write_cmd(0x06);//写入新数据后光标右移,显示屏不移动
lcd12864_write_cmd(0x01);//清屏
}

/*******************************************************************************
* 函 数 名 : lcd12864_clear
* 函数功能 : LCD12864清屏
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void lcd12864_clear(void)
{
lcd12864_write_cmd(0x01);
}

/*******************************************************************************
* 函 数 名 : lcd12864_show_string
* 函数功能 : LCD12864显示字符串
* 输 入 : x,y:显示坐标,x=0~7,y=0~3;
str:显示字符串数据
* 输 出 : 无
*******************************************************************************/
void lcd12864_show_string(u8 x,u8 y,u8 *str)
{
if(y<=0)y=0;
if(y>3)y=3;
x&=0x0f; //限制x,y不能大于显示范围

switch(y)
{
case 0: x|=0x80;break;//第1行地址+x的偏移
case 1: x|=0x90;break;//第2行地址+x的偏移
case 2: x|=0x88;break;//第3行地址+x的偏移
case 3: x|=0x98;break;//第4行地址+x的偏移
}
lcd12864_write_cmd(x);
while(*str!='\0')
{
lcd12864_write_data(*str);
str++;
}

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include "public.h"

/*******************************************************************************
* 函 数 名 : delay_10us
* 函数功能 : 延时函数,ten_us=1时,大约延时10us
* 输 入 : ten_us
* 输 出 : 无
*******************************************************************************/
void delay_10us(u16 ten_us)
{
while(ten_us--);
}

/*******************************************************************************
* 函 数 名 : delay_ms
* 函数功能 : ms延时函数,ms=1时,大约延时1ms
* 输 入 : ms:ms延时时间
* 输 出 : 无
*******************************************************************************/
void delay_ms(u16 ms)
{
u16 i,j;
for(i=ms;i>0;i--)
for(j=110;j>0;j--);
}

  头文件相关

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef _lcd12864_H
#define _lcd12864_H

#include "public.h"

//管脚定义
sbit LCD12864_RS=P2^6;//数据命令选择
sbit LCD12864_WR=P2^5;//读写选择
sbit LCD12864_E=P2^7;//使能信号
#define LCD12864_DATAPORT P0 //LCD12864数据端口定义
sbit LCD12864_PSB=P3^2;//8位或4并口/串口选择

//函数声明
void lcd12864_init(void);
void lcd12864_clear(void);
void lcd12864_show_string(u8 x,u8 y,u8 *str);
#endif

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef _public_H
#define _public_H

#include "reg52.h"

typedef unsigned int u16; //对系统默认数据类型进行重定义
typedef unsigned char u8;
typedef unsigned long u32;

void delay_10us(u16 ten_us);
void delay_ms(u16 ms);

#endif