问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

LCD1602显示模块详解

创作时间:
作者:
@小白创作中心

LCD1602显示模块详解

引用
CSDN
1.
https://blog.csdn.net/yychuyu/article/details/144620701

LCD1602是一种常见的字符型液晶显示模块,能够显示16列2行共32个字符,每个字符由5x8像素点阵构成。本文将深入探讨LCD1602的特点、原理和工作方式,并介绍如何使用代码进行初始化和编程,以实现自定义的内容显示。

1. LCD1602介绍

1.1 型号介绍

LCD,液晶显示模块具有体积小、功耗低、显示内容丰富等特点,现在字符型液晶显示模块已经是单片机应用设计中最常用的信息显示器件了。

有很多种型号的LCD:

  • 根据显示字符:1602(16列2行)、2004(20列4行)、12864(128列64行)。
  • 根据屏幕颜色:蓝屏(白字)、黄绿屏(黑字/白字)、灰屏(黑字)。
  • 根据工作电压:5V、3.3V。

以上三种分类结果,排列组合,就成为了我们在橙色软件上看到的,眼花缭乱的型号选择。

当然,我们今天的主角是LCD1602。顺带一提,我的是黄绿屏(黑字)5V。

1.2 工作参数及引脚介绍

工作参数如下:

  • 工作电压:5V
  • 工作电流:2.0mA
  • 工作温度:-20°C ~ +70°C
  • 设备寿命:>100,000小时

引脚接线参考如下:

LCD1602
STM32
说明
GND
GND
接地
VDD
5V
电源正极
V0
0-5V
液晶驱动电压
RS
任意GPIO口
寄存器选择:1:数据寄存器0:指令寄存器
RW
任意GPIO口
读、写操作选择:1:读0: 写
E
任意GPIO口
使能信号
D0
任意GPIO口
双向数据
D1
任意GPIO口
双向数据
D2
任意GPIO口
双向数据
D3
任意GPIO口
双向数据
D4
任意GPIO口
双向数据
D5
任意GPIO口
双向数据
D6
任意GPIO口
双向数据
D7
任意GPIO口
双向数据
BLA
5V
背光正极
BLK
GND
背光负极

引脚注解:

  • V0:液品显示器对比度调整端,接正电源时对比度最高,接地时对比度最低,对比度过高时会产生“鬼影”,使用时可以通过电位器或电阻调整对比度。电阻小了全是黑块,电阻大了不显示。
  • RW:读写信号线,高电平时进行读操作,低电平时进行写操作。当 RS 和 RW 共同为低电平时可以写入指令成者显示地址;当 RS 为低电平,RW 为高电平时可以读忙信号;当 RS 为高电平,RW 为低电平时可以写入数据。
  • E:使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。

2. LCD1602原理

2.1 LCD1602指令

LCD1602的读写操作、屏幕和光标的操作都是通过指令编程来实现的。LCD1602内部的控制器共有11条控制指令,如表所示:

  • 指令1:清显示,指令码 01H,光标复位到地址 00H 位置。
  • 指令2:光标复位,光标返回到地址00H。
  • 指令3:I/D:光标和显示模式设置,光标移动方向,高电平右移,低电平左移;S:屏幕上所有文字是否左移或者右移。高电平表示有效,低电平则无效。
  • 指令4:显示开关控制。D:控制整体显示的开与关,高电平表示开显示,低电平表示关显示;C:控制光标的开与关,高电平表示有光标,低电平表示无光标;B:控制光标是否闪烁,高电平闪烁,低电平不闪烁。
  • 指令5:S/C:高电平时移动显示的文字,低电平时移动光标;R/L:高电平时右移,低电平时左移。
  • 指令6:功能设置命令 DL:高电平时为4位总线,低电平时为8位总线;N:低电平时为单行显示,高电平时双行显示;F:低电平时显示5x7的点阵字符,高电平时显示5x10的点阵字符。
  • 指令7:字符发生器RAM地址设置。
  • 指令8:DDRAM地址设置。
  • 指令9:读忙信号和光标地址,BF:为忙标志位,高电平表示忙,此时模块不能接收命令或者数据,如果为低电平表示不忙。
  • 指令10:写数据。
  • 指令11:读数据。

2.2 基本操作时序

LCD1602的基本的操作分为以下四种:

  • 状态字读操作:输入 RS=0、RW=1、E=1;输出:D0~7 读出为状态字;
  • 数据读出操作:输入 RS=1、RW=1、E=1;输出:D0~7 读出为数据;
  • 指令写入操作:输入 RS=0、RW=0、E=上升沿; 输出:无;
  • 数据写入操作:输入 RS=1、RW=0、E=上升沿; 输出:无。

读操作的时序图如下:

当我们要写指令的时候,RS 置为低电平,RW 置为低电平,E 置为低电平,然后将指令数据送到数据口 D0~D7,延时 tsp1,让 LCD1602 准备接收数据,这时候将 E 拉高,产生一个上升沿,这时候指令就开始写入 LCD1602,延时一段时间,将 E 置为低电平。

写操作的时序图如下:

当我们要写数据的时候,RS 置为高电平,RW 置为低电平,E 置为低电平,然后将指令数据送到数据口 D0~D7,延时 tsp1,让 LCD1602 准备接收数据,这时候将 E 拉高,产生一个上升沿,这时候数据就开始写入 LCD1602,延时一段时间,将 E 置为低电平。

对比一下可以发现,写指令和写数据在时序上只是 RS 的不同,写指令 RS=0,写数据 RS=1。

时序时间参数如下表:

2.3 LCD1602显存地址

LCD1602的控制器内置有80个byte的显存,而LCD1602只有两行×16个字符的显示区域,所以显存中有些地址是无法对应上LCD屏的,下图为显存地址对应图:

写入显示地址时要求最高位 D7 为高电平,也就是说,如果想你想

写入第一行第一个字符应该是:

00000000B(00H)+ 10000000B(80H) = 10000000B(80H)。

写入第二行第一个字符应该是:

01000000B(40H)+ 10000000B(80H) = 11000000B(C0H)。

2.4 LCD1602字符表

在LCD1602的控制IC当中,字符库中0x000x0F未定义,留给使用者的自定义字符使用。但只能使用0x000x07或者0x08~0x0F之一。

字符表如下,和ASCII码相似。

2.5 LCD1602初始化

LCD1602初始化流程图如下:

3. 编程实战

现在我们就动手,让LCD1602居中显示一个「peace and love」和「LX handsome」。每秒右移一位,移完后再次居中显示「peace and love」和「LX handsome」。

3.1 硬件接线

本教程使用的硬件如下:

  • 单片机:STM32F103C8T6
  • 显示屏:LCD1602
  • 电阻:电位器
  • 烧录器:ST-LINK V2

接线如下:

LCD1602
STM32
GND
GND
VDD
5V
V0
GND
RS
B1
RW
B2
E
B10
D0
A0
D1
A1
D2
A2
D3
A3
D4
A4
D5
A5
D6
A6
D7
A7
BLA
3.3
BLK
GND

烧录的时候接线如下表,如果不会烧录的话可以看我之前的文章【STM32下载程序的五种方法】。

ST-Link V2
STM32
SWCLK
SWCLK
SWDIO
SWDIO
GND
GND
3.3V
3V3

接好如下图:

V0需要接一个5kΩ左右的电阻才能正常显示,这里我用的是电位器。手上没有电位器或者电阻的小伙伴可以侧着看,上下左右侧着看,也是可以看到显示的字符的。

3.2 引脚初始化

将我们要用到的引脚都进行一个初始化。

void lcd_gpio_init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  /* GPIO Ports Clock Enable */
  //__HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
                          |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7, GPIO_PIN_SET);
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_10, GPIO_PIN_SET);
  /*Configure GPIO pins : PA0 PA1 PA2 PA3
                           PA4 PA5 PA6 PA7 */
  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
                          |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  /*Configure GPIO pins : PB1 PB2 PB10 */
  GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_10;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

3.3 写指令

根据我们前面讲的时序,写指令:RS、RW、E置为低电平,指令数据传输,延时,将E拉高,延时,将E拉低。

void write_cmd(char cmd)
{
    RS_LOW;
    RW_LOW;
    EN_LOW;
    GPIOA->ODR = cmd;       //将一字节数据发到GPIOA 8个引脚
    HAL_Delay(5);
    EN_HIGH;
    HAL_Delay(5);
    EN_LOW;
}

3.4 写数据

根据我们前面讲的时序,写数据:RS置为高电平,RW、E置为低电平,指令数据传输,延时,将E拉高,延时,将E拉低。

void write_data(char dataShow)
{
    RS_HIGH;
    RW_LOW;
    EN_LOW;
    GPIOA->ODR = dataShow;   //将一字节数据发到GPIOA 8个引脚
    HAL_Delay(5);
    EN_HIGH;
    HAL_Delay(5);
    EN_LOW;
}

3.5 LCD1602初始化

按照初始化流程图写代码,检测忙信号可省略。

void lcd_init()
{
//(1)延时 15ms
    HAL_Delay(15);
//(2)写指令 38H(不检测忙信号) 
    write_cmd(0x38);
//(3)延时 5ms
    HAL_Delay(5);
//(4)检测忙信号(省略)
//(5)写指令 38H:显示模式设置
    write_cmd(0x38);
//(6)写指令 08H:显示关闭
    write_cmd(0x08);
//(7)写指令 01H:显示清屏
    write_cmd(0x01);
//(8)写指令 06H:显示光标移动设置
    write_cmd(0x06);
//(9)写指令 0CH:显示开及光标设置
    write_cmd(0x0c);
}

3.6 显示字符

根据我们前面说的显存地址,将数据一个个显示到LCD1602。

row: 显示行,col:显示起始列,string:显示字符。由于我们前面得出LCD1602字符表和ACSII码差不多,所以直接传参即可。

void lcd_show_line(char row, char col, char *string)
{
    switch(row){
    case 1:
        write_cmd(0x80+col);        //最高位 D7 为高电平
        while(*string){
            write_data(*string);
            string++;
        }
        break;
    case 2:
        write_cmd(0x80+0x40+col);
        while(*string){
            write_data(*string);
            string++;
        }
        break;
    }
}

3.7 画面移动

利用写指令,0x18,画面右移一位;0x1C,画面左移一位。

void lcd_right_move(void)
{
    for(int i=0;i < 16;i++){
        HAL_Delay(1000);
        write_cmd(0x18);            //画面右移一位 0x18
    }
}

3.8 主函数

int main(void)
{
    HAL_Init();                         /* 初始化HAL库 */
    sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
    delay_init(72);                     /* 延时初始化 */
    lcd_gpio_init();                    /* lcd初始化 */
    while(1)
    {
        lcd_start();
        lcd_show_line(1,1,"peace and love");
        lcd_show_line(2,2,"LX handsome");
        lcd_move();
    }
}

3.9 运行效果

我用的是我自己打的板子,上官二号。大家可以用自己的板子,是STM32F103C8T6就行。

显示「peace and love」和「LX handsome」。

每秒右移一位,移完后再次居中显示「peace and love」和「LX handsome」。

4. 总结

在将来的项目中,您可以尝试利用LED1602进行更多的实践和创新。通过进一步探索和学习,您可以了解更多高级功能和扩展选项,以满足特定项目的需求。

希望本文对您对于LCD1602的理解和应用有所帮助。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号