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