OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 10704|回复: 5

有关内部flash图片显示程序

[复制链接]

29

主题

71

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
207
金钱
207
注册时间
2013-7-25
在线时间
0 小时
发表于 2013-8-14 09:38:26 | 显示全部楼层 |阅读模式
    原子哥,我用的是战舰STM32,我想在内部flash里显示图片,移植的是Mini STM32中的那个程序。下面是移植的代码,都没有改动
//设置窗口
//sx,sy,ex,ey窗口坐标
//窗口大小ex-sx+1)*(ey-ex+1)
//注意,确保ex>=sx;ey>=sy!!!!
//9320/9325/9328/4531/1505/b505/8989等IC已经实际测试   
void LCD_Set_Window(u16 sx,u16 sy,u16 ex,u16 ey)   
{
u8 hsareg,heareg,vsareg,veareg;
u16 hsaval,heaval,vsaval,veaval;  
#if USE_HORIZONTAL  //使用横屏
//窗口值
hsaval=sy;
heaval=ey;
vsaval=319-ex;
veaval=319-sx;
#else //竖屏
//窗口值
hsaval=sx;
heaval=ex;
vsaval=sy;
veaval=ey;
#endif
  if(lcddev.id==0X8989)//8989 IC
{
hsareg=0X44;heareg=0X44;//水平方向窗口寄存器 (1289的由一个寄存器控制)
hsaval|=(heaval<<8); //得到寄存器值.
heaval=hsaval;
vsareg=0X45;veareg=0X46;//垂直方向窗口寄存器  
}else  //其他驱动IC
{
hsareg=0X50;heareg=0X51;//水平方向窗口寄存器
vsareg=0X52;veareg=0X53;//垂直方向窗口寄存器  
}  
//设置寄存器值
LCD_WriteReg(hsareg,hsaval);
LCD_WriteReg(heareg,heaval);
LCD_WriteReg(vsareg,vsaval);
LCD_WriteReg(veareg,veaval);
//从8位数据获得16位颜色
//mode:0,低位在前,高位在后.
//     1,高位在前,低位在后.
//str:数据
u16 image_getcolor(u8 mode,u8 *str)
{
u16 color;
if(mode)
{
color=((u16)*str++)<<8;
color|=*str;
}else
{
color=*str++;
color|=((u16)*str)<<8;
}
return color;
}
//在液晶上画图
//xsta,ysta,xend,yend:画图区域
//scan:见image2lcd V2.9的说明.
//*p:图像数据
void image_show(u16 xsta,u16 ysta,u16 xend,u16 yend,u8 scan,u8 *p)
{  
u32 i;
u32 len=0;
LCD_Set_Window(xsta,ysta,xend,yend);
if((scan&0x03)==0)//水平扫描
{
switch(scan>>6)//设置扫描方式
{
case 0:
LCD_Scan_Dir(L2R_U2D);//从左到右,从上到下
LCD_SetCursor(xsta,ysta);//设置光标位置 
break; 
case 1:
LCD_Scan_Dir(L2R_D2U);//从左到右,从下到上
LCD_SetCursor(xsta,yend);//设置光标位置 
break; 
case 2:
LCD_Scan_Dir(R2L_U2D);//从右到左,从上到下
LCD_SetCursor(xend,ysta);//设置光标位置 
break; 
case 3:
LCD_Scan_Dir(R2L_D2U);//从右到左,从下到上
LCD_SetCursor(xend,yend);//设置光标位置 
break; 
}
}else  //垂直扫描
{
switch(scan>>6)//设置扫描方式
{
case 0:
LCD_Scan_Dir(U2D_L2R);//从上到下,从左到右
LCD_SetCursor(xsta,ysta);//设置光标位置 
break; 
case 1:
LCD_Scan_Dir(D2U_L2R);//从下到上从,左到右
LCD_SetCursor(xsta,yend);//设置光标位置 
break; 
case 2:
LCD_Scan_Dir(U2D_R2L);//从上到下,从右到左 
LCD_SetCursor(xend,ysta);//设置光标位置 
break; 
case 3:
LCD_Scan_Dir(D2U_R2L);//从下到上,从右到左
LCD_SetCursor(xend,yend);//设置光标位置 
break; 
}
}
LCD_WriteRAM_Prepare();     //开始写入GRAM
len=(xend-xsta+1)*(yend-ysta+1); //写入的数据长度
for(i=0;i<len;i++)
{
LCD_WR_DATA(image_getcolor(scan&(1<<4),p));
p+=2;
}  
#if USE_HORIZONTAL  //使用横屏
LCD_Set_Window(0,0,319,239);
#else
LCD_Set_Window(0,0,239,319);
#endif          
}  

//在指定的位置显示一个图片
//此函数可以显示image2lcd软件生成的任意16位真彩色图片.
//限制:1,尺寸不能超过屏幕的区域.
//     2,生成数据时不能勾选:高位在前(MSB First)
//     3,必须包含图片信息头数据
//x,y:指定位置
//imgx:图片数据(必须包含图片信息头,"4096色/16位真彩色/18位真彩色/24位真彩色/32位真彩色”的图像数据头)
//注意:针对STM32,不能选择image2lcd的"高位在前(MSB First)"选项,否则imginfo的数据将不正确!!
void image_display(u16 x,u16 y,u8 * imgx)
{
HEADCOLOR *imginfo;
  u8 ifosize=sizeof(HEADCOLOR);//得到HEADCOLOR结构体的大小
imginfo=(HEADCOLOR*)imgx;
  image_show(x,y,x+imginfo->w-1,y+imginfo->h-1,imginfo->scan,imgx+ifosize);
}

图片是用image2lcd 软件生成的,格式就是你的那个pdf文档上的那个标准的图片。在主函数里就调用image_display(0,0,(u8*)gImage_1);这句,但是显示就是不对。图片根本显示不出来。这是为什么?弄了一晚上,还是没有结果。0X00,0X10,0XA6,0X00,0X6C,0X00,0X01,0X1B,这个那个图片的前8个字节。你看一下是哪里出问题了。

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-8-14 10:16:35 | 显示全部楼层
回复【楼主位】风:
---------------------------------
//9320/9325/9328/4531/1505/b505/8989等IC已经实际测试   
战舰板用的是9341....
最新版本,才支持9341液晶。
//设置窗口
//sx,sy,ex,ey窗口坐标
//窗口大小ex-sx+1)*(ey-ex+1)
//注意,确保ex>=sx;ey>=sy!!!!  
void LCD_Set_Window(u16 sx,u16 sy,u16 ex,u16 ey)    
{
u8 hsareg,heareg,vsareg,veareg;
u16 hsaval,heaval,vsaval,veaval;  
#if USE_HORIZONTAL  //使用横屏
//窗口值
hsaval=sy;
heaval=ey;
vsaval=319-ex;
veaval=319-sx;
#else //竖屏
//窗口值
hsaval=sx;
heaval=ex;
vsaval=sy;
veaval=ey;
#endif
if(DeviceCode==0X9341)
{
LCD_WR_REG(0x2A); 
LCD_WR_DATA(hsaval>>8); 
LCD_WR_DATA(hsaval&0XFF);  
LCD_WR_DATA(heaval>>8); 
LCD_WR_DATA(heaval&0XFF);  
LCD_WR_REG(0x2B); 
LCD_WR_DATA(vsaval>>8); 
LCD_WR_DATA(vsaval&0XFF);  
LCD_WR_DATA(veaval>>8); 
LCD_WR_DATA(veaval&0XFF);  
}else
{
  if(DeviceCode==0X8989)//8989 IC
{
hsareg=0X44;heareg=0X44;//水平方向窗口寄存器 (1289的由一个寄存器控制)
hsaval|=(heaval<<8); //得到寄存器值.
heaval=hsaval;
vsareg=0X45;veareg=0X46;//垂直方向窗口寄存器   
}else  //其他驱动IC
{
hsareg=0X50;heareg=0X51;//水平方向窗口寄存器
vsareg=0X52;veareg=0X53;//垂直方向窗口寄存器   
}   
//设置寄存器值
LCD_WriteReg(hsareg,hsaval);
LCD_WriteReg(heareg,heaval);
LCD_WriteReg(vsareg,vsaval);
LCD_WriteReg(veareg,veaval);
}



//从8位数据获得16位颜色
//mode:0,低位在前,高位在后.
//     1,高位在前,低位在后.
//str:数据
u16 image_getcolor(u8 mode,u8 *str)
{
u16 color;
if(mode)
{
color=((u16)*str++)<<8;
color|=*str;
}else
{
color=*str++;
color|=((u16)*str)<<8;
}
return color;
}
//在液晶上画图    
//xsta,ysta,xend,yend:画图区域
//scan:见image2lcd V2.9的说明.
//*p:图像数据
void image_show(u16 xsta,u16 ysta,u16 xend,u16 yend,u8 scan,u8 *p)
{  
u32 i;
u32 len=0;
if((scan&0x03)==0)//水平扫描
{
switch(scan>>6)//设置扫描方式
{
case 0:
LCD_Scan_Dir(L2R_U2D);//从左到右,从上到下
LCD_Set_Window(xsta,ysta,xend,yend);
LCD_SetCursor(xsta,ysta);//设置光标位置 
break; 
case 1:
LCD_Scan_Dir(L2R_D2U);//从左到右,从下到上
LCD_Set_Window(xsta,ysta,xend,yend);
LCD_SetCursor(xsta,yend);//设置光标位置 
break; 
case 2:
LCD_Scan_Dir(R2L_U2D);//从右到左,从上到下
LCD_Set_Window(xsta,ysta,xend,yend);
LCD_SetCursor(xend,ysta);//设置光标位置 
break; 
case 3:
LCD_Scan_Dir(R2L_D2U);//从右到左,从下到上
LCD_Set_Window(xsta,ysta,xend,yend);
LCD_SetCursor(xend,yend);//设置光标位置 
break; 
}
}else  //垂直扫描
{
switch(scan>>6)//设置扫描方式
{
case 0:
LCD_Scan_Dir(U2D_L2R);//从上到下,从左到右
LCD_Set_Window(xsta,ysta,xend,yend);
LCD_SetCursor(xsta,ysta);//设置光标位置 
break; 
case 1:
LCD_Scan_Dir(D2U_L2R);//从下到上从,左到右
LCD_Set_Window(xsta,ysta,xend,yend);
LCD_SetCursor(xsta,yend);//设置光标位置 
break; 
case 2:
LCD_Scan_Dir(U2D_R2L);//从上到下,从右到左 
LCD_Set_Window(xsta,ysta,xend,yend);
LCD_SetCursor(xend,ysta);//设置光标位置 
break; 
case 3:
LCD_Scan_Dir(D2U_R2L);//从下到上,从右到左
LCD_Set_Window(xsta,ysta,xend,yend);
LCD_SetCursor(xend,yend);//设置光标位置 
break; 
}
}
LCD_WriteRAM_Prepare();      //开始写入GRAM
len=(xend-xsta+1)*(yend-ysta+1); //写入的数据长度
for(i=0;i<len;i++)
{
LCD_WR_DATA(image_getcolor(scan&(1><<4),p));
p+=2;
}   
#if USE_HORIZONTAL  //使用横屏
LCD_Set_Window(0,0,319,239);
#else
LCD_Set_Window(0,0,239,319);
#endif             
}
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

29

主题

71

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
207
金钱
207
注册时间
2013-7-25
在线时间
0 小时
 楼主| 发表于 2013-8-14 15:06:58 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
可以正常显示了,可是我还有个疑问。我设定的最大宽度和高度是240,320.结果转换后的图像的数据头为:0X00,0X10,0XF0,0X00,0X9F,0X00,0X01,0X1B。这里的宽为:0XF000,对应的10进制为61400,高为:0X9F00,对应的10进制为40704.这两个数值明显大于我们所使用的屏的宽和高呀?难道是我对这个结构的数据解析错了?如果错了,这8个字节应该怎么对应?我设置的是低位在前。难道是宽为:0X00F0,高为:0X009F?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-8-14 15:24:52 | 显示全部楼层
回复【3楼】风:
---------------------------------
关于这个8个字节,请看IMG2LCD的介绍。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

29

主题

71

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
207
金钱
207
注册时间
2013-7-25
在线时间
0 小时
 楼主| 发表于 2013-8-14 16:17:09 | 显示全部楼层
回复【4楼】正点原子:
--------------------------------
我明白了,谢谢了。
回复 支持 反对

使用道具 举报

2

主题

5

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2015-4-24
在线时间
0 小时
发表于 2015-4-28 11:29:58 | 显示全部楼层
我也是移植的mini的代码~~但我的图片是可以显示的,只不过一连显示多个一排,请问原子哥,我这该怎么改啊~~

4.3寸LCD显示内部flash图片.rar

5.8 MB, 下载次数: 595

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-23 03:32

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表