• LVGL V8.3 使用lvgl文件系统读取SD卡内容基于Arduino


    编译平台介绍

    • Windows10
    • Vscode+PlatformIO
    • 使用ESP-WROOM-32模块
    • 包含GC9A01驱动的240*240屏幕一块
    • 包含SPI驱动的Flash卡
    • lvgl版本8.3.2

    移植前的准备

    使用tft-eSPI解决屏幕驱动

    移植tft-eSPI 请参考其它文章,难度不大,这里不在介绍

    移植LVGL

    移植LVGL 请参考其它文章,这里不再介绍,运行lvgl自带demos或者examples配置比较麻烦,能写一个简单的控件并正确显示就可以了,不用非纠结显示自带的案例

    SD卡格式化为FAT32格式

    SD卡插入电脑格式化为fat32格式

    解决引脚冲突

    TFlash卡与屏幕驱动均使用SPI驱动,不修改默认引脚会造成引脚冲突,esp32用户一般使用两组spi,分别是HSPIVSPI,引脚序号如下:

    SPI引脚图

    我的屏幕引脚分配方案如下,修改User_Setup.h文件,屏幕驱动使用HSPI相关引脚:

    // For ESP32 Dev board (only tested with GC9A01 display)
    // The hardware SPI can be mapped to any pins
    
    #define TFT_MOSI 13 // In some display driver board, it might be written as "SDA" and so on.
    #define TFT_SCLK 14
    #define TFT_CS   15  // Chip select control pin
    #define TFT_DC   27  // Data Command control pin
    #define TFT_RST  33  // Reset pin (could connect to Arduino RESET pin)
    #define TFT_BL   22  // LED back-light
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    这样SD卡驱动自然是使用VSPI,默认就是不用做任何修改,系统默认使用SDMMC方式驱动,使用SPI驱动的头文件没有包含在头文件路径中,在c_cpp_properties.json文件中添加头文件路径,否则报错:

     "includePath": [
     ···
    	"C:/Users/xx/.platformio/packages/framework-arduinoespressif32/libraries/SD/src",
    ···
    
    • 1
    • 2
    • 3
    • 4

    验证程序

    #include 
    #include "SD.h"
    #include "FS.h"
    void test_SD(void)
    {
    	if(!SD.begin())
        {
            Serial.println("Card Mount Failed");
            return MY_FS_INIT_FAIL;
        }
        else
        {
            Serial.println("Card Mount Success");
        }
        uint8_t cardType = SD.cardType();
     
        if(cardType == CARD_NONE){
            Serial.println("No SD card attached");
            return MY_FS_INIT_FAIL;
        }
        Serial.print("SD Card Type: ");
        if(cardType == CARD_MMC){
            Serial.println("MMC");
        } else if(cardType == CARD_SD){
            Serial.println("SDSC");
        } else if(cardType == CARD_SDHC){
            Serial.println("SDHC");
        } else {
            Serial.println("UNKNOWN");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    测试函数结果如下:

    Card Mount Success
    SD Card Type: SDSC
    
    • 1
    • 2

    开始移植

    lv_config.h配置

    打开文件系统宏 使用FATFS,并分配盘符,我这里使用的是S,这里就移植好了

    /*API for FATFS (needs to be added separately). Uses f_open, f_read, etc*/
    #define LV_USE_FS_FATFS 1
    #if LV_USE_FS_FATFS
        #define LV_FS_FATFS_LETTER 'S'     /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
        #define LV_FS_FATFS_CACHE_SIZE 0    /*>0 to cache this number of bytes in lv_fs_read()*/
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    修改DIR为FF_DIR

    lv_fs_fatfs.c文件中的DIR替换为FF_DIR,应该有两处,否则会报错

    /**
     * Initialize a 'fs_read_dir_t' variable for directory reading
     * @param drv pointer to a driver where this function belongs
     * @param dir_p pointer to a 'fs_read_dir_t' variable
     * @param path path to a directory
     * @return LV_FS_RES_OK or any error from lv_fs_res_t enum
     */
    static void * fs_dir_open (lv_fs_drv_t * drv, const char *path)
    {
        FF_DIR * d = lv_mem_alloc(sizeof(FF_DIR));
        if(d == NULL) return NULL;
     
        FRESULT res = f_opendir(d, path);
        if(res != FR_OK) {
            lv_mem_free(d);
            d = NULL;
        }
        return d;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    lv_fs的使用

    使用前初始化,按标准来讲应将SD初始化部分放入lv_fs_fatfs.c文件的fs_init函数中,但是在C++环境下,经常报一些语言相关错误,属于c与C++混编。简单的解决方法是把SD卡初始化放在lv文件系统初始化之前就可以了,在SD卡中放入一个Hello World!!的测试文件测试函数如下:

    #include 
    #include "SD.h"
    #include "my_fs_drv.h"
    //自己包装的文件系统初始化函数
    int my_fs_drv_init(void)
    {
        if(!SD.begin())
        {
            Serial.println("Card Mount Failed");
            return MY_FS_INIT_FAIL;
        }
        else
        {
            Serial.println("Card Mount Success");
        }
        uint8_t cardType = SD.cardType();
     
        if(cardType == CARD_NONE){
            Serial.println("No SD card attached");
            return MY_FS_INIT_FAIL;
        }
        Serial.print("SD Card Type: ");
        if(cardType == CARD_MMC){
            Serial.println("MMC");
        } else if(cardType == CARD_SD){
            Serial.println("SDSC");
        } else if(cardType == CARD_SDHC){
            Serial.println("SDHC");
        } else {
            Serial.println("UNKNOWN");
        }
        lv_fs_fatfs_init();  //lvgl 文件系统初始化 放在SD卡初始化之后就行
    }
    //测试读取函数
    void lv_fs_test(void)
    {
    	lv_fs_file_t f;
    	lv_fs_res_t res;
    	res = lv_fs_open(&f, "S:folder/file.txt", LV_FS_MODE_RD);
    	if(res != LV_FS_RES_OK) 
    	{
    		Serial.println("Open fail");
    		
    	}
    	else
    	{
    		Serial.println("Open OK");
    		uint32_t read_num;
    		uint8_t buf[8];
    		res = lv_fs_read(&f, buf, 8, &read_num);
    		Serial.printf("read:%s",buf);
    		lv_fs_close(&f);
    	}
    	
    		
    	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    执行测试后程序打印如下:

    Open OK
    read:Hello Wo
    
    • 1
    • 2

    至此移植完毕

  • 相关阅读:
    已解决 TypeError: Fetch argument None has invalid type <class ‘NoneType‘>
    VR虚拟展厅的亮点是什么?有哪些应用?
    投资理财知识分享:100个金融知识专业术语
    工业智能中的组态
    Facebook又双叒崩了!网友:扎克伯格一周只用上三天班?
    华为 HUAWEI 数通路由交换设备 基线安全加固操作
    深入flink系列——集群启动流程
    【每日随笔】毕业论文答辩 ③ ( 线上答辩注意点 | 答辩 PPT 准备 | 答辩通过的因素 )
    SVProgressHUD和MBProgressHUD的优缺点与SVProgressHUD震动实现
    解决每次打开pycharm都特别慢的几个方法
  • 原文地址:https://blog.csdn.net/z961968549/article/details/127647638