--- title: 51单片机学习笔记(九) tags: - 51单片机 categories: - 硬件学习 - 51单片机 description: LCD1602液晶显示器基本操作使用 abbrlink: '17528481' date: 2021-08-21 14:32:19 cover: https://gitee.com/ajream/images/raw/master/img/20210910204417_51cover.png --- ## 简单介绍 ### 主要参数 显示容量:16X2个字符 芯片工作电压:4.5~5.5V, 最佳工作电压5.0V(2.0mA) ### 引脚说明 RS:为0时是指令输入,也就是表示显示在哪个“格子”的(1602有16X2共32个"格子"); ​ 为1时表示数据输入,即每个”格子“显示的内容 R/W:为1时是读,0是写; E:读写数据时要置1 D0~D7:数据输入输出 ![image-20210825154248774](https://gitee.com/ajream/images/raw/master/img/20210825154252_image-20210825154248774.png) ## 基本操作 ### 读写操作 - 读状态,输入:RS=0, RW=1, E=0; 此时输出数据D0~D7为状态字,每一位都有各自的状态; 其中D0-D6表示当前数据地址指针的数值,D7的状态表示读写操作使能,如果是1表示禁止读写,0表示允许读写; ![image-20210825155602088](https://gitee.com/ajream/images/raw/master/img/20210825155603_image-20210825155602088.png) - 写指令(即告诉1602要显示的位置):RS=0, RW=0, E=高脉冲,D0-D7为指令码 - 读数据:RS=1, RW=1, E=1, 此时D0-D7输出数据 - 写数据:RS=1, RW=0, D0-D7表示要写入的数据,E=高脉冲 ```c void Read_Busy() //读状态判断是芯片否处于”忙“状态 { uchar busy; P0 = 0xff; RS = 0; RW = 1; do { EN = 1; busy = P0; EN = 0; }while(busy & 0x80); } //写LCD1602命令一个字节 void Write_Cmd(uchar cmd) { Read_Busy();//判断忙 RS = 0; RW = 0; P0 = cmd; EN = 1; EN = 0; } //写一个字节数据 void Write_Dat(uchar dat) { Read_Busy(); RS = 1; RW = 0; P0 = dat; EN = 1; EN = 0; } ``` ### RAM地址映射 控制器内部自带了80X8位(即80Bytes)的RAM缓冲区,对应关系如下图: ![image-20210825160547241](https://gitee.com/ajream/images/raw/master/img/20210825160548_image-20210825160547241.png) 注意:第10——27和50——67的地址上的字符是无法显示的,只能显示前面16X2个地址上所存放的字符 ### 指令说明 初始化设置: 1. 显示模式设置:指令码0x38(二进制是00111000),表示设置16X2显示,5X7点阵,8位数据接口 2. 开/关光标设置:(配置时要转为16进制) 指令码(二进制形式)`00001DCB` - D=1开显示,D=0关显示 - C=1显示光标,C=0不显示光标 - B=1光标闪烁,B=0不闪烁 指令码(二进制形式)`000001NS` - N=1当读或写一个字符后地址和光标自动+1,N=0则为自动-1; - S=1当写入一个字符整屏显示左移(N=1)或右移(N=0)达到光标不动屏幕移动的效果; S=0当写入一个字符,屏幕显示不移动 3. 数据控制 控制器内部有地址指针,通过发送指令 `80H+地址码` (地址码范围是0——27H,40H——67H) 即可访问地址上的数据,进而进行设置 4. 其他指令: ![image-20210825162336247](https://gitee.com/ajream/images/raw/master/img/20210825162337_image-20210825162336247.png) ### 时序图 读操作时序图 ![image-20210825162506774](https://gitee.com/ajream/images/raw/master/img/20210825162508_image-20210825162506774.png) 写操作时序图 ![image-20210825162527365](https://gitee.com/ajream/images/raw/master/img/20210825162528_image-20210825162527365.png) 时序参数 ![image-20210825162600974](https://gitee.com/ajream/images/raw/master/img/20210825162602_image-20210825162600974.png) ## 例子 控制LCD1602显示字符12345 ```c #include typedef unsigned char uchar; typedef unsigned int uint; sbit RS = P3^5; sbit RW = P3^6; sbit EN = P3^4; //判断液晶忙,如果忙则等待 void Read_Busy() { uchar busy; P0 = 0xff; RS = 0; RW = 1; do { EN = 1; busy = P0; EN = 0; }while(busy & 0x80); } //写LCD1602命令一个字节 void Write_Cmd(uchar cmd) { Read_Busy();//判断忙 RS = 0; RW = 0; P0 = cmd; EN = 1; EN = 0; } //写一个字节数据 void Write_Dat(uchar dat) { Read_Busy(); RS = 1; RW = 0; P0 = dat; EN = 1; EN = 0; } void main() { Write_Cmd(0x38);//设置16*2显示 Write_Cmd(0x0f);//开显示,显示光标,光标闪烁 Write_Cmd(0x01);//清屏 Write_Cmd(0x06);//地址指针移位命令 Write_Cmd(0x80 | 0x06);//显示地址 Write_Dat(1 + '0'); //写入的字符要转换位ASCII码 Write_Dat(2 + '0'); Write_Dat(3 + '0'); Write_Dat(4 + '0'); Write_Dat(5 + '0'); while(1); } ```