一点小总结~
源代码正在整理中,等MSP430F5529与LCD1602显示模块(下)发布后再一起上传至Github,敬请期待。
显示容量: 16X2个字符
芯片工作电压: 4.5~5.5V
工作电流: 2.0mA(5.0V)
模块最佳工作电压: 5.0V
字符尺寸: 2.95X4.35(WXH)mm
VSS 电源地
VDD 电源正极(5V)
V0 液晶显示偏压信号
RS 数据/命令选择端(H/L)
RW 读/写选择端(H/L)
E 使能信号
D0 Data I/O
D1 Data I/O
D2 Data I/O
D3 Data I/O
D4 Data I/O
D5 Data I/O
D6 Data I/O
D7 Data I/O
A 背光源正极
K 背光源负极
GND 电源地
VCC 电源正极(5V)
SDA 数据I/O口
SCL 数据时钟
读状态:
输入:RS=L,RW=H,E=H
输出:D0~D7=状态字
写指令:
输入:RS=L,RW=L,D0~D7=指令码,E=高脉冲
输出:无
读数据:
输入:RS=H,RW=H,E=H
输出:DO~D7=数据
写数据:
输入:RS=H,RW=L,D0~D7=数据,E=高脉冲
输出:无
1、清屏指令(clear display) RS=L,RW=L,D0~D7=0000_0001
功能:
清除液晶显示器,即将DDRAM中的内容全部填入20H(空白字符)
光标撤回至显示屏左上角
将地址计数器(AC)设为0
光标移动方向为从左向右,并且DDRAM的自增量为1(I/D=1)
2、光标归位指令(Return Home)RS=L,RW=L,D0~D7=0000_001X
功能:
将地址计数器(AC)设为00H
DDRAM内容保持不变,光标移至左上角
3、进入模式设置指令(Entry Mode Set)
功能:
设定每次写入1位数据后光标移位方向并且设定光标每次写入一个字符后是否移动 。
I/D = 0时光标左移,DDRAM地址自增1
I/D = 1时光标右移,DDRAM地址自增1(当从CGRAM中读取或写入数据时,CGRAM操作与DDRAM相同)
SH = 0 且 DDRAM是读操作(CGRAM读或写),整个屏幕不移动
SH = 1 且DDRAM是写操作,整个屏幕移动,移动方向由I/D决定。
4、显示开关控制(Display ON/OFF Control)
功能:
D = 1 , 显示功能开
D = 0 , 显示功能关,但是DDRAM中的数据依然保留
C = 1 , 有光标
C = 0 , 没有光标
B = 1 , 光标闪烁
B = 0 , 光标不闪烁
5、设置显示屏或光标移动方向的指令
功能:
整屏的移动或光标移动
S/C =0 R/L =0 光标左移 ,地址计数器减1(即显示内容和光标一起左移)S/C =0 R/L =1 光标右移 ,地址计数器加1(即显示内容和光标一起右移)
S/C =1 R/L =0 显示内容左移 ,光标不移动
S/C =1 R/L =1 显示内容右移 ,光标不移动
6、功能设定指令
功能:
设定数据总线位数、显示的行数及字形。
DL=1 ,数据总线是8位
DL=0 ,数据总线是4位
N=0 ,显示一行
N=1 ,显示两行
F=0 ,5*8 点阵/字符
F=1 ,5*11点阵/字符
7.设置DDRAM(光标)地址
功能:
设置地址计数器AC的值,实则上是设置光标所在的位置。
DDRAM的地址与显示屏对照关系(N=LOW)
非常感谢MSP430F5529&LCD1602程序的作者Aliqiji提供思路和代码!
#define DataDir P3DIR //D0~D7分别对应P3.0-P3.7
#define DataPort P3OUT
#define CLR_RS P1OUT&=~BIT3; //RS = P1.3
#define SET_RS P1OUT|=BIT3;
#define CLR_RW P1OUT&=~BIT4; //RW = P1.4
#define SET_RW P1OUT|=BIT4;
#define CLR_EN P1OUT&=~BIT5; //EN = P1.5
#define SET_EN P1OUT|=BIT5;
void GPIO_init(){
P1DIR |= BIT3+BIT4+BIT5; //控制线端口设为输出状态
DataDir = 0xFF;
}
void delay_ms(unsigned int ms){ //For MSP430F5529
for(;ms>0;ms--) __delay_cycles(1000);
}
void LCD1602_WriteCMD(unsigned char cmd)
{
CLR_EN;
CLR_RS; //指令
CLR_RW; //写
DataPort=cmd; //指令数据传到P0口待发送给LCD1602
SET_EN;
CLR_EN; //产生下降沿
delay_ms(1);
}
void LCD1602_WriteDATA(unsigned char Data)
{
CLR_EN;
SET_RS; //数据
CLR_RW; //写
DataPort=Data;
SET_EN;
CLR_EN; //产生下降沿
delay_ms(1);
}
void LCD1602_Init()
{
GPIO_init();
LCD1602_WriteCMD(0x38); // 置功能,8位总线,双行显示,显示5X7的点阵字符
LCD1602_WriteCMD(0x0f); // 显示开关控制,开显示, 有光标,闪烁
LCD1602_WriteCMD(0x06); // 光标和显示位置设置, 光标移动方向右移,屏幕上所有文字不动
LCD1602_WriteCMD(0x01); // 清显示,指令码01H,光标复位到地址00H位置
delay_ms(10);
}
void DispChar(unsigned char data)
{
LCD1602_WriteDATA(data);
}
void DispStr(unsigned char *str)
{
while(*str != 0){
DispChar(*str++);
}
}
这部分的内容在前文指令说明中***设置DDRAM(光标)地址*** 处有所提及。
设置指针在第一行最左端
LCD1602_WriteCMD(0x80);
设置指针在第二行最左端
LCD1602_WriteCMD(0x80 + 0x40);
在显示速度要求不高的情况下,八线并口模式占用了过多的单片机管脚,如果管脚资源紧张,可以试一试使用四线模式。
四线模式是指只使用数据端口D4~D7完成与八线模式一样的操作,但不同的是,四线模式只能写而不能读。
四线模式的时序操作与八线模式不同点在于,一个指令或者一个数据,需要传输两次,也就是EN产生两次下降沿,第一次下降沿的时候传输高四位数据,第二次下降沿的时候传输低四位数据。
那么,我们应该怎么修改上述代码来实现四线模式呢~请看下文
#define DataDir P3DIR
#define DataPort P3OUT
#define CLR_RS P1OUT&=~BIT3; //RS = P1.3
#define SET_RS P1OUT|=BIT3;
#define CLR_RW P1OUT&=~BIT4; //RW = P1.4
#define SET_RW P1OUT|=BIT4;
#define CLR_EN P1OUT&=~BIT5; //EN = P1.5
#define SET_EN P1OUT|=BIT5;
由于我当时写的综合代码中,P3.4端口被占用,所以我采用了P3.0,P3.5,P3.6,P3.7四个端口作为数据口。
void GPIO_init(){
P1DIR |= BIT3+BIT4+BIT5; //控制线端口设为输出状态
DataDir = BIT0+BIT5+BIT6+BIT7;
}
void Set_DataPort(unsigned char Data){
if(Data&BIT4) P3OUT |= BIT0;
else P3OUT &= ~BIT0;
if(Data&BIT5) P3OUT |= BIT5;
else P3OUT &= ~BIT5;
if(Data&BIT6) P3OUT |= BIT6;
else P3OUT &= ~BIT6;
if(Data&BIT7) P3OUT |= BIT7;
else P3OUT &= ~BIT7;
}
void LCD1602_WriteCMD(unsigned char cmd)
{
CLR_EN;
CLR_RS; //指令
Set_DataPort(cmd&0b11110000); //指令数据传到P0口待发送给LCD1602
SET_EN; //LCD1602使能口
CLR_EN; //产生下降沿
Set_DataPort((cmd&0b00001111)<<4); //指令数据传到P0口待发送给LCD1602
SET_EN;
CLR_EN
delay_ms(1);
}
void LCD1602_WriteDATA(unsigned char data)
{
CLR_EN;
SET_RS; //指令
Set_DataPort(data&0b11110000); //数据传到P0口待发送给LCD1602
SET_EN; //LCD1602使能口
CLR_EN; //产生下降沿
Set_DataPort((data&0b00001111)<<4); //数据传到P0口待发送给LCD1602
SET_EN;
CLR_EN
delay_ms(1);
}
void LCD1602_Init()
{
GPIO_init();
LCD1602_WriteCMD(0b00101000); // 置功能,4位总线,双行显示,显示5X7的点阵字符 //00101000
LCD1602_WriteCMD(0b00001100); // 显示开关控制,开显示, 有光标,闪烁
LCD1602_WriteCMD(0b00000110); // 光标和显示位置设置, 光标移动方向右移,屏幕上所有文字不动
LCD1602_WriteCMD(0b00000001); // 清显示,指令码01H,光标复位到地址00H位置
delay_ms(10);
}
接线按照1.3接口说明以及代码中所选择的端口接即可,背光源A、K一般情况下是不用接的。
特别要说明的是,V0(液晶显示偏压信号)的接线,数据手册中说它要接一个电位器到地以调节对比度,如下图所示。
所以我们可以把它接到MSP430F5529的拨码电位器(P6.5)上,接上之后就可以通过拨动拨码电位器调节屏幕的对比度啦!
通过学习LCD1602的操作,我们可以了解到单片机与外设间进行并口通信的一般原理。并口通信速度快,但是占用的管脚多,接线麻烦,在管脚资源紧张的情况下还会导致很多其他的问题,虽然LCD1602提供的四线模式可以在一定程度上缓和这种矛盾,但是有没有其他更省管脚资源的方法呢?答案是有的,那就是采用串口通信,下篇文章我将讲讲利用I2C协议与LCD1602进行串口通信~
LCD1602指令集解读
MSP430F5529&LCD1602程序 作者:Aliqiji
LCD1602中文数据手册