当前位置: 首页 > article >正文

LCD1602显示模块详解

LCD1602( Liquid Crystal Display 1602),一种常见的字符型液晶显示模块。虽然它接线多,但是LCD1602是每个嵌入式工程师的必经之路。它能够显示16列2行,共32个字符字符,每个字符都由5x8像素点阵构成,是一种专门用来显示字母、数字、符号等的液晶显示模块。

LCD 具有体积小、功耗低、显示内容丰富等特点,这种显示模块广泛应用于嵌入式系统和电子项目中,为开发者提供了简单而有效的文本和数字显示。在本文中,我们将深入探讨 LCD 中的 LCD1602 的特点、原理和工作方式。同时,我们还会介绍如何使用代码进行初始化和编程,以实现自定义的内容显示。

通过学习 LCD1602,您将能够更好地理解液晶显示技术,并将其应用于各种项目中。无论您是新手还是有经验的开发人员,本文都将为您提供基础知识和实用指南。

1. 源码下载及前置阅读

本文首发 良许嵌入式网 :https://www.lxlinux.net/e/ ,欢迎关注!

本文所涉及的源码及安装包如下(由于平台限制,请点击以下链接阅读原文下载):

https://www.lxlinux.net/e/stm32/lcd1602-tutorial.html

如果你是嵌入式开发小白,那么建议你先读读下面几篇文章。

  • 了解不同的下载程序方法,为你的嵌入式开发提供更多选择:STM32下载程序的五种方法
  • 手把手让你掌握MDK的使用方式和技巧,助你更高效地进行开发:一文教你使用MDK开发工具
  • 从零开始轻松掌握STM32开发的必备指南:零基础快速上手STM32开发(手把手保姆级教程)

往期精彩教程,有兴趣的小伙伴可以看看。

  • 从零开始轻松掌握STM32开发的必备指南:零基础快速上手STM32开发(手把手保姆级教程)
  • 深入浅出,帮助您理解和应用MQTT协议:万字猛文:MQTT原理及案例
  • 通俗易懂的 GPIO 介绍与实践:如何快速成为点灯大师?
作者简介
大家好,我是良许,博客里所有的文章皆为我的原创。
下面是我的一些个人介绍,欢迎交个朋友:
· 211工科硕士,国家奖学金获得者;
· 深耕嵌入式11年,前世界500强外企高级嵌入式工程师;
· 书籍《速学Linux作者》,机械工业出版社专家委员会成员;
· 全网60W粉丝,博客分享大量原创成体系文章,全网阅读量累计超4000万;
· 靠自媒体连续年入百万,靠自己买房买车。

我本科及硕士都是学机械,通过自学成功进入世界500强外企。我已经将自己的学习经验写成了一本电子书,超千人通过此书学习并转行成功。现在将这本电子书免费分享给大家,希望对你们有帮助:

电子书链接:https://www.lxlinux.net/1024.html

2. LCD1602介绍

2.1 型号介绍

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

有很多种型号的 LCD。

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

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

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

2.2 工作参数及引脚介绍

工作参数如下:

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

引脚接线参考如下:

LCD1602STM32说明
GNDGND接地
VDD5V电源正极
V00-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口双向数据
BLA5V背光正极
BLKGND背光负极

引脚注解:

  • V0:液品显示器对比度调整端,接正电源时对比度最高,接地时对比度最低,对比度过高时会产 生“鬼影”,使用时可以通过电位器或电阻调整对比度。电阻小了全是黑块,电阻大了不显示。

  • RW:读写信号线,高电平时进行读操作,低电平时进行写操作。

    当 RS 和 RW 共同为低电平时可以写入指令成者显示地址;

    当 RS 为低电平,RW 为高电平时可以读忙信号;

    当 RS 为高电平,RW 为低电平时可以写入数据。

  • E:使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。

3. LCD1602原理

3.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:读数据。

3.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

时序时间参数如下表:

3.3 LCD1602显存地址

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

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

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

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

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

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

3.4 LCD1602字符表

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

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

3.5 LCD1602初始化

LCD1602 初始化流程图如下:

5. 编程实战

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

5.1 硬件接线

本教程使用的硬件如下:

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

接线如下:

LCD1602STM32
GNDGND
VDD5V
V0GND
RSB1
RWB2
EB10
D0A0
D1A1
D2A2
D3A3
D4A4
D5A5
D6A6
D7A7
BLA3.3
BLKGND

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

ST-Link V2STM32
SWCLKSWCLK
SWDIOSWDIO
GNDGND
3.3V3V3

接好如下图:

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

5.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);
}

5.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;
}

5.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;
}

5.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);
}

5.5 显示字符

根据我们前面说的显存地址,将数据一个个显示到 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;
    }
}

5.6 画面移动

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

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

5.6 主函数

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();
    }
}

5.6 运行效果

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

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

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

8. 总结

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

希望本文对您对于 LCD1602 的理解和应用有所帮助。感谢各位看官,peace and love!

另外,想进大厂的同学,一定要好好学算法,这是面试必备的。这里准备了一份 BAT 大佬总结的 LeetCode 刷题宝典,很多人靠它们进了大厂。

刷题 | LeetCode算法刷题神器,看完 BAT 随你挑!

有收获?希望老铁们来个三连击,给更多的人看到这篇文章

推荐阅读:

  • 程序员必备编程资料大全
  • 程序员必备软件资源

欢迎关注我的博客:良许嵌入式教程网,满满都是干货!


http://www.kler.cn/a/445186.html

相关文章:

  • 数字时代的医疗挂号变革:SSM+Vue 系统设计与实现之道
  • STL 剖析
  • W25Q128读写实验(一)
  • 怿星科技联合赛力斯举办workshop活动,进一步推动双方合作
  • 【信息系统项目管理师-论文真题】2018下半年论文详解(包括解题思路和写作要点)
  • 《软件工程文档攻略:解锁软件开发的“秘籍”》
  • 数说故事聚焦“卖车”场景,推出AI汽车销售转化解决方案
  • 【优选算法篇】揭秘快速排序:分治算法如何突破性能瓶颈
  • 完整微服务设计 功能实现
  • 【Spring】配置文件的使用
  • D99【python 接口自动化学习】- pytest进阶之fixture用法
  • 将4G太阳能无线监控的视频接入电子监控大屏,要考虑哪些方面?
  • Altair: 轻松创建交互式数据可视化
  • Hexo Next主题集成百度统计
  • 进网许可认证、交换路由设备检测项目更新25年1月起
  • 占个坑:利用工作以外的时间,用numpy实现MLP-手写识别
  • Springboot 学习 之 logback-spring.xml 日志压缩 .tmp 临时文件问题
  • 学习反射(反射的使用,反射的应用场景)
  • 51c自动驾驶~合集42
  • 使用 acme.sh 申请域名 SSL/TLS 证书完整指南
  • 基础库正则表达式
  • 【模块一】kubernetes容器编排进阶实战之基于velero及minio实现etcd数据备份与恢复
  • 【人工智能数学基础】——深入详解贝叶斯理论:掌握贝叶斯定理及其在分类和预测中的应用
  • 【Flutter_Web】Flutter编译Web第二篇(webview篇):flutter_inappwebview如何改造方法,变成web之后数据如何交互
  • 短视频账号矩阵系统源代码-代码分享
  • 基于注意力机制的faster-rcnn算法的目标检测(源码+pytorch框架)