硬汉嵌入式论坛

 找回密码
 立即注册
查看: 4693|回复: 17
收起左侧

[其它] GUI_BMP_DrawEx()函数与SPI Flash搭配显示问题

[复制链接]

2

主题

4

回帖

20

积分

新手上路

积分
20
发表于 2017-3-7 18:56:22 | 显示全部楼层 |阅读模式
为什么我的_GetDataEx()函数只执行一次而显示数据失败?而emwin PC仿真的例程这个函数可以执行多次而执行正确?



#include "main.h"
#include "w25qxx.h"

#define SPIFLASHSECTOR    4096
typedef struct{
    u32 rBMPAddressofSFlash;//位流图在SpiFlash里的偏移地址
    u32 rSizeofBMP;//位流图片总大小
    u32 rRemainSizeBMP;//剩余数据大小
}TypeofBitBMP;
TypeofBitBMP BitBMPBinary;
u8 BmpBuf[SPIFLASHSECTOR];//读出一个sector

static int _GetDataEx(void * p, const U8 ** ppData, unsigned NumBytesReq, U32 Off){
   
    if(NumBytesReq > SPIFLASHSECTOR)
        NumBytesReq = SPIFLASHSECTOR;//请求数据过大
   
//    BitBMPBinary = *((TypeofBitBMP *)p);
    W25QXX_Read(BmpBuf,(Off + QSPI_DTA_ADDR + BorderBK_off),NumBytesReq);
    *ppData = BmpBuf;//返回读取位流图片数据
   
//    BitBMPBinary.rRemainSizeBMP -= NumBytesReq;
    if(BitBMPBinary.rRemainSizeBMP > NumBytesReq){
        BitBMPBinary.rRemainSizeBMP -= NumBytesReq;
        return NumBytesReq;    //返回Buffer数据大小
    }else{        
        return BitBMPBinary.rRemainSizeBMP;    //返回Buffer数据大小
    }
}

static void _cbBkWindow(WM_MESSAGE* pMsg){
   
    switch (pMsg->MsgId){
        case WM_PAINT:   
            GUI_SetBkColor(GUI_RED);
            GUI_SetColor(GUI_WHITE);
            BitBMPBinary.rBMPAddressofSFlash = QSPI_DTA_ADDR + BorderBK_off;
            BitBMPBinary.rSizeofBMP = BorderBK_len;
            BitBMPBinary.rRemainSizeBMP = BorderBK_len;
            GUI_BMP_DrawEx(_GetDataEx,(void *)&BitBMPBinary,0,0);
            break;
        default:
            WM_DefaultProc(pMsg);
            break;
    }
}

void MainTask(void){
    UpdateFontETC();
    GUI_Init();
   
    WM_SetCreateFlags(WM_CF_MEMDEV);    //ê1Äü′°¿úê1óÃÄú′æé豸
   
    PROGBAR_SetDefaultSkin(PROGBAR_SKIN_FLEX);
    FRAMEWIN_SetDefaultSkin(FRAMEWIN_SKIN_FLEX);
    PROGBAR_SetDefaultSkin(PROGBAR_SKIN_FLEX);
    BUTTON_SetDefaultSkin(BUTTON_SKIN_FLEX);
    CHECKBOX_SetDefaultSkin(CHECKBOX_SKIN_FLEX);
    DROPDOWN_SetDefaultSkin(DROPDOWN_SKIN_FLEX);
    SCROLLBAR_SetDefaultSkin(SCROLLBAR_SKIN_FLEX);
    SLIDER_SetDefaultSkin(SLIDER_SKIN_FLEX);
    HEADER_SetDefaultSkin(HEADER_SKIN_FLEX);
    RADIO_SetDefaultSkin(RADIO_SKIN_FLEX);            //ê1Äü¿Ø¼tƤ·ô
   
    WM_SetCallback(WM_HBKWIN, &_cbBkWindow);        //éèÖÃ×àÃæ′°¿úμÄ»Øμ÷oˉêy

//    User_CreateFrame(&_cbLanguage);
    while(1){
        GUI_Delay(100);        
    }
}

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106640
QQ
发表于 2017-3-8 00:41:50 | 显示全部楼层
流位图要使用这个函数:GUI_DrawStreamedBitmapEx
回复

使用道具 举报

2

主题

4

回帖

20

积分

新手上路

积分
20
 楼主| 发表于 2017-3-8 09:57:04 | 显示全部楼层
我用了GUI_DrawStreamedBitmapExAuto(_GetDataEx,(void *)&BitBMPBinary,0,0);
还加了GUI_BMP_GetXSizeEx(_GetDataEx, (void *)&BitBMPBinary);
            GUI_BMP_GetYSizeEx(_GetDataEx, (void *)&BitBMPBinary);
执行第一次,NumBytesReq = 0x1A,  off = 0x00
执行第二次,NumBytesReq = 0x1A,  off = 0x00
执行第三次,NumBytesReq = 0x10,  off = 0x00
执行第四次,NumBytesReq = 0x25800,  off = 0x10 这个整个文件的长度
我每次只读一个sector=4096B, 然后它就不来第5次了


#include "main.h"
#include "w25qxx.h"

#define SPIFLASHSECTOR    4096
typedef struct{//óû§¶¨òåò»¸ö½á11ì壬óÃóúspiflashóÃÕa¸ö×îoÃ
    u32 rBMPAddressofSFlash;    //í¼Æ¬ÔúSpiFlashÖDμľø¶ÔμØÖ·
    u32 rSizeofBMP;                //×üμÄλá÷í¼êy¾Y′óD¡
    u32 rRemainSizeBMP;            //ê£ÏÂμÄ×Ö½úêy
}TypeofBitBMP;
TypeofBitBMP BitBMPBinary;
u8 BmpBuf[SPIFLASHSECTOR];    //èç1ûêÇÎļtÏμí3ê±£¬é趨ò»DD¡£èç1ûêÇSpiFlash,é趨Îaò»¸öSector

static int _GetDataEx(void * p, const U8 ** ppData, unsigned NumBytesReq, U32 Off){
   
    if(NumBytesReq > SPIFLASHSECTOR)
        NumBytesReq = SPIFLASHSECTOR;    //èç1ûÇëÇóêy¾Yêyá¿′óóú4096
   
//    BitBMPBinary = *((TypeofBitBMP *)p);
    W25QXX_Read(BmpBuf,(Off + QSPI_DTA_ADDR + BorderBK_off),NumBytesReq);
    *ppData = BmpBuf;        //·μ»Ø¶á3öà′μÄêy¾Y
   
//    BitBMPBinary.rRemainSizeBMP -= NumBytesReq;
    if(BitBMPBinary.rRemainSizeBMP > NumBytesReq){
        BitBMPBinary.rRemainSizeBMP -= NumBytesReq;
        return NumBytesReq;        //Îò¶ááËò»¸ösectorμÄêy¾Y¸øÄ㣬BmpBufàïêy¾Y¶¼¿éóÃ
    }else{        
        return BitBMPBinary.rRemainSizeBMP;    //BmpBufàïÖ»óDê£ÏÂÕaμã¿éóÃ
    }
}

static void _cbBkWindow(WM_MESSAGE* pMsg){
   
    switch (pMsg->MsgId){
        case WM_PAINT:   
            GUI_SetBkColor(GUI_RED);
            GUI_SetColor(GUI_WHITE);
            BitBMPBinary.rBMPAddressofSFlash = QSPI_DTA_ADDR + BorderBK_off;
            BitBMPBinary.rSizeofBMP = BorderBK_len;
            BitBMPBinary.rRemainSizeBMP = BorderBK_len;
            //GUI_BMP_DrawEx(_GetDataEx,(void *)&BitBMPBinary,0,0);
            GUI_BMP_GetXSizeEx(_GetDataEx, (void *)&BitBMPBinary);
            GUI_BMP_GetYSizeEx(_GetDataEx, (void *)&BitBMPBinary);            
            GUI_DrawStreamedBitmapExAuto(_GetDataEx,(void *)&BitBMPBinary,0,0);
//            GUI_DrawStreamedBitmapAuto((void *)&BitBMPBinary,0,0);
            break;
        default:
            WM_DefaultProc(pMsg);
            break;
    }
}

void MainTask(void){
    UpdateFontETC();
    GUI_Init();
   
    WM_SetCreateFlags(WM_CF_MEMDEV);    //ê1Äü′°¿úê1óÃÄú′æé豸
   
    PROGBAR_SetDefaultSkin(PROGBAR_SKIN_FLEX);
    FRAMEWIN_SetDefaultSkin(FRAMEWIN_SKIN_FLEX);
    PROGBAR_SetDefaultSkin(PROGBAR_SKIN_FLEX);
    BUTTON_SetDefaultSkin(BUTTON_SKIN_FLEX);
    CHECKBOX_SetDefaultSkin(CHECKBOX_SKIN_FLEX);
    DROPDOWN_SetDefaultSkin(DROPDOWN_SKIN_FLEX);
    SCROLLBAR_SetDefaultSkin(SCROLLBAR_SKIN_FLEX);
    SLIDER_SetDefaultSkin(SLIDER_SKIN_FLEX);
    HEADER_SetDefaultSkin(HEADER_SKIN_FLEX);
    RADIO_SetDefaultSkin(RADIO_SKIN_FLEX);            //ê1Äü¿Ø¼tƤ·ô
   
    WM_SetCallback(WM_HBKWIN, &_cbBkWindow);        //éèÖÃ×àÃæ′°¿úμÄ»Øμ÷oˉêy

//    User_CreateFrame(&_cbLanguage);
    while(1){
        GUI_Delay(100);        
    }
}

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106640
QQ
发表于 2017-3-8 10:28:00 | 显示全部楼层
这样调试下,先把你用BmpCvt转换的流位图用B2C小软件转换成C文件添加到工程里面,用C文件来测试函数_GetDataEx,问题应该就是在这个函数里面。

另外注意GUI_BMP_GetXSizeEx和GUI_BMP_GetYSizeEx是用于BMP图片的,不适用于流位图。
回复

使用道具 举报

1

主题

9

回帖

12

积分

新手上路

积分
12
发表于 2018-9-24 16:00:52 | 显示全部楼层
deet1 发表于 2017-3-8 09:57
我用了GUI_DrawStreamedBitmapExAuto(_GetDataEx,(void *)&BitBMPBinary,0,0);
还加了GUI_BMP_GetXSizeEx ...

这个功能实现了吗?能分享一下代码不?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106640
QQ
发表于 2018-9-25 01:31:38 | 显示全部楼层
yuneizhilin 发表于 2018-9-24 16:00
这个功能实现了吗?能分享一下代码不?

这样吧,你把你实现的贴出来,我给你看下。
回复

使用道具 举报

1

主题

9

回帖

12

积分

新手上路

积分
12
发表于 2018-9-25 10:28:03 | 显示全部楼层
首先谢谢硬汉,我是将dta文件转换为bin文件(后期没转换成bin下载到spi flash,也试过,没成功显示),通过串口下载到板子的spi flash(已验证过,确实存入了spi flash了),然后用如下代码实现显示,但是未成功,只把相关代码筛选出来粘这了,要不太乱。代码实现,也是采用楼上代码的方式。
#define SPIFLASHSECTOR    4096
typedef struct{
  u32         *fphoto;  
        u32 rBMPAddressofSFlash;//位流图在SpiFlash里的偏移地址
    u32 rSizeofBMP;//位流图片总大小
    u32 rRemainSizeBMP;//剩余数据大小
}TypeofBitBMP;

TypeofBitBMP BitBMPBinary;

u8 BmpBuf[SPIFLASHSECTOR];//定义一个sector

uint32_t readnum=0;//由于调试过程中,Off一直为0,所以定义readnum代替Off

static int _GetData(void * p, const U8 ** ppData, unsigned NumBytesReq, U32 Off){
  
        //U32 phFile;
  //phFile =*(U32*)p;
         
        if(NumBytesReq >SPIFLASHSECTOR)
        NumBytesReq = SPIFLASHSECTOR;//请求数据过大
   
  //W25QXX_Read(BmpBuf,(Off + BitBMPBinary.rBMPAddressofSFlash),NumBytesReq);
        W25QXX_Read(BmpBuf,(readnum + BitBMPBinary.rBMPAddressofSFlash),NumBytesReq);
        readnum=readnum+NumBytesReq;
    *ppData = BmpBuf;//返回读取位流图片数据
  
    if(BitBMPBinary.rRemainSizeBMP > NumBytesReq){
        BitBMPBinary.rRemainSizeBMP -= NumBytesReq;
        return NumBytesReq;    //返回Buffer数据大小
    }else
        {        
    readnum=0;   
                return BitBMPBinary.rRemainSizeBMP;    //返回Buffer数据大小
    }
}



在WM_PAINT分支中有如下代码:
case WM_PAINT:
        GUI_DrawStreamedBitmapEx(_GetData, (BitBMPBinary.fphoto), 0, 0);
                       

在MainTask中包含如下代码(只筛选出了相关代码):               
void MainTask(void)
{

        u32 *P=NULL;

        BitBMPBinary.fphoto=P;
        BitBMPBinary.rBMPAddressofSFlash=0;
        BitBMPBinary.rRemainSizeBMP=153616;
        BitBMPBinary.rSizeofBMP=153616;
                       
                       
}
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106640
QQ
发表于 2018-9-26 08:52:26 | 显示全部楼层
yuneizhilin 发表于 2018-9-25 10:28
首先谢谢硬汉,我是将dta文件转换为bin文件(后期没转换成bin下载到spi flash,也试过,没成功显示),通过 ...

改成用函数GUI_DrawStreamedBitmapExAuto试下。
回复

使用道具 举报

1

主题

9

回帖

12

积分

新手上路

积分
12
发表于 2018-9-26 09:52:33 | 显示全部楼层
试了,也不行,我用GUI_GetStreamedBitmapInfoEx得到的信息不对,我的图片是320*240的,但是通过GUI_GetStreamedBitmapInfoEx函数得到的x大小和Y大小都很大
回复

使用道具 举报

29

主题

514

回帖

606

积分

金牌会员

积分
606
QQ
发表于 2018-9-26 09:58:50 | 显示全部楼层
yuneizhilin 发表于 2018-9-26 09:52
试了,也不行,我用GUI_GetStreamedBitmapInfoEx得到的信息不对,我的图片是320*240的,但是通过GUI_GetStr ...


我现在的芯片只有64KB内存,已经实现320*240的logo显示。需要清晰协调好资源才可以实现。
Releasing your creativity
回复

使用道具 举报

1

主题

9

回帖

12

积分

新手上路

积分
12
发表于 2018-9-26 10:35:09 | 显示全部楼层
廷润 发表于 2018-9-26 09:58
我现在的芯片只有64KB内存,已经实现320*240的logo显示。需要清晰协调好资源才可以实现。

你用文件系统了吗?我没用文件系统
回复

使用道具 举报

29

主题

514

回帖

606

积分

金牌会员

积分
606
QQ
发表于 2018-9-26 10:40:12 | 显示全部楼层
yuneizhilin 发表于 2018-9-26 10:35
你用文件系统了吗?我没用文件系统

跟文件系统没关系。我有发表一个贴子,先玩熟悉那个sample,多琢磨里面的细节。
Releasing your creativity
回复

使用道具 举报

1

主题

9

回帖

12

积分

新手上路

积分
12
发表于 2018-9-27 09:47:51 | 显示全部楼层
本帖最后由 yuneizhilin 于 2018-9-27 10:00 编辑
eric2013 发表于 2018-9-26 08:52
改成用函数GUI_DrawStreamedBitmapExAuto试下。

图像存在spi flash,我用GUI_BMP_DrawEx函数实现了显示功能,现在的问题是只是开机只显示一次,后期窗口切换回这个窗口时就不显示了,我用串口助手监视_GetData函数中的调用,发现只调用了一次,调用一次说明调用了WM_PAINT分支下的GUI_BMP_DrawEx函数。正常是调用很多次GetData函数,直到图片显示完成,有没有其他人遇到此问题。我用GUI_BMP_GetXSizeEx  GUI_BMP_GetYSizeEx 函数监视了一下图片的大小,发现第一次开机时,读到的图片大小为320*240,第二次需要显示图片时,读到的大小成为1*1了,是不是第一次显示完,还需要处理一下什么???
回复

使用道具 举报

1

主题

9

回帖

12

积分

新手上路

积分
12
发表于 2018-9-27 10:47:02 | 显示全部楼层
yuneizhilin 发表于 2018-9-27 09:47
图像存在spi flash,我用GUI_BMP_DrawEx函数实现了显示功能,现在的问题是只是开机只显示一次,后期窗口 ...

解决了,因为一个全局变量的原因
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106640
QQ
发表于 2018-9-28 00:10:41 | 显示全部楼层
yuneizhilin 发表于 2018-9-27 10:47
解决了,因为一个全局变量的原因

回复

使用道具 举报

5

主题

12

回帖

27

积分

新手上路

积分
27
发表于 2022-6-3 22:34:52 | 显示全部楼层
yuneizhilin 发表于 2018-9-27 10:47
解决了,因为一个全局变量的原因

兄弟是哪个全局变量的问题啊?我移植你上面的程序,也遇到你同样的问题,只显示一个点,能否帮指点下,新手谢过!
回复

使用道具 举报

0

主题

1

回帖

1

积分

新手上路

积分
1
发表于 2023-9-20 17:28:07 | 显示全部楼层
我试了也不行。dta文件存到flash 要转换成bin文件吗
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106640
QQ
发表于 2023-9-21 08:38:43 | 显示全部楼层
fazai 发表于 2023-9-20 17:28
我试了也不行。dta文件存到flash 要转换成bin文件吗

都可以,本质也是二进制bin文件
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-27 12:43 , Processed in 0.266574 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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