1.什么是 1602?
LCD 屏,有 16 个引脚
2.16 个引脚
- 第 1,2 引脚:VDD、VS S 为 1602 供电的正负极,最佳供电电压为 5V。
- 第 3 引脚:VL 液晶显示偏压信号,即为显示屏的对比度调节端,当接电源时对比度最高,接低时对比对最低,在使用中往往通过接一个可变电阻来调节显示对比度。
- 第 4 引脚:RS 为数据/命令选择端,当 RS=1 时,选择操作 1602 内部的数据寄存器,当 RS=0 时,选择操作内部指令寄存器。
- 第 5 引脚:R/W 为读写选择端,当 R/W=1 时,对 1602 进行读数据操作,当 R/W=0 时,对 1602 进行写操作。
- 第 6 引脚:E 为 1602 液晶显示模块使能端,与 RS,R/W 配合使用在高电平时读取信息,负跳变时执行指令。
- 第 7-14 引脚:为 8 位的双向数据端口 D0~D7。
- 第 15,16 引脚:BLA 背光源正极,BLK 背光源负极。BLK 接地,BLA 接电源 VDD 时,1602 液晶背光点亮,接 GND 时,背光熄灭。
3.引脚线路图
4.读写时序
4.1 读一个字节
- RS 对应 P36
- R/W 对应 P35
- E 对应 P34
- D0-D7 对应 P2
步骤
- RS 无论高低,RS 为高,当前模式为内部数据寄存器,RS=0 为内部指令寄存器
- R/W 变为读模式 高为读,低为写,经过 tsp1 时间后拉高 E
- E 的高电平时间维持 tpw
- 在 E 的电平拉高时不超过 td,读取 d0-d7
- 最后将 E 拉低完成读取
unsigned char RD_sta() //读状态函数
{
unsigned char sta;
RS_1602 = 0;
RW_1602 = 1; //进入读 1602 状态模式
EN_1602 = 1; //拉高使能信号
sta = P2; //将 1602 状态数据读取
EN_1602 = 0; //拉低使能,完成读操作
return sta; //将状态值返
}
4.2 写一个字节
写操作时序与读操作的基本一致,唯一不同的是,在使能信号 E 拉高之前 tSP2
单片机必须把需要写的数据送到数据端口上。当 RS=1 时,表示将要往 1602 写
数据,当 RS=0 时,表示将要往 1602 里面写指令。
void WR_Dat(unsigned char dat) //写数据函数
{
Ready(); //检测 1602 是否处于空闲状态
RS_1602 = 1;
RW_1602 = 0; //进入写数据模式
P2 = dat; //将数据输出
EN_1602 = 1; //拉高使能信号
EN_1602 = 0; //拉低使能,完成写操作
}
void WR_Cmd(unsigned char cmd) //写指令函数
{
Ready(); //检测 1602 是否处于空闲状态
RS_1602 = 0;
RW_1602 = 0; //进入写指令模式
P2 = cmd; //将指令数据输出
EN_1602 = 1; //拉高使能信号
EN_1602 = 0; //拉低使能,完成写操作
}
4.3 状态检测
- 0-6 位为数据指针地址
- 7 位表示使能状态,根据前两个时序图,无论读写使能 E 都被拉高,所以 1 为忙状态,0 为空闲状态
void Ready() //空闲检测函数
{
P2 = 0xFF;
while (RD_sta() & 0x80)
; //bit7 等于 1 表示忙,一直检测到 0 为止
}
4.4 指令
如下是显示屏初始化过程
-
- 写指令 38H:设置 16x2 显示,5x7 点阵,8 位数据接口;
-
- 写指令 0CH:开显示,关闭光标;
-
- 写指令 06H:读或写完一个字符后,地址指针、光标均加 1;
-
- 写指令 01H:数据指针清零、所示显示清零
void Init_1602() //1602 初始化函
{
WR_Cmd(0x38); //设置 16x2 显示,5x7 点阵,8 位数据接口
WR_Cmd(0x0C); //开显示,关闭光标
WR_Cmd(0x06); //读或写完一个字符后,地址指针、光标均加 1
WR_Cmd(0x01); //数据指针清零、所示显示清零
}
5. 显示操作
5.1 字符
两行 32 个字符
- 第一行:0x00-0x27
- 第二行:0x40-0x67
写的时候需要在 0x80 地址上附加
第二行第一列写,那么地址为 0x80+0x40
上图为字符表
比如 C
为 0x43
上图为 ASCII 表,hex 也为 0x43
所以可以直接写入 C
不用做转换了
5.2 行列显示
void Disp_1602_str(unsigned char row, unsigned char column, char *str)
{
unsigned char addr;
addr = (row - 1) * 0x40 + (column - 1); //组合成地址
WR_Cmd(0x80 + addr); //写地址命令
while (*str) //判断 str 字符串是否已结束
{
WR_Dat(*str++); //将 str 字符串数据依次写入
}
}