LCD12864液晶的使用之字库型液晶(二)
出处:cheng8760 发布于:2011-09-16 17:01:12
一、显示图片
显示图片要用到它的扩充指令,里面有个绘图开关G!当我们要显示图片时,要打开绘图开关G。
还是上次的图片:取模、生成数据,显示效果如下图所示:
现在来说明一下显示图片的函数:
/**********************************************
函数:显示图片
说明:要先设定垂直地址再设定水平地址(连续写入两
个字节的资料,来完成垂直于水平的坐标地址)
0x80---0x87:显示上半部分
0x88---0x8F:显示下半部分
只需设定显示的个位置,指针会自动加1
**********************************************/
void display_BMP(uchar *address)
{
uchar i,j;
for(i=0;i<32;i++)
{
write_LCD_command(0x80+i);//先送垂直地址
write_LCD_command(0x80); //再送水平地址 ----显示图片的上半部分
for(j=0;j<16;j++)
{
write_LCD_data(*address);
address++;
}
}
for(i=0;i<32;i++)
{
write_LCD_command(0x80+i);//先送垂直地址
write_LCD_command(0x88);//显示图片的下半部分
for(j=0;j<16;j++)
{
write_LCD_data(*address);
address++;//指针地址指向下个位置
}
}
}
还有一点要注意的就是显示图片和显示ASCII码、汉字的初始化函数不同,显示图片用的是扩展指令:
void init_BMP()
{
write_LCD_command(0x36);//CL=1--8位。扩充指令(RE=1),绘图打开(G=1)
delay(100);//适当延时
write_LCD_command(0x36);
delay(37);
write_LCD_command(0x3E); //8位(CL=1),扩充指令(RE=1),绘图打开(G=1)
delay(100);
write_LCD_command(0x01);//清屏指令
delay(100);
}
这一点一定要注意,上面的延时函数可以不要,大家结合情况适当添加!显示图片的就这么多了,其他部分的代码和显示汉字的一样!这里就不多写了!
一、显示动画
上面也说了,不断的刷新一张张静态图片就可以显示动画了,上面的两个写函数:写数据函数和写命令函数,EN从1变0延时应尽量短些,上面的delay(100);延时过长,大家可以做适当的修改!
还有一点要说明的是,清屏只是简单的清屏二不是清除显示的内容,我这么说吧,当你要显示很多张图片时,清屏显示后,只要RAM中的图片数据不变,显示还是清屏前显示的图片,要显示下一帧图片时就会变乱,解决办法是,将0送入显示的RAM区(0写入到显示图片函数中),也就是将一张空白图片送入到RAM区显示。这样就OK了,其它的步骤我在上面已经做了介绍!大家可以试一下!
二、显示正弦曲线
那么怎么才能显示一个正弦波形呢?我们可以这样想,如果我们可以控制128*64液晶上的每个像素的显示与关闭,那么就可以根据曲线的规律来显示一个正弦波形了,那么!怎么才能控制一个像素点呢?这就要用到打点函数了;这个的原理和Proteus中的一样!
其GDRAM对应的显示关系如上图所示;首先我们要在液晶上打号坐标,根据xy坐标来确定像素点的具体位置,首先要确定列,也就是Y的大小,然后确定它的行,就是哪个字节的哪个位,也就X的大小了,点亮一个像素点就送1,否则送0,这个大家都应该知道吧,其他不画点的地方就送0就行了,可是按照我们的这个思路写下去,似乎不对,点亮的点数不止我们要求的一个!是什么原因呢?原来是对不点亮的点做填0操作了,造成对原来数据的破坏,解决的办法是先读出一个字节的数据,然后点亮我们要求的那个像素点,再将其余不做操作的像素点的数据送入到原理的位置,经过这样一整合,就可以只改变我们要求的那个像素点,而其余的点不发生变化!在根据正弦函数sin(x)的对应关系就可以显示正弦曲线了!思路就是这个样子的。下面就是那个画点函数的代码:
/********************************************************
画点函数说明:增加LCD读函数,目的是使不打点的地方数据保持
不变:方法是先读出不打点位置的数据,打完点后将读到的数据写
入原来的位置,只有这样才会显示打点的曲线。
坐标原点:屏的左上角(0,0);到右下端(127,63);
*********************************************************/
void Draw_dots(uchar x,uchar y,uchar color)
{
uchar ROW,xlabel,xlabel_bit;
uchar Read_H,Read_L; //读LCD中的数据
write_LCD_command(0x34);//扩充指令
write_LCD_command(0x36);//打开绘图指令
xlabel=x》4;//取16*16首地址
xlabel_bit=x & 0x0F;//计算该点在16位数据的第几位
if(y<32)//如果是上半屏,上下半屏y都是0--31
{
ROW=y;
}
else//显示的是下半屏
{
ROW=y-32;
xlabel+=8; //规定显示在下半屏
}
write_LCD_command(ROW+0x80); //送入垂直地址
write_LCD_command(xlabel+0x80);//再送入水平地址
ReadByte();//读取当前GDRAM数据前腰进行空读,接下来就可以读出数据了
Read_H=ReadByte(); //读高8位
Read_L=ReadByte(); //读低8位
write_LCD_command(ROW+0x80); //送入垂直地址
write_LCD_command(xlabel+0x80);//再送入水平地址
if(xlabel_bit<8)
{
switch(color)
{
case 0:Read_H &= (~(0x01《(7-xlabel_bit)));//若变白
break;
case 1:Read_H |= (0x01《(7-xlabel_bit));//若涂黑
break;
case 2:Read_H ^= (0x01《(7-xlabel_bit));//若反转
break;
default:break;
}
write_LCD_data(Read_H);//将数据写入GDRAM
write_LCD_data(Read_L);//先写高位,再写低位(地址指针顺序)
}
else
{
switch(color)//color设置
{
case 0: Read_L &= (~(0x01《(15-xlabel_bit)));//若变白
break;
case 1: Read_L |= (0x01《(15-xlabel_bit));//若涂黑
break;
case 2: Read_L ^= (0x01《(15-xlabel_bit));//若反转
break;
default:break;
}
write_LCD_data(Read_H);
write_LCD_data(Read_L);//写入数据
}
write_LCD_command(0x30);//回到普通模式
}
其实写这个函数,主要还是思路,思路对了些代码就简单了!里面的正弦函数显示,可以包含math.h这个头文件中的正弦函数即可!
下面是我写个一个显示正弦函数的效果,通过按键可以调节幅度和频率!
下面这个显示温度曲线:
版权与免责声明
凡本网注明“出处:维库电子市场网”的所有作品,版权均属于维库电子市场网,转载请必须注明维库电子市场网,https://www.dzsc.com,违反者本网将追究相关法律责任。
本网转载并注明自其它出处的作品,目的在于传递更多信息,并不代表本网赞同其观点或证实其内容的真实性,不承担此类作品侵权行为的直接责任及连带责任。其他媒体、网站或个人从本网转载时,必须保留本网注明的作品出处,并自负版权等法律责任。
如涉及作品内容、版权等问题,请在作品发表之日起一周内与本网联系,否则视为放弃相关权利。
- 分布式光伏发电的工作原理、特点及优势2024/4/23 17:53:20
- 一文详解发光二极管2024/4/22 17:31:28
- 一文详解发光二极管LED2024/4/10 17:57:25
- 安装FFC柔性连接线2024/4/2 17:02:42
- LED驱动电路的工作原理2024/3/21 16:41:50