请教!!!怎样从外部FLASH读取大图片数据,并显示在LCD上!

2019-07-21 08:48发布

现在已经做好了从上位机串口把大图片数据通过串口传到下位机,并写入到外部FLASH里,并且可以正常读取!(写的小图片,只是做个试验,只是证明方案可行)
但现在问题来了!!!
如果我要显示在LCD上,在程序里开不了这么大的BUFF,最多18K左右的缓冲区,但240*320的16位真彩图片有130多K,求解决办法!!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
12条回答
正点原子
1楼-- · 2019-07-22 03:23
回复【7楼】0o小松o0:
---------------------------------
效率确实不高,一次多读一些数据吧,比如一次读4K字节,然后一次性写完4K,再读下一次,这样可以快很多。
0o小松o0
2楼-- · 2019-07-22 04:06

回复【8楼】正点原子:
---------------------------------
修改后的程序,速度快了好多,我试了一下一次读15000个点,10000个点,8000个点,5000个点,4000个点的速率,高于5000就没意义了 差不多的了,而且高于8000后,刷图的时候会感觉明显的停顿(求解释,有点不懂!),还有另外看看,有没有更有效率的方法,现在刷一个240*320的图不超过1秒。。估计就0.7秒左右!
u16 image_getcolor(u8 mode,u8 *str)
{
    u16 color;

    if(mode)
    {
        color=((u16)*str++)<<8;
        color|=*str;
    }
    else
    {
        /*color=Buffer[0];
        color|=Buffer_color[0]<<8;*/
        color=*str++;
        color|=((u16)*str)<<8;
    } 

    return color;
}
//在液晶上画图
//xsta,ysta,xend,yend:画图区域
//scan:见image2lcd V2.9的说明.
//*p:图像数据
int number = 0;
void image_show(u16 xsta,u16 ysta,u16 xend,u16 yend,u8 scan,u8 *p)
{  
    u32 i;
    u32 u;
    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); //写入的数据长度 
    if((len+len)%5000 == 0) 
    { 
        number = (len+len)/5000; 
        for(u=0;u<number;u++) 
        { 
            W25X_Read_Bytes(8+(u*5000),Buffer, 5000); 
            for(i=0;i<5000;i++) 
            { 
                if(i%2 == 0) 
                { 
                    LCD_WR_DATA(image_getcolor(scan&(1><<4),Buffer)); 
                    Buffer[0] = Buffer[i+2]; 
                    Buffer[1] = Buffer[i+3]; 
                } 
            } 
        } 
    } 
    else 
    { 
        number = ((len+len)/5000) + 1; 
        for(u=0;u<number-1;u++) 
        { 
            W25X_Read_Bytes(8+(u*5000),Buffer, 5000); 
            for(i=0;i<5000;i++) 
        { 
            if(i%2 == 0) 
            { 
                LCD_WR_DATA(image_getcolor(scan&(1><<4),Buffer)); 
                Buffer[0] = Buffer[i+2]; 
                Buffer[1] = Buffer[i+3]; 
            } 
        } 
    } 
    W25X_Read_Bytes(8+(5000*(number-1)),Buffer, (len+len)-(5000*(number-1))); 
    for(i=0;i<(len+len)-(5000*(number-1));i++) 
    { 
        if(i%2 == 0) 
        { 
            LCD_WR_DATA(image_getcolor(scan&(1<<4),Buffer)); 
            Buffer[0] = Buffer[i+2]; 
            Buffer[1] = Buffer[i+3]; 
        } 
    }

    /*for(i=0;i<(len+len);i++) 
        { 
        if((i%2) == 0) 
        { 
            W25X_Read_Bytes(8+i,Buffer, 1); 
            W25X_Read_Bytes(9+i,Buffer_color, 1); 
            LCD_WR_DATA(image_getcolor(scan&(1<<4),Buffer)); 
        } 
        }*/  
#if USE_HORIZONTAL  //使用横屏
LCD_Set_Window(0,0,319,239);
#else
LCD_Set_Window(0,0,239,319);
#endif             
}  

//在指定的位置显示一个图片
//此函数可以显示image2lcd软件生成的任意16位真彩 {MOD}图片.
//限制:1,尺寸不能超过屏幕的区域.
//     2,生成数据时不能勾选:高位在前(MSB First)
//     3,必须包含图片信息头数据
//x,y:指定位置
//imgx:图片数据(必须包含图片信息头,"4096 {MOD}/16位真彩 {MOD}/18位真彩 {MOD}/24位真彩 {MOD}/32位真彩 {MOD}”的图像数据头)
//注意:针对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);
}

majay123
3楼-- · 2019-07-22 09:51
回复【9楼】0o小松o0:
---------------------------------
主函数要怎么写啊
天天mdk
4楼-- · 2019-07-22 11:29
你好楼主,可以给我发一份您的程序吗?
一抹时光
5楼-- · 2019-07-22 16:02
 精彩回答 2  元偷偷看……
head1987
6楼-- · 2019-07-22 21:14
请问一下*Buffer是怎么定义的

一周热门 更多>