编译平台介绍

  • 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

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

 "includePath": [
 ···
	"C:/Users/xx/.platformio/packages/framework-arduinoespressif32/libraries/SD/src",
···

验证程序

#include <Arduino.h>
#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");
    }
}

测试函数结果如下:

Card Mount Success
SD Card Type: SDSC

开始移植

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

修改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;
}

lv_fs的使用

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

#include <lvgl.h>
#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);
	}
	
		
	
}

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

Open OK
read:Hello Wo

至此移植完毕

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐