AN1103 内部FLASH图片显示 本应用文档(AN1103)将向大家展示,如何将直接存放在STM32内部FLASH的图片数据(解码后的数据)显示到LCD上.以及介绍图片数据生成工具image2lcd V2.9的一些用法。本实验以ALIENTEK MiniSTM32开发板为实验对象。
本文档分为如下几部分:
1,图片显示原理。
2,Image2lcd简介。
3,软件实现。
一, 图片显示原理。
在LCD上显示图片无非就是画点。原理就这么简单。画点需要2个要素:1,坐标。2,颜。知道了这两个要素,画图就简单了,一副图片在LCD上显示出来,我们只需要在正确的位置写入正确的颜即可。就像你用铅笔在本子上画图一样,本子就是LCD,铅笔就是你的画点函数。
图片显示另外一个重要的特点就是他的数据量很大,比如画一幅320*240的图像,以16位计算,那么光颜的数据量就有:320*240*2=153600字节。这其中还不包括设置坐标的过程,如果加上坐标设置,
数据量就是颜数据量的5倍(每次坐标设置需要发送5次命令/数据)以上。所以尽量优化画点过程,才能使你的图片显示得流畅。
单纯的画点,显然无法做太多优化,因为坐标设置是必须的。幸好,我们ALIENTEK所使用的液晶都是支持开窗显示以及坐标自增显示的。这样,我们只需要设置一次窗口,然后设置一次坐标,就可以不停的往LCD写颜数据,而不需要再做地址设置了。这样可以使得速度比单纯的画点显示要快至少5倍以上。
开窗也有几个条件:1,窗大小。2,GRAM自增方向(就是扫描方向)。
开窗的概念:如图1所示:
图1
我们本来的液晶是分辨率是240*320.对图1的0X00~0XEF(x坐标),0X00~0X13F(y坐标)。图一中我们开辟了一个灰区域的窗口,它的范围为XSTA~XEND,YSTA~YEND。这样我们开辟窗口以后,再往LCD写数据,它就只会在这个窗口范围内地址按照设定的方向自增。比如从左到右,从上到下的扫描方式,规律为:从(XSTA,YSTA)开始,x坐标递增,每次遇到XEND地址则y坐标增1,同时x坐标重设为XSTA,直到y坐标递增到大于YEND,此时坐标又变为 (XSTA,YSTA)。
所以,只要我们预先知道图片数据的生成格式,以及图片尺寸,那么我们就可以采用开窗方式来画图,从而提高效率。
二, Image2lcd简介。
Image2Lcd 是一款非常好的图像工具软件,它能把各种来源的图片转换成特定的数据格式以用来匹配单片机系统所需要的显示数据格式。Image2Lcd支持的输入图像格式包括: BMP, WBMP, JPG, GIF, WMF, EMF, ICO, 等等。Image2Lcd的输出数据类型包括定制的二进制类型、C语言数组类型和标准的BMP格式、WBMP格式。Image2Lcd能可视调节输入图象的数据扫描方式、灰度(颜数)、图像数据排列方式、亮度、对比度、等等。对于包含了图像头数据保存的图像数据文件,Image2Lcd能重新打开作为输入图像。
因为image2lcd能生成带图像数据头的数据文件,使得我们处理起来方便很多,这里我们仅以16位真彩为例进行说明。
在该软件的帮助文件查到对“4096/16位真彩/18位真彩/24位真彩/32位真彩”图片,其生成的图像数据头的结构为:
typedef struct _HEADCOLOR
{
unsigned char scan;
unsigned char gray;
unsigned short w;
unsigned short h;
unsigned char is565;
unsigned char rgb;
}HEADCOLOR;
各个成员的功能描述如下:
scan: 扫描模式高速走应急车道怎么处罚
Bit7: 0:自左至右扫描,1:自右至左扫描。
Bit6: 0:自顶至底扫描,1:自底至顶扫描。
Bit5: 0:字节内象素数据从高位到低位排列,1:字节内象素数据从低位到高位排列。
Bit4: 0:WORD类型高低位字节顺序与PC相同,1:WORD类型高低位字节顺序与PC相反。  Bit3~2: 保留。
Bit1~0: [00]水平扫描,[01]垂直扫描,[10]数据水平,字节垂直,[11]数据垂直,字节水平。  gray: 灰度值
灰度值,1:单,2:四灰,4:十六灰,8:256,12:4096,16:16位彩,24:24位彩,32:32位彩。
w: 图像的宽度。
h: 图像的高度。
蒙迪欧致胜2.3
is565: 在4096模式下为0表示使用[16bits(WORD)]格式,此时图像数据中每个WORD表示一个象素;为1表示使用[12bits(连续字节流)]格式,此时连续排列的每12Bits代表一个象素。 在16位彩模式下为0表示R G B颜分量所占用的位数都为5Bits,为1表示R G B颜分量所占用的位数分别为5Bits,6Bits,5Bits。
在18位彩模式下为0表示"6Bits in Low Byte",为1表示"6Bits in High Byte"。
在24位彩和32位彩模式下is565无效。
rgb: 描述R G B颜分量的排列顺序,rgb中每2Bits表示一种颜分量,[00]表示空白,[01]表示Red,[10]表示Green,[11]表示Blue。
在HEADCOLOR中,scan,w,h这三个参数对我们的图片显示尤为有用。直到了w和h,就可以直到开窗的大小。而scan的最高两位,则代表了图片数据生成时的扫描方向,也就
是我们开窗后地址自增的方向。直到了这几个参数,我们就可以很方便的解析各种大小,各种扫描方式的图片数据了。
下面我们以图2为例,按从左到右,从上到下的扫描方式,生成16位真彩(RGB:565)格式的图像数据。
图2
该图片的尺寸为200*168。我们用image2lcd V2.9打开此图片,设置如图3所示:
图3
北京奔驰价格图3中,我们设置如上图。我们要生成的的图像数据为16位真彩,所以在2处选择16位真彩,然后扫描方式为水平扫描,在3处选中包含头像数据头选项(注意:不能选择“高位在前(MSB First)”这个选项!!!)。在5处选中16位彩选项卡,然后在颜位数(4处)选择RGB565(因为我们的液晶刚好也是RGB565格式)。然后点击保存,命名为image1,可以得到图像数组如下:
东风标致408油耗const unsigned char gImage_image1[67208] = { 0X00,0X10,0XC8,0X00,0XA8,0X00,0X01,0X1B, 0X6B,0X6E,0XD1,0X9F,0XF5,0XB7,0XD3,0XAF,0XF3,0XAF,0X0F,0X8F,0XCE,0X86,0XF3,0XAF,
……
0X73,0XB7,0XF6,0XCF,0XF9,0XD7,0X98,0XCF,0X71,0XAE,0XD6,0XDF,0XFA,0XE7,0XF8,0XCF,
0XF6,0XC7,0X10,0X9F,0X53,0XB7,0XD5,0XC7,0XF6,0XCF,0X74,0XBF,0XD1,0XA6,0XF7,0XD7, };
其中红数字为图像头数据,一共是8个字节,刚好是HEADCOLOR的大小。紧随其后的就是按设定的方向顺序存放的图像数据(颜数据)。这样我们只需要在软件上对这个数组(gImage_image1)的数据进行解析,就可以还原图像了。
三, 软件实现。
在第二节的介绍中,我们得到了一个数组(gImage_image1),而从第一节的介绍,我们需要一个开窗函数,以及一个扫描方向设置函数,这里提供这两个函数的代码如下:
//设置LCD的自动扫描方向
//0~7:代表8个方向(具体定义见lcd.h)
//9320/9325/9328/4531/1505/b505/8989等IC已经实际测试
void LCD_Scan_Dir(u8 dir)
{
u16 regval=0;
u8 dirreg=0;
#if USE_HORIZONTAL//使用横屏
switch(dir)//方向转换
{
case 0:dir=6;break;
ex1pro
case 1:dir=7;break;
case 2:dir=4;break;
case 3:dir=5;break;
case 4:dir=1;break;
case 5:dir=0;break;
case 6:dir=3;break;
case 7:dir=2;break;
}
#endif
福特车怎么样if(DeviceCode==0x8989)//8989 IC
{
dirreg=0X11;
regval=0X6040;//65K
}else//其他驱动IC
{
dirreg=0X03;
regval=1<<12;
}
switch(dir)
{
case L2R_U2D://从左到右,从上到下
regval|=(1<<5)|(1<<4)|(0<<3);
break;
case L2R_D2U://从左到右,从下到上
regval|=(0<<5)|(1<<4)|(0<<3);
break;
case R2L_U2D://从右到左,从上到下
regval|=(1<<5)|(0<<4)|(0<<3);
break;