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,分别是HSPI和VSPI,引脚序号如下:
我的屏幕引脚分配方案如下,修改
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
至此移植完毕
更多推荐
已为社区贡献5条内容
所有评论(0)