目录

  • 硬知识
    • 显示特性
    • 接口定义
    • 操作时序
      • 写操作时序
      • 读操作时序
    • 寄存器
    • 忙标志位BF
    • 地址计数器(AC)
    • 显示数据寄存器(DDRAM)
    • CGROM
    • CGRAM
    • 指令
      • 清屏指令
      • 光标归位指令
      • 进入模式设置指令
      • 显示开关控制指令
      • 设定显示屏或光标移动方向指令
      • 功能设定指令
      • 设定CGRAM地址指令
      • 设定DDRAM地址指令
      • 读取忙信号或AC地址指令
      • 数据写入DDRAM或CGRAM指令
      • 从 CGRAM或DDRAM读出数据的指令
  • 示例程序
    • LCD1602.c
    • LCD1602.h
    • 测试程序
      • main.c
      • 实验现象
      • 仿真现象
        • 八线制
        • 四线制

普中51-单核-A2
STC89C52
Windows 10 20H2
Proteus 8 Frofessional v8.9 SP2
Keil uVision V5.29.0.0
PK51 Prof.Developers Kit Version:9.60.0.0


硬知识

摘自《通用1602 液晶显示模块使用手册》、《液晶LCD1602(中文资料)—— ball 2010-5-13整理》

显示特性

单5V电源电压,低功耗、长寿命、高可靠性
       内置192种字符(160个5x7点阵字符和32个5x10点阵字符)
       具有64个字节的自定义字符RAM,可自定义8个5x8点阵字符或四个5x11点阵字符
       显示方式:STN、半透、正显
       驱动方式:1/16DUTY,1/5BIAS
       视角方向:6点
       背光方式:底部LED
       通讯方式:4位或8位并口可选
       标准的接口特性,适配MCS1和M6800系列MPU的操作时序。

接口定义

操作时序

写操作时序


读操作时序


寄存器

本模块内部具有两个8位寄存器:指令寄存器(IR)和地址寄存器(DR),用户可以通过RS和R/W输入信号的组合选择指定的寄存器,进行相应的操作。下表中列出了组合选择方式。


       指令寄存器IR,内部存储DDRAM和CGRAM中的数据显示的指令代码和地址信息,只能由MPU对其执行写操作:
       数据寄存器DR,内部暂时存储MPU与模块内部DDRAM和CGRAM之间的传送数据,内部操作使DR与DDRAM或者CGRAM之间的数据传送自动进行:

忙标志位BF

忙标志BF-1时,表明模块正在进行内部操作,此时不接受任何外部指令和数据。当Rs-0,RW-1以及E为高电平时,BF输出到DB7,每次操作之前最好先进行状态字检测,只有在确认BF-0之后,MPU才能访问模块

地址计数器(AC)

AC地址计数器是DDRAM或者CGRAM的地址指针。随着IR中指令码的写入,指令码中携带的地址信息自动送入AC中,并行做出AC作为DDRAM的地址指针还是CGRAM的地址指针的选择。
       AC具有自动加1或者减1的功能。当DR与DDRAM或者CGRAM之间完成一次数据传后,AC自动会加1或减1,在RS=0,R/W=1且E为高电平时,AC的内容送到DB6 ~ DB0;

显示数据寄存器(DDRAM)

DDRAM存储显示字符的字符码,其容量的大小决定着模块最多可显示的字符数目.DDRAM地址与LCD显示屏上的显示位置的对应关系如下:

执行显示移位操作时,对应的DDRAM地址也发生移位,以每行16个字符的显示为例,移位前后的地址对应关系如下:

CGROM

HD44780内置了192个常用字符的字模,存于字符产生器CGROM(Character Generator ROM)中。在CGROM中,模块已经以8位二进制数的形式,生成了5x8点阵的字符字模组字符字模(一个字符对应一组字模),字符字模是与显示字符点阵相对应的8x8矩阵位图数据(与点阵行相对应的矩阵行的高三位为“0"),同时每一组字符字模都有一个由其在CGROM中存放地址的高八位数据组成的字符码对应。

CGRAM

另外还有8个允许用户自定义的字符产生RAM,称为CGRAM(Character Generator RAM)
       就单屏结构的模块而言,字符码地址范围为00H ~ FFH,其中00H ~ 07H字符码与用户在CGRAM中生成的自定义图形字符的字模组相对应:至于双屏或者多屏结构的模块,由于各显示屏结构部分的工作分别由独立的使能信号E控制,因而各结构部分间字符的发生互不影响,每一显示屏结构部分的字符码地址范围为00H ~ FFH,其中00H ~ 07H字符码与用户在CGRAM中生成的自定义图形字符的字模组相对应。

指令

清屏指令

光标归位指令

进入模式设置指令

显示开关控制指令

设定显示屏或光标移动方向指令


功能设定指令

设定CGRAM地址指令

设定DDRAM地址指令

读取忙信号或AC地址指令

数据写入DDRAM或CGRAM指令

从 CGRAM或DDRAM读出数据的指令

示例程序

stdint.h见【51单片机快速入门指南】1:基础知识和工程创建

LCD1602.c

#include <STC89C5xRC.H>
#include "stdint.h"
#include "LCD1602.h"//******************以下内容移植时需修改******************void delay_ms(int i);#define LCD1602_Port P0sbit RS_Pin = P2 ^ 6;            //寄存器选择位,RS位
sbit WR_Pin = P2 ^ 5;          //读写选择位,RW
sbit EN_Pin = P2 ^ 7;          //使能信号位,E位void LCD1602_Delay()
{//主频快就加延时
}void LCD1602_RS_H()
{RS_Pin = 1;
}void LCD1602_RS_L()
{RS_Pin = 0;
}void LCD1602_WR_H()
{WR_Pin = 1;
}void LCD1602_WR_L()
{WR_Pin = 0;
}void LCD1602_EN_H()
{EN_Pin = 1;
}void LCD1602_EN_L()
{EN_Pin = 0;
}void LCD1602_Write_Port(uint8_t Data)
{#ifdef USE_4_PinLCD1602_Port &= 0x0F;LCD1602_Port |= (Data << 4);
#elseLCD1602_Port = Data;
#endif
}uint8_t LCD1602_Read_Port()
{#ifdef USE_4_Pin    //4线下好像没有意义return 0;
#elsereturn LCD1602_Port;
#endif
}//******************以上内容移植时需修改******************unsigned char code LCD1602_DIY_Char[64]=  //8个自定义字符 地址为0x00~0x07
{0x02,0x04,0x0F,0x12,0x0F,0x0A,0x1F,0x02,//年0x0F,0x09,0x0F,0x09,0x0F,0x09,0x09,0x11,//月0x1F,0x11,0x11,0x1F,0x11,0x11,0x1F,0x00,//日0x16,0x09,0x08,0x08,0x08,0x09,0x06,0x00,//℃0x00,0x11,0x0A,0x04,0x0A,0x11,0x00,0x00,//×0x00,0x04,0x00,0x1F,0x00,0x04,0x00,0x00,//÷0x00,0x0E,0x11,0x11,0x11,0x0A,0x1B,0x00,//Ω0x00,0x11,0x11,0x11,0x19,0x16,0x10,0x00,//μ
};/*****************************************************
函数功能:判断液晶模块的忙碌状态
返回值:1: 忙碌; 0: 不忙
***************************************************/
uint8_t LCD1602_Busy_Test(void)
{#ifdef USE_4_Pindelay_ms(2);return 0;
#elsereturn ((LCD1602_Operation(0, 1, 0) & 0x80) && 1);
#endif
}uint8_t LCD1602_Operation(uint8_t Cmd_Data_Flag, uint8_t Write_Read_Flag, uint8_t Data)
{if(Cmd_Data_Flag)LCD1602_RS_H();elseLCD1602_RS_L();if(Write_Read_Flag)LCD1602_WR_H();elseLCD1602_WR_L();LCD1602_Delay();       //给硬件反应时间if(Write_Read_Flag){LCD1602_EN_H();LCD1602_Delay();    //给硬件反应时间Data = LCD1602_Read_Port();}else{LCD1602_EN_L();LCD1602_Write_Port(Data);LCD1602_Delay(); //给硬件反应时间LCD1602_EN_H();LCD1602_Delay();    //给硬件反应时间}LCD1602_EN_L();return Data;
}/*****************************************************
函数功能:将一个字节写入液晶模块
入口参数:Byte 字节, Cmd_Data_Flag 0为命令, 1为数据
***************************************************/
void LCD1602_Write_Byte(uint8_t Byte, uint8_t Cmd_Data_Flag)
{while (LCD1602_Busy_Test());   //如果忙就等待
#ifdef USE_4_PinLCD1602_Operation(Cmd_Data_Flag, 0, Byte >> 4);while (LCD1602_Busy_Test());LCD1602_Operation(Cmd_Data_Flag, 0, Byte & 0x0F);
#elseLCD1602_Operation(Cmd_Data_Flag, 0, Byte);
#endif
}void LCD1602_DIY_Char_Init(void)
{unsigned char i;LCD1602_Write_Byte(LCD1602_Set_CGRAM_Addr, 0); //开始写入你要显示的自定义字符、汉字代码   for(i = 0; i < 64; i++){LCD1602_Write_Byte(LCD1602_DIY_Char[i], 1);   //开始写入你要显示的自定义字符、汉字代码}
}/*****************************************************
函数功能:指定字符显示的实际地址
入口参数:row 行:0或1 col:列
***************************************************/
void LCD1602_Write_Address(uint8_t row, uint8_t col)
{if(row)LCD1602_Write_Byte(col | 0xc0, 0);  elseLCD1602_Write_Byte(col | 0x80, 0);  //显示位置的确定方法规定为"80H+地址码x"
}void LCD1602_Write_Str(char *Str)
{while (*Str)                       //检测字符串结束标志{LCD1602_Write_Byte(*Str++, 1);    //发送当前字符}
}/*****************************************************
函数功能:对LCD的显示模式进行初始化设置
***************************************************/
void LCD1602_Init(void)
{#ifdef USE_4_PinLCD1602_Write_Byte(LCD1602_Cursor_Return, 0);LCD1602_Write_Byte(LCD1602_Config | LCD1602_4PIN | LCD1602_2Row | LCD1602_5X7, 0);
#elseLCD1602_Write_Byte(LCD1602_Config | LCD1602_8PIN | LCD1602_2Row | LCD1602_5X7, 0);
#endifLCD1602_Write_Byte(LCD1602_Display_Switch | Display_Enable | Cursor_Enable | Cursor_Blink_Enable, 0);LCD1602_Write_Byte(LCD1602_Cursor_Screen_Mode | Cursor_Right_Mode | Screen_Static_Mode, 0);LCD1602_DIY_Char_Init();LCD1602_Write_Byte(LCD1602_Clr, 0);   //清屏幕指令,将以前的显示内容清除
}

LCD1602.h

#ifndef LCD1602_H_
#define LCD1602_H_#define USE_8_Pin
//#define USE_4_Pin#ifdef USE_8_Pin
#ifdef USE_4_Pin
#error
#endif
#endif#define LCD1602_Clr                   0x01
#define LCD1602_Cursor_Return       0x02#define LCD1602_Cursor_Screen_Mode  0x04#define Cursor_Left_Mode        0x00    #define Cursor_Right_Mode       0x02#define Screen_Static_Mode      0x00#define Screen_Right_Mode       0x01#define LCD1602_Display_Switch      0x08#define Display_Disable         0x00#define Display_Enable          0x04#define Cursor_Disable          0x00#define Cursor_Enable           0x02#define Cursor_Blink_Disable    0x00#define Cursor_Blink_Enable     0x01#define LCD1602_Cursor_Screen_Move  0x10#define Cursor_Left             0x00#define Cursor_Right            0x04#define Screen_Left             0x08#define Screen_Right            0x0c#define LCD1602_Config              0x20#define LCD1602_4PIN            0x00#define LCD1602_8PIN            0x10#define LCD1602_1Row            0x00#define LCD1602_2Row            0x08#define LCD1602_5X7             0x00#define LCD1602_5X10            0x04#define LCD1602_Set_CGRAM_Addr      0x40
#define LCD1602_Set_DDRAM_Addr      0x80uint8_t LCD1602_Busy_Test(void);
uint8_t LCD1602_Operation(uint8_t Cmd_Data_Flag, uint8_t Write_Read_Flag, uint8_t Data);
void LCD1602_Write_Byte(uint8_t Byte, uint8_t Cmd_Data_Flag);
void LCD1602_Write_Address(uint8_t row, uint8_t col);
void LCD1602_Write_Str(char *Str);
void LCD1602_Init(void);#endif

测试程序

四线和八线在LCD1602.h中控制

main.c

#include <STC89C5xRC.H>
#include "intrins.h"
#include "stdint.h"
#include "LCD1602.h"void Delay1ms()       //@11.0592MHz
{unsigned char i, j;_nop_();i = 2;j = 199;do{while (--j);} while (--i);
}void delay_ms(int i)
{while(i--)Delay1ms();
}void main(void)
{char i;LCD1602_Init();LCD1602_Write_Address(0, 0);LCD1602_Write_Str("0123456789ABCDEF");LCD1602_Write_Address(1, 0);for(i = 0; i < 8; ++i)LCD1602_Write_Byte(i, 1);while(1){   }
}

实验现象

仿真现象

需要注意的是,Proteus仿真时存储模式需设为Small才能正确显示,很神秘。

八线制

四线制

【51单片机快速入门指南】6.1:LCD1602的八线、四线控制及自定义符号,完美兼容Proteus仿真相关推荐

  1. 【51单片机快速入门指南】6.4:DHT11、DHT22单总线温湿度传感器

    目录 硬知识 DHT11 DHT22 通信协议 读取步骤 数据解读 DHT11 DHT22 示例程序 DHT11_22.c DHT11_22.h 测试程序 main.c 实验现象 DHT11 DHT2 ...

  2. 【51单片机快速入门指南】4.6:I2C 与 PCF8563实时时钟日历芯片

    目录 硬知识 概述 特性 功能描述 报警功能模式 定时器模式 CLKOUT输出 复位低电压检测器和时钟监视器 低电压检测器和时钟监视器 寄存器结构 寄存器概述 BCD编码格式寄存器概述 Control ...

  3. 【51单片机快速入门指南】6.3:DS18B20 单总线数字温度计的多路读取

    目录 硬知识 DS18B20介绍 时序 初始化时序 写时序 读时序 命令 ROM 操作命令 ROM 搜索举例 存贮器操作命令 示例程序 DS18B20.c DS18B20.h 测试程序 定时器中断服务 ...

  4. 【51单片机快速入门指南】5.3:SPI控制晶联讯JLX12864G_08602 LCD屏幕

    目录 示例程序 JLX12864G_08602.c JLX12864G_08602.h JLX12864G_08602_Font.c JLX12864G_08602_Font.h 测试程序 main. ...

  5. 【51单片机快速入门指南】5.1:SPI与DS1302时钟芯片

    目录 硬知识 DS1302 简介 DS1302 使用 控制寄存器 日历/时钟寄存器 DS1302 的读写时序 电路设计 示例程序 DS1302.c DS1302.h 测试程序 main.c 实验现象 ...

  6. 【51单片机快速入门指南】4.5:I2C 与 TCA6416实现双向 IO 扩展

    目录 硬知识 IO 扩展芯片 TCA6416A TAC6416A 的寄存器 IO 输入寄存器 IO 输出寄存器 IO 反相寄存器 IO 方向寄存器 TCA6416A 的操作 TCA6416A 写数据 ...

  7. 【51单片机快速入门指南】4.4.3:Madgwick AHRS 九轴姿态融合获取四元数、欧拉角

    目录 传感器的方向 源码 Madgwick_9.c Madgwick_9.h 使用方法 测试 main.c 效果 STC15F2K60S2 22.1184MHz Keil uVision V5.29. ...

  8. 【51单片机快速入门指南】4.4.2:Mahony AHRS 九轴姿态融合获取四元数、欧拉角

    目录 传感器的方向 源码 Mahony_9.c Mahony_9.h 使用方法 测试 main.c 效果 STC15F2K60S2 22.1184MHz Keil uVision V5.29.0.0 ...

  9. 【51单片机快速入门指南】4.4.1:python串口接收磁力计数据并进行最小二乘法椭球拟合

    目录 硬知识 Python代码 使用方法 串口收集数据 椭球拟合 验证 STC15F2K60S2 16.384MHz Keil uVision V5.29.0.0 PK51 Prof.Develope ...

最新文章

  1. Flask-RESTful的简单使用
  2. SaaS加速器 I 商业中心:提供商业助力 共享商业成功
  3. jQuery1.4的15个新特性实例精讲
  4. linux hexdump命令详解
  5. ubuntu19.10锁屏时间调节
  6. 【转】理解字节序 大端字节序和小端字节序
  7. 安卓一步一步搭建组件化
  8. 对口计算机专业分数线,湖南省2021年普通高校招生本科批(职高对口类)平行一志愿投档分数线公布...
  9. 公差与配合查询计算过程讲解
  10. dell服务器开机蓝屏无限重启,戴尔电脑不停蓝屏重启怎么办
  11. Cocos2d-x教程(33)-三维物体AABB碰撞检测算法
  12. 判断距离1970年1月1日的天数
  13. 一个简单光栅器的实现(五) 光栅化阶段
  14. 证监会叫停VR等行业跨界定增,福兮祸兮?
  15. 斯坦福自然语言处理习题课1——绪论
  16. python爬取付费漫画_python selenium爬取kuku漫画
  17. 什么是马丁格尔策略?
  18. jQuery仿京东左侧物品导航栏练习
  19. 大学生学计算机专业开学要带电脑吗,大学新生刚开学需要带电脑吗
  20. java微信支付签名生成_微信APP支付(Java后台生成签名具体步骤)

热门文章

  1. DB2 常用操作命令集合
  2. CentOS7.0 安装 tomcat-9.0
  3. leetcode733. 图像渲染(bfs)
  4. leetcode64. 最小路径和(dp)
  5. 邮箱如何秘密发送多个人邮件_如何发送秘密消息
  6. 前端绘制绘制图表_绘制图表(第2页):JavaScript图表库的比较
  7. oracle java认证_如何通过Oracle的Java认证-开发人员实用指南
  8. marlin 三角洲_三角洲湖泊和数据湖泊-入门
  9. (摘录)sockaddr与sockaddr_in,sockaddr_un结构体详细讲解
  10. 中介者模式分析、结构图及基本代码