从SD卡拷贝UI资源到QSPI Flash文件系统(仿串口终端显示拷贝过程)

上次发布了几个QSPI Fatfs的例程应用,如下:

让QSPI FLASH(W25Q64)支持Fatfs文件系统

QSPI FLASH与SD卡同时支持fatfs文件系统

QSPI FLASH fatfs BMP图片显示

这次我将STemWin给集成了进来,在这个例程中使用了多行文本控件,做了一个终端可显示从SD卡将BMP格式的图片资源拷贝到QSPI FLASH文件系统的过程,图片数据如下,事先已经将其拷贝到SD卡的根目录中:

做这个功能的主要目的是为了后面做一些基于小熊派的开源项目就可以彻底的不需要SD卡来做图片存放,而是直接利用板子上的QSPI FLASH作为图片存储,这个例程充当着一个数据迁移的角色。

1、软件功能简介

1.1、插入SD卡上电

当插入SD卡开机时,程序会自动的将SD卡根目录下的.bmp文件依次拷贝到QSPI FLASH的文件系统上,这里就会调用UI拷贝函数,拷贝的过程会通过LCD以多行文本的形式显示出来。

1.2、不插入SD卡上电

当检测到没有SD卡的时候,程序会调用文件索引函数,将QSPI FLASH文件系统下的BMP图片通过LCD依次显示出来。

先来直观的感受一下:

刷屏现象还是有的,资源有限,没办法。

2、主要函数功能实现

软件上根据野火电子开发板提供的文件系统例程进行了一下简单的改造,其中也加入了GUI的逻辑,以适配STemWin在LCD上的显示效果,主要为以下几个函数:

  • 索引盘符根目录下的.bmp格式的文件

FRESULT scan_files (char* src_path)
{
    FRESULT res;
    DIR dir;
    UINT i;
    static FILINFO fno;
    char UI_Path[100] = {0};
    res = f_opendir(&dir, src_path); /* Open the directory */

    if (res == FR_OK)
    {
        for (;;)
        {
            res = f_readdir(&dir, &fno);                   /* Read a directory item */

            if (res != FR_OK || fno.fname[0] == 0) break;  /* Break on error or end of dir */

            if (fno.fattrib & AM_DIR)                      /* It is a directory */
            {
                i = strlen(src_path);
                sprintf(&src_path[i], "/%s", fno.fname);
                res = scan_files(src_path);                   /* Enter the directory */

                if (res != FR_OK) break;

                src_path[i] = 0;
            }
            else
            {
                memset(UI_Path, 0, 100);
                sprintf(UI_Path, "%s/%s\n", src_path, fno.fname);
                if(strstr(fno.fname, ".bmp") != 0)
        {
          LCD_Clear(BLACK);
          Lcd_show_bmp(0,0,UI_Path);
          HAL_Delay(500);
        }
            }
        }
        f_closedir(&dir);
    }
    return res;
}
  • 复制文件

/**
  * @brief  复制文件
  * @param  src_path:源文件路径
  * @param  dst_path:文件将要复制到的目录(不含文件名)
  * @retval result:文件系统的返回值
  */
int copy_file(char *src_path, char *dst_path)
{
    FRESULT res = FR_OK;
    char *sub_dir = NULL;
  char buf[100] = {0};
    res = f_open(&SDFile, src_path, FA_READ);

    if(res != FR_OK)
    {
        printf("打开文件失败!\n");
        return -1 ;
    }

    //获取子文件路径
    sub_dir =  strrchr(src_path, '/');

    if(NULL == sub_dir)
    {
        printf("获取子文件路径失败!\n");
        return -2 ;
    }

    //拼接成新路径
    sprintf(newfn, "%s%s", dst_path, sub_dir);
    //printf("正在复制文件 %s ...", newfn);
  sprintf(buf,"copy 0:->%s success\n",newfn);
  MULTIEDIT_AddText(hItem,buf);
    res = f_open(&USERFile, newfn, FA_CREATE_ALWAYS | FA_WRITE | FA_READ);

    if(res != FR_OK)
    {
        printf("打开文件失败!\n");
        return -3 ;
    }

    //拷贝文件
    while(res == FR_OK)
    {
        res = f_read(&SDFile, &read_buf, COPY_UNIT, &real_read_num);

        if(res != FR_OK)
        {
            printf("读取文件失败!\n");
            return -4 ;
        }

        res = f_write(&USERFile, &read_buf, real_read_num, &real_write_num);

        if(res != FR_OK)
        {
            printf("写文件失败!\n");
            return -5 ;
        }

        if(real_read_num != COPY_UNIT)
            break;
    GUI_Delay(1);
    }
    f_close(&SDFile);
    f_close(&USERFile);
    return res;
}
  • 从SD卡根目录拷贝.bmp文件到QSPI FLASH fatfs文件系统的根目录

/*从SD卡拷贝UI文件到QSPI FLASH*/
FRESULT copy_ui_files (char* src_path)
{
    FRESULT res;
    DIR dir;
    UINT i;
    static FILINFO fno;
    char UI_Path[100] = {0};
    res = f_opendir(&dir, src_path); /* Open the directory */

    if (res == FR_OK)
    {
        for (;;)
        {
            res = f_readdir(&dir, &fno);                   /* Read a directory item */

            if (res != FR_OK || fno.fname[0] == 0) break;  /* Break on error or end of dir */

            if (fno.fattrib & AM_DIR)                      /* It is a directory */
            {
                i = strlen(src_path);
                sprintf(&src_path[i], "/%s", fno.fname);
                res = scan_files(src_path);                   /* Enter the directory */

                if (res != FR_OK) break;

                src_path[i] = 0;
            }
            else
            {
                memset(UI_Path, 0, 100);
                sprintf(UI_Path, "%s/%s", src_path, fno.fname);
                if(strstr(fno.fname, ".bmp") != 0)
                    copy_file(UI_Path, "1:");
            }
      GUI_Delay(1);
        }
        f_closedir(&dir);
    }
    return res;
}

利用STemWin的GUIBuilder生成基本界面及功能函数,并对其进行简单改造,在这里主要使用了框架窗口,然后在其之上绘制了多文本控件:

static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] =
{
    { FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, 240, 240, 0, 0x64, 0 },
    { MULTIEDIT_CreateIndirect, "Multiedit", ID_MULTIEDIT_0, 0, 0, 230, 220, 0, 0x0, 0 },
    // USER START (Optionally insert additional widgets)
    // USER END
};

在回调函数_cbDialog中添加如下代码:

/*********************************************************************
*
*       _cbDialog
*/
static void _cbDialog(WM_MESSAGE * pMsg)
{
    int     NCode;
    int     Id;
    uint8_t ret ;
    // USER END
    switch (pMsg->MsgId)
    {
        case WM_INIT_DIALOG:
            hItem = pMsg->hWin;
            FRAMEWIN_SetText(hItem, "BearPi Copy Ui Console");
            hItem = WM_GetDialogItem(pMsg->hWin, ID_MULTIEDIT_0);
            MULTIEDIT_SetBkColor(hItem, MULTIEDIT_CI_EDIT, GUI_BLACK);
            MULTIEDIT_SetTextColor(hItem, MULTIEDIT_CI_EDIT, GUI_MAKE_COLOR(0x0000FF00));
            printf("开始拷贝文件:\n");
            ret = copy_ui_files(src_dir);
            if(ret != FR_OK)
            {
                MULTIEDIT_AddText(hItem, "Open SD card Fail!\n");
                MULTIEDIT_AddText(hItem, "Copy 0:==>1: Fail\n");
                MULTIEDIT_AddText(hItem, "View QSPI_FLASH UI Resource:\n");
                GUI_Delay(1000);
                LCD_Clear(BLACK);
                HAL_Delay(500);
                scan_files(dst_dir);
                LCD_Clear(BLACK);
                HAL_Delay(500);
                MULTIEDIT_AddText(hItem, "View Success!\n");
            }
            else
            {
                MULTIEDIT_AddText(hItem, "Open SD card Success\n");
                MULTIEDIT_AddText(hItem, "Copy 0:==>1: Success\n");
                GUI_Delay(100);
            }
            break;
        default:
            WM_DefaultProc(pMsg);
            break;
    }
}

当在主程序调用以下函数时,则会自动运行以上程序。

WM_HWIN CreateFramewin(void)
{
    WM_HWIN hWin;

    hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
    return hWin;
}

获取完整demo:

码云仓库:https://gitee.com/morixinguan/bear-pi/tree/master/22.SD_Card_Copy_to_QSPI_Flash

获取方法:

git clone https://gitee.com/morixinguan/bear-pi.git

即可获取本次实验工程全部代码。

我的码云项目开源主页:https://gitee.com/morixinguan

往期精彩

QSPI FLASH fatfs BMP图片显示

RTOS支持STemWin(以RT-Thread为例)

QSPI FLASH与SD卡同时支持fatfs文件系统

让QSPI FLASH(W25Q64)支持Fatfs文件系统

整理了很久之前在码云/Github/CSDN上收藏的嵌入式产品级项目分享开源

觉得本次分享的文章对您有帮助,随手点[在看]并转发分享,也是对我的支持。

Engineer-Bruce_Yang CSDN认证博客专家 嵌入式硬件 单片机 arm开发
本科毕业于华南理工大学,现美国卡罗尔工商管理硕士研究生在读,曾就职于世界名企伟易达、联发科技等,多年嵌入式产品开发经验,在智能玩具、安防产品、平板电脑、手机开发有丰富的实战开发经验,现任深圳市云之手科技有限公司副总经理、研发总工程师。
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页