3.4.1LCD1602简介
1602LCD分为带背光和不带背光两种,基控制器大部分为HD44780,带背光的比不带背光的厚,是否带背光在应用中并无差别。
1602LCD一般带有字库,也就是主机往指定的地方写ASCII码就可以显示想要的字符,无需复杂的取模。
1602液晶模块内部的控制器共有11条控制指令,如下表所示:
序号 |
指令 |
RS |
R/W |
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 |
* |
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 |
* |
* |
6 |
置功能 |
0 |
0 |
0 |
0 |
1 |
DL |
N |
F |
* |
* |
7 |
置字符发生存贮器地址 |
0 |
0 |
0 |
1 |
字符发生存贮器地址 |
8 |
置数据存贮器地址 |
0 |
0 |
1 |
显示数据存贮器地址 |
9 |
读忙标志或地址 |
0 |
1 |
BF |
计数器地址 |
10 |
写数到CGRAM或DDRAM) |
1 |
0 |
要写的数据内容 |
11 |
从CGRAM或DDRAM读数 |
1 |
1 |
读出的数据内容 |
3.4.2LCD1602读写时序及代码实现
对于LCD1602写之前一般要确认是否正在忙,否则会导致写入失败,对于本设计而言,这里不做检测,直接写命令和数据,简化设计
写命令和写数据的时序和代码实现一致。以写命令为例:file:///C:/Users/yao/AppData/Local/Temp/msohtmlclip1/01/clip_image002.jpg
代码实现:
这里同样使用把时序整合带状态机的概念,把R/W,RS,E 拉低,输出数据到并行管脚计数一段时间后,拉高E管脚,在计数一段时间后拉低E管脚一段时间,这样完成了写命令的过程,握手信号的设计与IIC模块的一致。
case stateis
whenx"0"=>--写时序产生
done_flag<= '0';
--en
if cnt_div = 10#0# then LCD_EN<='0';
elsif cnt_div = Period_Pos thenLCD_EN<='1'; LCD_Data<= wr_data;
elsif cnt_div = Period_Neg thenLCD_EN<='0';
end if;
if cnt_div =10#0# thenLCD_RS<='0';--写命令
-- elsif cnt_div = Period thenLCD_RS<='1';
end if;
if cnt_div = Period then state <=x"1"; cnt_div<=(others =>'0');
else cnt_div<=cnt_div+1;
end if;
when x"1" =>--产生一个时钟的高电平
done_flag<='1';
state <= x"2";
when x"2" =>--产生一个时钟的高电平
done_flag<='0';
state <= x"0";
whenothers =>state <= x"0";
end case;
3.4.3LCD1602驱动设计总结
使用上述的写命令和写数据模块,通过握手通信进行同步,完成以下初始化过程(1)-(4),循环在(5),(6)状态就可以使LCD显示想要的字符
(1) 发送命令31h(设置8位数据线模式,单行,5*7)(这里使用单行显示的原因是LCD1602 3.3V供电后显示双行时亮度不够,故加了个数码管电路来显示温度)
(2) 发送命令01h(清屏)
(3) 发送命令06h(设置每写入一个数据光标右移,地址加1)
(4) 发送命令0fh(显示开及光标有并闪烁)
(5) 发送地址
(6) 发送数据(ASCII码) |