本文使用proteus仿真通过AT89C52驱动LCD1602(HD44780驱动-16线)
引脚介绍
序号 | 引脚 | 引脚说明 | 序号 | 引脚 | 引脚说明 |
---|---|---|---|---|---|
1 | VSS | 电源地 | 9 | D2 | 数据位2 |
2 | VDD | 电源正 | 10 | D3 | 数据位3 |
3 | VEE | 显示对比度 | 11 | D4 | 数据位4 |
4 | RS | 数据/命令 | 12 | D5 | 数据位5 |
5 | RW | 读/写 | 13 | D6 | 数据位6 |
6 | E | 使能 | 14 | D7 | 数据位7 |
7 | D0 | 数据位0 | 15 | BLA | 背光正 |
8 | D1 | 数据位1 | 16 | BLK | 背光负 |
其中proteus中没有BLA和BLK引脚,但使用模块时是有的。
指令集
序号 | 指令 | RS | RW | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | ||
1 | 清屏 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | ||
2 | 光标复位 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | x | ||
3 | 输入方式设置 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | I/D | S | ||
4 | 显示开关控制 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | D | C | B | ||
5 | 光标或字符移位控制 | 0 | 0 | 0 | 0 | 0 | 1 | S/C | R/L | x | x | ||
6 | 功能设置 | 0 | 0 | 0 | 0 | 1 | DL | N | F | x | x | ||
7 | 字符发生存储器地址设置 | 0 | 0 | 0 | 1 | 字符发生存储器地址 | |||||||
8 | 数据存储器地址设置 | 0 | 0 | 1 | 显示数据存储器地址 | ||||||||
9 | 读忙标志或地址 | 0 | 1 | BF | 计数器地址 | ||||||||
10 | 写入数据至CGRAM或DDRAM | 1 | 0 | 要写入的数据内容 | |||||||||
11 | 从CGRAM或DDRAM中读取数据 | 1 | 1 | 读取的数据内容 |
- 指令3:
I/D表示光标的移动方向,高电平右移,低电平左移;
S表示显示屏上所有文字是否左移或右移,高电平表示有效,低电平表示无效。 - 指令4:
D用于控制整体显示的开与关,高电平表示开显示,低电平表示关显示;
C用于控制光标的开与关,高电平表示有光标,低电平表示无光标;
B用于控制光标是否闪烁,高电平闪烁,低电平不闪烁。 - 指令5:S/C表示在高电平时移动显示的文字,低电平时移动光标。
- 指令6:
DL表示在高电平时为8位总线,低电平时为4位总线;
N表示在低电平时为单行显示,高电平时双行显示;
F表示在低电平时显示5×7的点阵字符,高电平时显示5×10的点阵字符。 - 指令7:字符发生器RAM地址设置。
- 指令8:DDRAM地址设置。
- 指令9:BF为忙标志位,高电平表示忙,此时模块不能接收命令或数据,如果为低电平则表示不忙。
使用例程
初始化流程:功能设置(指令6)---->显示开关控制(指令4)---->输入方式设置(指令3)---->清屏(指令1)
void LCD_Init(void)
{
LCD_WriteCmd(0x38); //显示16*2 5*7/字符 8线数据
LCD_WriteCmd(0x0C); //开显示 不显示光标
LCD_WriteCmd(0x06); //地址加1,当写入数据后光标右移
LCD_WriteCmd(0x01); //清屏
}
显示字符串流程:设置光标位置(指令8)—>写入显示字符(指令10)
void LCD_SetPos(unsigned char line, unsigned char column) //设置光标位置
{
(line == 0) ? LCD_WriteCmd(0x80+column) : LCD_WriteCmd(0x80+0x40+column);
}
void LCD_ShowStr(unsigned char line, unsigned char column, unsigned char *str)
{
LCD_SetPos(line, column);
while(*str != '\0') LCD_WriteData(*str++);
}
接着就是补充写命令函数以及写数据函数
void LCD_WriteCmd(unsigned char cmd)
{
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
P0 = cmd;
delay_ms(2);
LCD_EN = 1;
delay_ms(2);
LCD_EN = 0;
}
void LCD_WriteData(unsigned char dat)
{
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
P0 = dat;
delay_ms(2);
LCD_EN = 1;
delay_ms(2);
LCD_EN = 0;
}
由于51的速度有点慢,所以不用像STM32一样 加延时之类的。
简单的初始化和显示字符串步骤就是这样的(更多玩法反正我觉得没必要不如上大屏幕,看着爽)。
最后使用proteus仿真时的接线为(其中P0口需要接上拉电阻4.7k)
P0.0—>D0
P0.1—>D1
P0.2—>D2
P0.3—>D3
P0.4—>D4
P0.5—>D5
P0.6—>D6
P0.7—>D7
P2.5—>E
P2.6---->RW
P2.7—>RS