lcd1602指令解读及基本程序
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
0x18字符全部左移一格,但光标不动
0x1c字符全部右移一格,但光标不动
0x10光标左移1格,且AC值减1
0x14光标右移1格,且AC值加1
*/
#include <intrins.h>
#define dataport P1
sbit RS=P2^ 6;
sbit RW=P2^5;
sbit EN=P2^4;
uchar code yue[]={0x0f,0x09,0x0f,0x09,0x0f,0x09,0x0b,0x11};// "月"
uchar code ri[]={0x1f,0x11,0x11,0x1f,0x11,0x11,0x11,0x1f};// "日"
//显示汉字
displyonecharacter(0,0,0x40,nian);
displyonecharacter(1,0,0x80,yue);
displyonecharacter(1,0,0xc0,ri);
0x01清屏,光标复位到地址00H位置
0x02光标归原点,DDRAM中内容不变,地址计数器AC=0;(此时地址为0x80)
0x0F开显示,显示光标,光标闪烁
0x0e开显示,显示光标,光标不闪烁
0x0c开显示,不显示光标
0x08只开显示
0x06地址加一,当写入数据的时候光标右移
设定显示屏或光标移动方向指令
}
void writecmd(unsigned char cmd) //写命令到LCD1602
{
waitfor(); //测忙
RS=0;RW=0; //选择指令寄存器写操作
dataport=cmd; //将数据送到数据口
EN=1;
EN=0; //使能下降沿脉冲
}
void init(void) //初始化函数
第一行: 00H 01H 02H 03H 04H 05H 06H 07H ..... 27H
第二行: 40H 41H 42H 43H 44H 45H 46H 47H ..... 67H
*/
1602LCD的RAM地址映射
液晶显示模块是一个慢显示器件,所以在执行每条指令之前一定要确认模块的忙标志为低电平,表示不忙,否则此指令失效。要显示字符时要先输入显示字符地址,也就是告诉模块在,哪里显示字符,图是1602的内部显示地址。
图五:LCD1602内部显示地址
例如第二行第一个字符的地址是40H,那么是否直接写入40H就可以将光标定位在第二行第一个字符的位置呢?这样不行,因为写入显示地址时要求最高位D7恒定为高电平1,所以实际写入的数据应该是01000000B(40H)+10000000B(80H)=11000000B(C0H)。
}
void location(unsigned char x,unsigned char y) //坐标函数
{
unsigned char temp;
temp=x&0x0f; //只要x数据的后四位
if(y)
{
temp=temp|0x40;
} //第一行为0第二行为1如果y=1则地址加0x40
temp|=0x80; //DDRAM地址的命令DB7为一
指令位D7 D6 D5 D4 D3 D2D1 D0
功能设置00 1DL NF* *
DL=1总线8位DL=0总线4位
N=0显单行N=1显双行
F=0 5X7点阵F=1 5X10点阵
lcd_1602指令汇总
0x28设置16*2显示,5*7点阵,4位数据接口
0x38设置16*2显示,5*7点阵,8位数据接口
9读忙标志或地址01 BF ----计数器地址(7位)---------
10写CGRAM或DDRAM 10 --------要写的数据内容(8位------
11读CGRAM或DDRAM 11 --------读出的数据内容(8位)-----
*/
// 51单片机对lcd1602一些基础程序
/*基本操作时序:
D3=1移字符D3=0移光标D2=1右移D2=0左移
6功能设置0000 1DL N F* *
DL=1总线8位DL=0总线4位
N=0显单行N=1显双行
F=0 5X7点阵F=1 5X10点阵
7置字符发生器地址00 01 -字符发生存贮器地址(6位)-
8置数据存贮器地址00 1--显示数据存贮器地址(7位)---
/*
HD44780内置了DDRAM、CGROM和CGRAM。
CGROM和CGRAM就是内置192个常用字符产生器,用户自定义的字符产生器RAM
DDRAM就是显示数据RAM,用来寄存待显示的字符代码。共80个字节,其地址和屏幕的对应关系如下表:
显示位置: 1 2 3 4 5 6 7 8 ..... 40
writecmd(address); //CGRAM里的地址初始值0x40每次加0x80
while(i--)
{
writedata(*p);
p++;
}
}
void DisplayOneChar(unsigned char x,unsigned char y,unsigned char address,unsigned char *p) //显示一个自定义字符
{
unsigned char i=8;
writecmd(address); //CGRAM里的地址初始值0x40每次加0x08
while(i--){Βιβλιοθήκη writedata(*p);
p++;
}
location(x,y); //设定要显示的位置
writedata((address&=0x3f)/0x08); //要从CGRAM中读出数据在1602上显示搞了半天发现CGRAM里的地址
写指令输入:RS=0,RW=0,E=下降沿脉冲,DB0~DB7=指令码输出:无
写数据输入:RS=1,RW=0,E=下降沿脉冲,DB0~DB7=数据输出:无
读状态输入:RS=0,RW=1,E=1输出:DB0~DB7=状态字
读数据输入:RS=1,RW=1,E=1输出:DB0~DB7=数据/
*/
/*
lcd_1602指令:
void waitfor() //检测忙信号函数
{
dataport=0xff;
RS=0;RW=1; //选择指令寄存器读操作RS=0指令RS=1数据; RW=0写RW=1读
EN=1; //使能操作
while(dataport&0x80); //如果最高位是1表示1602正忙原地踏步忙完后芯片会将高位拉低
也就是说想要在LCD1602屏幕的第一行第一列显示一个"A"字,就要向DDRAM的00H地址写入“A”字的代码就行了。但具体的写入是要按LCD模块的指令格式来进行的,后面我会说到的。那么一行可有40个地址呀?是的,在1602中我们就用前16个就行了。第二行也一样用前16个地址。对应如下:
DDRAM地址与显示位置的对应关系
num=num/10;
if(num==0)break;
}
for(gh=k;gh>=0;gh--)
{
displyonechar(x,y,(*(number+gh)+48));
x++;
}
}
//字型码
uchar code nian[]={0x08,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x02};// "年"
{
writecmd(0x38); //功能设定8位数据传输双行显示设置工作方式:0x28=4位总线字符两行显示,0x38=8位总线字符两行显示
writecmd(0x0c); //显示器开关
writecmd(0x01); //清屏
writecmd(0x06); //字符进入模式每进入一个字符光标向右移动一格原有字符不动
} //和DDRAM里的地址有上面的转换关系
void displynumber(unsigned char x,unsigned char y,unsigned long num) //显示一个整数
{
unsigned int number[8];
int k,gh;
for(k=0;;k++)
{
*(number+k)=(unsigned int)(num%10);//强制类型转换
/*
1602液晶模块内部的控制器共有11条控制指令,如下表
序号指令RS R/WD7 D6 D5 D4 D3 D2D1 D0
1清显示0000 00 000 1
2光标返回0000 00 001 *
3置输入模式0000 00 01I/D S
4显示开/关控制0000 00 1DC B
5光标或字符移位0000 01 S/C R/L* *
EN=0;
}
void writedata(unsigned char dataw) //写数据到LCD1602
{
waitfor(); //测忙
RS=1;RW=0; //选择数据寄存器写操作RS=0指令RS=1数据; RW=0写RW=1读
dataport=dataw; //将数据送到数据口
EN=1;
EN=0; //使能下降沿脉冲
{
while(*p) //当一个字符型数组读完时*P指的为零
{
displayonechar(x,y,*(p++));
x++;
}
}
void WriteCgram(unsigned char address,unsigned char *p) //写CGRAM的数据
{
unsigned char i=8;
writecmd(temp);
}
void DisplayOneChar(unsigned char x,unsigned char y,unsigned char dataw) //显示一个字符函数
{
location(x,y);
writedata(dataw);
}
void displaylistchar(unsigned char x,unsigned char y,unsigned char *p) //显示字符串
0x1c字符全部右移一格,但光标不动
0x10光标左移1格,且AC值减1
0x14光标右移1格,且AC值加1
*/
#include <intrins.h>
#define dataport P1
sbit RS=P2^ 6;
sbit RW=P2^5;
sbit EN=P2^4;
uchar code yue[]={0x0f,0x09,0x0f,0x09,0x0f,0x09,0x0b,0x11};// "月"
uchar code ri[]={0x1f,0x11,0x11,0x1f,0x11,0x11,0x11,0x1f};// "日"
//显示汉字
displyonecharacter(0,0,0x40,nian);
displyonecharacter(1,0,0x80,yue);
displyonecharacter(1,0,0xc0,ri);
0x01清屏,光标复位到地址00H位置
0x02光标归原点,DDRAM中内容不变,地址计数器AC=0;(此时地址为0x80)
0x0F开显示,显示光标,光标闪烁
0x0e开显示,显示光标,光标不闪烁
0x0c开显示,不显示光标
0x08只开显示
0x06地址加一,当写入数据的时候光标右移
设定显示屏或光标移动方向指令
}
void writecmd(unsigned char cmd) //写命令到LCD1602
{
waitfor(); //测忙
RS=0;RW=0; //选择指令寄存器写操作
dataport=cmd; //将数据送到数据口
EN=1;
EN=0; //使能下降沿脉冲
}
void init(void) //初始化函数
第一行: 00H 01H 02H 03H 04H 05H 06H 07H ..... 27H
第二行: 40H 41H 42H 43H 44H 45H 46H 47H ..... 67H
*/
1602LCD的RAM地址映射
液晶显示模块是一个慢显示器件,所以在执行每条指令之前一定要确认模块的忙标志为低电平,表示不忙,否则此指令失效。要显示字符时要先输入显示字符地址,也就是告诉模块在,哪里显示字符,图是1602的内部显示地址。
图五:LCD1602内部显示地址
例如第二行第一个字符的地址是40H,那么是否直接写入40H就可以将光标定位在第二行第一个字符的位置呢?这样不行,因为写入显示地址时要求最高位D7恒定为高电平1,所以实际写入的数据应该是01000000B(40H)+10000000B(80H)=11000000B(C0H)。
}
void location(unsigned char x,unsigned char y) //坐标函数
{
unsigned char temp;
temp=x&0x0f; //只要x数据的后四位
if(y)
{
temp=temp|0x40;
} //第一行为0第二行为1如果y=1则地址加0x40
temp|=0x80; //DDRAM地址的命令DB7为一
指令位D7 D6 D5 D4 D3 D2D1 D0
功能设置00 1DL NF* *
DL=1总线8位DL=0总线4位
N=0显单行N=1显双行
F=0 5X7点阵F=1 5X10点阵
lcd_1602指令汇总
0x28设置16*2显示,5*7点阵,4位数据接口
0x38设置16*2显示,5*7点阵,8位数据接口
9读忙标志或地址01 BF ----计数器地址(7位)---------
10写CGRAM或DDRAM 10 --------要写的数据内容(8位------
11读CGRAM或DDRAM 11 --------读出的数据内容(8位)-----
*/
// 51单片机对lcd1602一些基础程序
/*基本操作时序:
D3=1移字符D3=0移光标D2=1右移D2=0左移
6功能设置0000 1DL N F* *
DL=1总线8位DL=0总线4位
N=0显单行N=1显双行
F=0 5X7点阵F=1 5X10点阵
7置字符发生器地址00 01 -字符发生存贮器地址(6位)-
8置数据存贮器地址00 1--显示数据存贮器地址(7位)---
/*
HD44780内置了DDRAM、CGROM和CGRAM。
CGROM和CGRAM就是内置192个常用字符产生器,用户自定义的字符产生器RAM
DDRAM就是显示数据RAM,用来寄存待显示的字符代码。共80个字节,其地址和屏幕的对应关系如下表:
显示位置: 1 2 3 4 5 6 7 8 ..... 40
writecmd(address); //CGRAM里的地址初始值0x40每次加0x80
while(i--)
{
writedata(*p);
p++;
}
}
void DisplayOneChar(unsigned char x,unsigned char y,unsigned char address,unsigned char *p) //显示一个自定义字符
{
unsigned char i=8;
writecmd(address); //CGRAM里的地址初始值0x40每次加0x08
while(i--){Βιβλιοθήκη writedata(*p);
p++;
}
location(x,y); //设定要显示的位置
writedata((address&=0x3f)/0x08); //要从CGRAM中读出数据在1602上显示搞了半天发现CGRAM里的地址
写指令输入:RS=0,RW=0,E=下降沿脉冲,DB0~DB7=指令码输出:无
写数据输入:RS=1,RW=0,E=下降沿脉冲,DB0~DB7=数据输出:无
读状态输入:RS=0,RW=1,E=1输出:DB0~DB7=状态字
读数据输入:RS=1,RW=1,E=1输出:DB0~DB7=数据/
*/
/*
lcd_1602指令:
void waitfor() //检测忙信号函数
{
dataport=0xff;
RS=0;RW=1; //选择指令寄存器读操作RS=0指令RS=1数据; RW=0写RW=1读
EN=1; //使能操作
while(dataport&0x80); //如果最高位是1表示1602正忙原地踏步忙完后芯片会将高位拉低
也就是说想要在LCD1602屏幕的第一行第一列显示一个"A"字,就要向DDRAM的00H地址写入“A”字的代码就行了。但具体的写入是要按LCD模块的指令格式来进行的,后面我会说到的。那么一行可有40个地址呀?是的,在1602中我们就用前16个就行了。第二行也一样用前16个地址。对应如下:
DDRAM地址与显示位置的对应关系
num=num/10;
if(num==0)break;
}
for(gh=k;gh>=0;gh--)
{
displyonechar(x,y,(*(number+gh)+48));
x++;
}
}
//字型码
uchar code nian[]={0x08,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x02};// "年"
{
writecmd(0x38); //功能设定8位数据传输双行显示设置工作方式:0x28=4位总线字符两行显示,0x38=8位总线字符两行显示
writecmd(0x0c); //显示器开关
writecmd(0x01); //清屏
writecmd(0x06); //字符进入模式每进入一个字符光标向右移动一格原有字符不动
} //和DDRAM里的地址有上面的转换关系
void displynumber(unsigned char x,unsigned char y,unsigned long num) //显示一个整数
{
unsigned int number[8];
int k,gh;
for(k=0;;k++)
{
*(number+k)=(unsigned int)(num%10);//强制类型转换
/*
1602液晶模块内部的控制器共有11条控制指令,如下表
序号指令RS R/WD7 D6 D5 D4 D3 D2D1 D0
1清显示0000 00 000 1
2光标返回0000 00 001 *
3置输入模式0000 00 01I/D S
4显示开/关控制0000 00 1DC B
5光标或字符移位0000 01 S/C R/L* *
EN=0;
}
void writedata(unsigned char dataw) //写数据到LCD1602
{
waitfor(); //测忙
RS=1;RW=0; //选择数据寄存器写操作RS=0指令RS=1数据; RW=0写RW=1读
dataport=dataw; //将数据送到数据口
EN=1;
EN=0; //使能下降沿脉冲
{
while(*p) //当一个字符型数组读完时*P指的为零
{
displayonechar(x,y,*(p++));
x++;
}
}
void WriteCgram(unsigned char address,unsigned char *p) //写CGRAM的数据
{
unsigned char i=8;
writecmd(temp);
}
void DisplayOneChar(unsigned char x,unsigned char y,unsigned char dataw) //显示一个字符函数
{
location(x,y);
writedata(dataw);
}
void displaylistchar(unsigned char x,unsigned char y,unsigned char *p) //显示字符串