c
#include "SD.h"
#include "ff.h"
#include "usart.h"
#include <string.h>
#include "lvgl.h"
#include <stdio.h>
// 全局 FatFs 对象和文件操作变量
FATFS fs; /* FatFs 文件系统对象 */
FIL fil; /* 文件对象 */
FRESULT fres; /* FatFs 函数返回结果 */
// 文件列表存储
char file_list[MAX_FILES][MAX_NAME_LEN];
int file_count = 0;
// 打印文件信息(内部使用)
static void print_file_info(FILINFO* fno);
void List_SD_Files(void)
{
DIR dir;
FILINFO fno;
UINT i = 0;
char path[] = "0:";
// 挂载文件系统
fres = f_mount(&fs, path, 1);
if (fres != FR_OK) {
HAL_UART_Transmit(&huart1, (uint8_t*)"failed", 6, 1000);
return;
}
HAL_UART_Transmit(&huart1, (uint8_t*)"successful", 10, 1000);
HAL_UART_Transmit(&huart1, (uint8_t*)"\r\n", 2, 1000);
// 打开根目录
fres = f_opendir(&dir, path);
if (fres != FR_OK) {
HAL_UART_Transmit(&huart1, (uint8_t*)"failedFF", 8, 1000);
return;
}
// 读取目录项
while (1) {
fres = f_readdir(&dir, &fno);
if (fres != FR_OK || fno.fname[0] == 0) break;
if (strcmp(fno.fname, ".") == 0 || strcmp(fno.fname, "..") == 0) continue;
print_file_info(&fno);
}
// 清理资源
f_closedir(&dir);
f_mount(NULL, path, 0);
}
static void print_file_info(FILINFO* fno)
{
// 打印文件名
HAL_UART_Transmit(&huart1, (uint8_t*)fno->fname, strlen(fno->fname), 1000);
strncpy(file_list[file_count], fno->fname, MAX_NAME_LEN - 1);
file_list[file_count][MAX_NAME_LEN - 1] = '\0';
file_count++;
HAL_UART_Transmit(&huart1, (uint8_t*)"\r\n", 2, 1000);
}
int SD_ReadFile(char* flname)
{
char path[] = "0:";
char line[100];
// 挂载文件系统
fres = f_mount(&fs, path, 1);
if (fres != FR_OK) return (int)fres;
// 打开文件
fres = f_open(&fil, flname, FA_READ);
if (fres != FR_OK) {
f_mount(NULL, path, 0);
return (int)fres;
}
// 逐行读取
while (f_gets(line, sizeof(line), &fil)) {
HAL_UART_Transmit(&huart1, (uint8_t*)line, strlen(line), 1000);
HAL_UART_Transmit(&huart1, (uint8_t*)"\r\n", 2, 1000);
}
// 关闭文件并卸载
f_close(&fil);
f_mount(NULL, path, 0);
return (int)fres;
}
int SD_WriteFile(char* newfname, char* data, UINT* bw)
{
char path[] = "0:";
UINT len = strlen(data);
// 挂载文件系统
fres = f_mount(&fs, path, 1);
if (fres != FR_OK) return (int)fres;
// 创建/打开文件
fres = f_open(&fil, newfname, FA_CREATE_ALWAYS | FA_WRITE | FA_READ);
if (fres != FR_OK) {
f_mount(NULL, path, 0);
return (int)fres;
}
// 写入数据
fres = f_write(&fil, data, len, bw);
if (fres == FR_OK) {
HAL_UART_Transmit(&huart1, (uint8_t*)"Write successful", 16, 1000);
HAL_UART_Transmit(&huart1, (uint8_t*)"\r\n", 2, 1000);
} else {
HAL_UART_Transmit(&huart1, (uint8_t*)"Write failed", 12, 1000);
HAL_UART_Transmit(&huart1, (uint8_t*)"\r\n", 2, 1000);
}
// 刷新并关闭
f_sync(&fil);
f_close(&fil);
f_mount(NULL, path, 0);
return (int)fres;
}
// 将SD卡文件列表更新到LVGL界面 - 仅显示文件名
void Update_SD_Files_To_LVGL(lv_obj_t* tab_page)
{
if (tab_page == NULL) {
//HAL_UART_Transmit(&huart1, (uint8_t*)"Tab page is NULL\r\n", 18, 1000);
return;
}
// 清除tab页面中的所有子对象
lv_obj_clean(tab_page);
// 为每个文件创建标签(只显示文件名)
for (int i = 1; i < file_count && i < MAX_FILES; i++) {
lv_obj_t* file_label = lv_label_create(tab_page);
lv_label_set_text(file_label, file_list[i]);
// 设置样式:文件名使用等宽字体
lv_obj_set_style_text_font(file_label, &lv_font_montserrat_14, 0);
lv_obj_set_style_text_color(file_label, lv_color_hex(0x000000), 0);
// 垂直排列,每行间隔25像素
lv_obj_align(file_label, LV_ALIGN_TOP_LEFT, 10, 10 + (i * 25));
}
// 如果没有文件,显示提示信息
if (file_count == 0) {
lv_obj_t* no_file_label = lv_label_create(tab_page);
lv_label_set_text(no_file_label, "No files found");
lv_obj_set_style_text_color(no_file_label, lv_color_hex(0x888888), 0);
lv_obj_align(no_file_label, LV_ALIGN_CENTER, 0, 0);
}
//HAL_UART_Transmit(&huart1, (uint8_t*)"Files displayed on LVGL (only filenames)\r\n", 42, 1000);
}
.h
c
#ifndef FATFS_UTIL_H
#define FATFS_UTIL_H
#include "ff.h"
#include "main.h"
#include "lvgl.h"
#define MAX_FILES 500 // 最大文件数
#define MAX_NAME_LEN 50 // 文件名最大长度(包含 '\0')
extern char file_list[MAX_FILES][MAX_NAME_LEN];
extern int file_count;
void List_SD_Files(void);
int SD_ReadFile(char* flname);
int SD_WriteFile(char* newfname, char* data, UINT* bw);
// LVGL界面更新函数
void Update_SD_Files_To_LVGL(lv_obj_t* tabview);
#endif /* FATFS_UTIL_H */
调用List_SD_Files()后调用Update_SD_Files_To_LVGL(guider_ui.screen_1_list_1);即可显示,传入要传入的图框