第28章 LCD12864液晶显示

第二十八章 LCD12864液晶显示

1. 导入

上一章我们学习了如何在 LCD1602 显示字符数据, 我们知道 LCD1602 是字符型显示器, 它不能显示汉字图形等。 对于需要显示汉字或图形的项目中, LCD1602无法实现, 因此本章就来介绍一个可以实现字符、 汉字、 图形等显示的液晶屏--LCD12864。 LCD12864 分为带字库和不带字库两种。 我们开发板上集成了一个LCD12864 液晶显示器接口, 它可兼容带字库和不带字库两种屏, 将 LCD12864 液晶对应插入即可。

2. LCD12864介绍

LCD12864 液晶屏结构上与 LCD1602 一样, 只是在行列数与显示像素上区别很大。

注意区分 LCD1602 和 LCD12864:12864 是 64行 128 列, 当然也有可能会设计成 64 列 128 行, 这里的行列不像 1602 那样, 1602 是按照八行四列标准英文字符格式, 以一行十六个字符, 两列字符命名,而 12864 是以 128 列像素, 64 行像素, 也就是有 128*64 个像素点组成。 就好比是 128 列 64 行的点阵。 需要一行一列的去显示像素点。

通常显示一个汉字需要 16x16 个像素点, 所以 LCD12864 一行最多能显示 8个汉字, 最多能显示 4 行。 通常显示一个字符需要 8x8 个像素点, 所以 LCD12864一行最多能显示 16 个字符, 最多能显示 8 行。

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

更多可以参考:LCD12864显示屏原理及使用教程-CSDN博客

2.1 带字库LCD12864

屏幕截图 2024 06 15 101319

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

屏幕截图 2024 06 15 101530

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

屏幕截图 2024 06 15 101606

2.2 LCD12864(带字库)常用指令

  • 功能设定

屏幕截图 2024 06 15 102035

  • 清屏指令

屏幕截图 2024 06 15 102156

  • 进入设定点

屏幕截图 2024 06 15 102218

  • 显示状态开关

屏幕截图 2024 06 15 102234

从上图得知,LCD12864能直接显示的地址范围如下:

第一行: 0X80-OX87; ( 一个汉字占用 2 个字节, 共 8 个汉字)
第二行: 0X90-0X97;
第三行: 0X88-0X8F;
第四行: 0X98-0X9F;

参考:带字库LCD12864(ST7920)使用记录(命令 数据 地址 绘图 反白)-CSDN博客

3. 硬件设计

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

  • 带字库 LCD12864 液晶

开发板上集成了一个 LCD12864 液晶接口, 下面我们来看下开发板上LCD12864 液晶接口电路, 如下图所示:

屏幕截图 2024 06 15 102808

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

至于 TFTLCD 后面章节会介绍。 该电路中 LCD12864 的 8 位数据口 LCD_D0-LCD_D7 与单片机的 P0.0-P0.7管脚连接, LCD12864 的 RS、 RW、 E 脚与单片机的 P2.6、 P2.5、 P2.7 管脚连接, LCD12864 的 PSB 脚与单片机的 P3.2 管脚连接, LCD12864 的 RESET 复位脚直接连接在 VCC 上。 当使用 LCD12864 时, 其他设备就不要占用这些管脚, 即使要用也只能分时复用。

4. 软件设计

本章所要实现的功能是: LCD12864 上显示汉字字符信息。程序框架如下:

  • 编写 LCD12864 显示函数

  • 编写主函数

4.1 LCD12864显示函数

#include "lcd12864.h"

// 写入命令函数
void lcd12864_write_cmd(unsigned char 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后负跳变完成写入
}

// 写入数据函数
void lcd12864_write_data(unsigned char 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后负跳变完成写入
}

// 初始化函数
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); // 清屏    
}

// 清屏函数
void lcd12864_clear(void)
{
    lcd12864_write_cmd(0x01);    
} 

// 显示字符串函数
void lcd12864_show_string(unsigned char x,unsigned char y,unsigned char *str)
{
    if(y<=0)
        y=0;
    if(y>3)
        y=3;

    x &= 0x0f; // 限制x,y不能大于显示范围

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

4.2 主函数

#include "public.h"
#include "lcd12864.h"

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)
    {

    }    
}

5. 小结

与前面一样,对代码理解要求不高,只要会用主函数里面的功能即可。学有余力可以打开工程按照注释理解,后面的TFTLCD也是一样,后面两个实验就不做小结了。

2024.7.25:还是简单分析一下lcd12864配置函数吧

  • 写入命令函数

看注释

// 写入命令函数
void lcd12864_write_cmd(unsigned char cmd)
{
    // 1. 选择命令
    LCD12864_RS = 0;

    // 2. 选择写命令
    LCD12864_WR=0;

    // 3. 使能信号
    LCD12864_E = 0;

    // 4. 准备写入数据
    LCD12864_DATAPORT = cmd;
    delay_ms(1);

    LCD12864_E = 1; // 使能脚E先上升沿写入
    delay_ms(1);

    LCD12864_E = 0; // 使能脚E后负跳变完成写入
}

选择命令->写命令->使能信号->写入数据准备->使能引脚(我们宏定义的是P0)高到低完成写入命令

  • 写入数据函数
// 写入数据函数
void lcd12864_write_data(unsigned char dat)
{
    // 1. 选择数据
    LCD12864_RS = 1;

    // 2. 选择写命令
    LCD12864_WR = 0;

    // 3. 使能信号
    LCD12864_E = 0;

    // 4. 准备写入数据
    LCD12864_DATAPORT = dat; // 准备数据
    delay_ms(1);

    LCD12864_E = 1; // 使能脚E先上升沿写入
    delay_ms(1);
    LCD12864_E = 0; // 使能脚E后负跳变完成写入
}

与写入命令大同小异,不做分析

  • 初始化函数
// 初始化函数
void lcd12864_init(void)
{
    // 1. 选择8位模式
    LCD12864_PSB = 1;

    // 以下写入命令是根据芯片来的,不知道可以网上查一下
    lcd12864_write_cmd(0x30); // 数据总线8位,基本指令操作
    lcd12864_write_cmd(0x0c); // 整体显示关,游标显示关,游标正常显示
    lcd12864_write_cmd(0x06); // 写入新数据后光标右移,显示屏不移动
    lcd12864_write_cmd(0x01); // 清屏    
}

初始化函数根据实际情况配置

  • 清屏函数
// 清屏函数
void lcd12864_clear(void)
{
    lcd12864_write_cmd(0x01);    
} 

看这个图就应该很好理解了吧

  • 显示字符串函数(核心-我们需要重点理解)
// 显示字符串函数
// x,y: 显示位置坐标 str:代表要显示的字符串
void lcd12864_show_string(unsigned char x,unsigned char y,unsigned char *str)
{
    if(y <= 0) // 限制y不能小于0
        y = 0;
    if( y > 3) // 限制y不能大于3
        y = 3;

    x &= 0x0f; // 限制x,y不能大于显示范围

    switch(y)
    {
        case 0: 
            x |= 0x80; // 第1行地址+x的偏移
            break; 
        case 1: 
            x |= 0x90; // 第2行地址+x的偏移
            break;
        case 2: 
            x |= 0x88; // 第3行地址+x的偏移
            break;
        case 3: 
            x |= 0x98; // 第4行地址+x的偏移
            break;
    }
    lcd12864_write_cmd(x); // 写入显示位置坐标
    while(*str != '\0') // 当字符串不为空时
    {
        lcd12864_write_data(*str); // 写入显示字符
        str++;        
    }        
} 

关于LCD屏或者后面TFT彩屏,我们只要求会使用已经封装好的函数就行了,一般买这些商家都会提高驱动文件,无需像上面自己写,所以最后三章只是简单了解即可,没有过多要求


2024.7.25 第一次修订

2024.8.25 第二次修订,后期不再维护

posted @ 2024-08-25 09:35  hazy1k  阅读(36)  评论(0编辑  收藏  举报