lcd1602的基础操作和配置可查看12章讲解!
一.原理
基础回顾:
1. lcd1602一个字符的显示是宽5个像素高8个像素,一共40个像素。其中每行的5个像素是由1个字节的低5位控制,高3位不起作用(此处需要注意,后面创建图形需要考虑到)。所以一个字符的显示要8个字节;
2. 由lcd1602的使用手册可知,其用户字模存储区CGRAM是6位地址(即64个地址),每个地址可存入1个字节的数据。因此,CGRAM最多可存入8个完整字符。
3. 动态的制作也是利用视觉残留现象,短时间播放多帧画面。
二.图形模型的创建
由上面动图可见,我使用左边8个字符位置显示图形(即一幅图片宽20,高16),一帧图片8个字符显示的顺序为从左至右,从上至下(即先显示第一行4个字符,再显示第2行4个字符)。
取字模的软件为PCtoLCD2002。
1.设置显示区大小
图片的宽度需保留完整字节的大小,把高3位空出来,因此宽度设为32。
2.字模输出设置
3.依据所设计的图形,一帧帧绘制出来。
设计的图形:
逐帧绘制:
第一帧:
第二帧:
第n帧:
4.注意事项
实际需要显示的顺序:
代码生成字模的顺序:
由于此字模软件无法按需要显示的顺序输出,因此在代码中需要适当更改。
例如字模软件的输出为:
{0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F, //实际显示的第1个字符
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F, //第5个字符
0x1F,0x1F,0x1F,0x1F,0x1C,0x1F,0x1F,0x1F, //第2个字符
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F, //第6个字符
0x1F,0x1F,0x1F,0x1F,0x07,0x1F,0x1F,0x1F, //第3个字符
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F, //第7个字符
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F, //第4个字符
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F}, //第8个字符
三.代码与注释
#include "stc15.h"
#include "intrins.h"
#define LCD1602_DB P0
sbit LCD1602_RS=P2^0; //RS,数据/命令选择端(H/L)
sbit LCD1602_RW=P2^1; //R/W,读/写选择端(H/L)
sbit LCD1602_E=P1^2; // E,使能信号
//共有17帧
unsigned char code picture[17][64]=
{
//第一帧
{0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F, //第1个字符
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F, //第5个字符
0x1F,0x1F,0x1F,0x1F,0x1C,0x1F,0x1F,0x1F, //第2个字符
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F, //第6个字符
0x1F,0x1F,0x1F,0x1F,0x07,0x1F,0x1F,0x1F, //第3个字符
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F, //第7个字符
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F, //第4个字符
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F}, //第8个字符
//第二帧
{0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x19,0x1C,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x13,0x07,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
{0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1F,0x13,0x19,0x1C,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1F,0x19,0x13,0x07,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
{0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x07,0x13,0x19,0x1C,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1C,0x19,0x13,0x07,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
{0x1F,0x1C,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x07,0x13,0x19,0x1C,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1C,0x19,0x13,0x07,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x07,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
{0x1F,0x1C,0x19,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x07,0x13,0x19,0x1C,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1C,0x19,0x13,0x07,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x07,0x13,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
{0x1F,0x1C,0x19,0x13,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x07,0x13,0x19,0x1C,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1C,0x19,0x13,0x07,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x07,0x13,0x19,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
{0x1F,0x1C,0x19,0x13,0x17,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x07,0x13,0x19,0x1C,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1C,0x19,0x13,0x07,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x07,0x13,0x19,0x1D,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
{0x1F,0x1C,0x19,0x13,0x17,0x17,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x07,0x13,0x19,0x1C,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1C,0x19,0x13,0x07,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x07,0x13,0x19,0x1D,0x1D,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
{0x1F,0x1C,0x19,0x13,0x17,0x17,0x13,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x07,0x13,0x19,0x1C,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1C,0x19,0x13,0x07,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x07,0x13,0x19,0x1D,0x1D,0x19,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
{0x1F,0x1C,0x19,0x13,0x17,0x17,0x13,0x19,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x07,0x13,0x19,0x1C,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1C,0x19,0x13,0x07,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x07,0x13,0x19,0x1D,0x1D,0x19,0x13,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
{0x1F,0x1C,0x19,0x13,0x17,0x17,0x13,0x19,
0x1C,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x07,0x13,0x19,0x1C,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1C,0x19,0x13,0x07,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x07,0x13,0x19,0x1D,0x1D,0x19,0x13,
0x07,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
{0x1F,0x1C,0x19,0x13,0x17,0x17,0x13,0x19,
0x1C,0x1E,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x07,0x13,0x19,0x1C,0x1F,0x1F,0x1F,
0x1F,0x0F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1C,0x19,0x13,0x07,0x1F,0x1F,0x1F,
0x1F,0x1E,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x07,0x13,0x19,0x1D,0x1D,0x19,0x13,
0x07,0x0F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
{0x1F,0x1C,0x19,0x13,0x17,0x17,0x13,0x19,
0x1C,0x1E,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x07,0x13,0x19,0x1C,0x1F,0x1F,0x1F,
0x1F,0x0F,0x07,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1C,0x19,0x13,0x07,0x1F,0x1F,0x1F,
0x1F,0x1E,0x1C,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x07,0x13,0x19,0x1D,0x1D,0x19,0x13,
0x07,0x0F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
{0x1F,0x1C,0x19,0x13,0x17,0x17,0x13,0x19,
0x1C,0x1E,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x07,0x13,0x19,0x1C,0x1F,0x1F,0x1F,
0x1F,0x0F,0x07,0x13,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1C,0x19,0x13,0x07,0x1F,0x1F,0x1F,
0x1F,0x1E,0x1C,0x19,0x1F,0x1F,0x1F,0x1F,
0x1F,0x07,0x13,0x19,0x1D,0x1D,0x19,0x13,
0x07,0x0F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
{0x1F,0x1C,0x19,0x13,0x17,0x17,0x13,0x19,
0x1C,0x1E,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x07,0x13,0x19,0x1C,0x1F,0x1F,0x1F,
0x1F,0x0F,0x07,0x13,0x19,0x1F,0x1F,0x1F,
0x1F,0x1C,0x19,0x13,0x07,0x1F,0x1F,0x1F,
0x1F,0x1E,0x1C,0x19,0x13,0x1F,0x1F,0x1F,
0x1F,0x07,0x13,0x19,0x1D,0x1D,0x19,0x13,
0x07,0x0F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
{0x1F,0x1C,0x19,0x13,0x17,0x17,0x13,0x19,
0x1C,0x1E,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x07,0x13,0x19,0x1C,0x1F,0x1F,0x1F,
0x1F,0x0F,0x07,0x13,0x19,0x1C,0x1E,0x1F,
0x1F,0x1C,0x19,0x13,0x07,0x1F,0x1F,0x1F,
0x1F,0x1E,0x1C,0x19,0x13,0x07,0x0F,0x1F,
0x1F,0x07,0x13,0x19,0x1D,0x1D,0x19,0x13,
0x07,0x0F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
};
//读状态
void read_state(void)
{
unsigned char sta; //状态读取存储变量
LCD1602_DB=0xff;
LCD1602_RS=0;
LCD1602_RW=1;
LCD1602_E=1;
do
{
LCD1602_E=1;
sta=LCD1602_DB;//把状态字读取到sta变量中,可通过最高位判断液晶是否处于忙态,1时为忙
LCD1602_E=0;//释放总线,防止影响其他模块
}while(sta&0x80);
}
//写命令
void write_cmd(unsigned char cmd)
{
read_state();
LCD1602_RS=0; //RS=0->指令
LCD1602_RW=0; //R/W=0->写
LCD1602_DB=cmd;
LCD1602_E=1;
LCD1602_E=0;
}
//写数据
void write_data(unsigned char date)
{
read_state();
LCD1602_RS=1; //RS=1->数据
LCD1602_RW=0;
LCD1602_DB=date;
LCD1602_E=1;
LCD1602_E=0;
}
//LCD初始化
void lcd_init()
{
LCD1602_E=0; //使能关(操作前关使能使用时打开)
write_cmd(0x3c); //设置16*2显示,5*8点阵,8位数据口
write_cmd(0x0c); //设置开显示,不显示光标
write_cmd(0x06); //设置写一个字符后地址指针自动加1
write_cmd(0x01); //显示清0,数据指针清0
}
//把字符写入用户字模RAM
void Write_CGRAM(void)
{
static unsigned char i=0; //帧数
unsigned char j,k;//j为字符的序号,k为每个字符的行序号
for(j=0;j<8;j++)
{
write_cmd(0x40+j*8); //此处的0x40为写入CGRAM命令的固定位,
//不理解可以看12节,j*8为对应地址
//此处的写入数据即将输出的字模转为所需的显示顺序依次存入CGRAM
if(j<4) //先将第一行4个字符存入
{
for(k=0;k<8;k++)
{
write_data(picture[i][2*8*j+k]);
}
}
else //再存入第二行4个字符
{
for(k=0;k<8;k++)
{
write_data(picture[i][2*8*(j-4)+8+k]);
}
}
}
i++;
if(i==17)
i=0;
}
//LCD显示一帧画面
void display()
{
unsigned char m;
//按顺序把CGRAM中的字符存入DDRAM中进行显示
write_cmd(0x80);
for(m=0;m<4;m++)
{
write_data(m); //从CGRAM中进行显示直接输出对应字符序号即可
}
write_cmd(0xc0);
for(m=0;m<4;m++)
{
write_data(m+4);
}
}
//100ms延时
void Delay100ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 5;
j = 52;
k = 195;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void main()
{
lcd_init();
while(1)
{
Write_CGRAM();
display();
Delay100ms(); //适当延时,10帧/s
}
}
评论(0)
您还未登录,请登录后发表或查看评论