发布时间 : 星期二 文章lcd1602指令解读及基本程序更新完毕开始阅读85148ca8fab069dc502201c9
/*
HD44780内置了DDRAM、CGROM和CGRAM。
CGROM和CGRAM就是内置192个常用字符产生器,用户自定义的字符产生器RAM DDRAM就是显示数据RAM,用来寄存待显示的字符代码。共80个字节,其地址和屏幕的对应关系如下表:
显示位置: 1 2 3 4 5 6 7 8 ..... 40 第一行: 00H 01H 02H 03H 04H 05H 06H 07H ..... 27H 第二行: 40H 41H 42H 43H 44H 45H 46H 47H ..... 67H */
1602LCD的RAM地址映射
液晶显示模块是一个慢显示器件,所以在执行每条指令之前一定要确认模块的忙标志为低电平,表示不忙,否则此指令失效。要显示字符时要先输入显示字符地址,也就是告诉模块在,哪里显示字符,图是1602的内部显示地址。 也就是说想要在LCD1602屏幕的第一行第一列显示一个\字,就要向DDRAM的00H地址写入“A”字的代码就行了。但具体的写入是要按LCD模块的指令格式来进行的,后面我会说到的。那么一行可有40个地址呀?是的,在1602中我们就用前16个就行了。第二行也一样用前16个地址。对应如下: DDRAM地址与显示位置的对应关系
图五:LCD1602内部显示地址
例如第二行第一个字符的地址是40H,那么是否直接写入40H就可以将光标定位在第二行第一个字符的位置呢?这样不行,因为写入显示地址时要求最高位
D7恒定为高电平1,所以实际写入的数据应该是01000000B(40H)
+10000000B(80H)=11000000B(C0H)。
/*
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 * *
D3=1移字符 D3=0移光标 D2=1右移 D2=0左移
6 功能设置 0 0 0 0 1 DL N F * *
DL=1总线8位 DL=0总线4位 N=0显单行 N=1显双行 F=0 5X7点阵 F=1 5X10点阵
7 置字符发生器地址 0 0 0 1 -字符发生存贮器地址(6位)- 8 置数据存贮器地址 0 0 1 --显示数据存贮器地址(7位)--- 9 读忙标志或地址 0 1 BF ----计数器地址(7位)---------
10 写CGRAM或DDRAM 1 0 --------要写的数据内容(8位------ 11 读CGRAM或DDRAM 1 1 --------读出的数据内容(8位)----- */
// 51单片机对lcd1602一些基础程序
/* 基本操作时序:
写指令 输入: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指令:
指令位 D7 D6 D5 D4 D3 D2 D1 D0 功能设置 0 0 1 DL N F * * 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位数据接口 0x01 清屏,光标复位到地址00H位置
0x02 光标归原点,DDRAM中内容不变,地址计数器AC=0;(此时地址为0x80) 0x0F 开显示,显示光标,光标闪烁 0x0e 开显示,显示光标,光标不闪烁 0x0c 开显示,不显示光标 0x08 只开显示
0x06 地址加一,当写入数据的时候光标右移 设定显示屏或光标移动方向指令
0x18 字符全部左移一格,但光标不动 0x1c 字符全部右移一格,但光标不动 0x10 光标左移1格,且AC值减1 0x14 光标右移1格,且AC值加1 */
#include
void waitfor() //检测忙信号函数 {
dataport=0xff;
RS=0;RW=1; //选择指令寄存器 读操作 RS=0指令 RS=1数据; RW=0写 RW=1读
EN=1; //使能操作
while(dataport&0x80); //如果最高位是1 表示1602正忙 原地踏步 忙完后芯片会将高位拉低 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; //使能下降沿脉冲 }
void writecmd(unsigned char cmd) //写命令到LCD1602 {
waitfor(); //测忙
RS=0;RW=0; //选择指令寄存器 写操作 dataport=cmd; //将数据送到数据口 EN=1;
EN=0; //使能下降沿脉冲 }
void init(void) // 初始化函数 {
writecmd(0x38); //功能设定 8位数据传输 双行显示 设置工作方式:0x28=4位总线字符两行显示,0x38=8位总线字符两行显示 writecmd(0x0c); //显示器开关 writecmd(0x01); //清屏
writecmd(0x06); //字符进入模式 每进入一个字符光标向右移动一格 原有字符不动 }
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为一 writecmd(temp); }
void DisplayOneChar(unsigned char x,unsigned char y,unsigned char dataw) //显示一个字符函数 {
location(x,y);