ARM32开发-fat_fs文件系统

news2024/11/18 23:45:09

FAT_FS 文件系统

FAT (File Allocation Table) 文件系统是一种广泛使用的基于磁盘的文件系统,尤其适用于小型嵌入式系统和存储卡。FAT_FS 就是一个专门针对 FAT 文件系统的开源实现。

FAT_FS 的主要特点

  1. 轻量级和高度可移植:
    • FAT_FS 是一个非常轻量级的文件系统实现,占用资源少,非常适合嵌入式系统。
    • 它被设计为可以在不同的硬件平台和操作系统上运行,具有很强的可移植性。
  1. 支持 FAT12/16/32 文件系统:
    • FAT_FS 支持 FAT12、FAT16 和 FAT32 三种常见的 FAT 文件系统格式。
    • 可以方便地在这些文件系统格式之间进行切换和转换。
  1. 功能丰富:
    • FAT_FS 提供了完整的文件系统功能,包括文件和目录的创建、读写、删除等。
    • 还支持长文件名、时间戳、属性标志等特性。

FAT_FS 与 SDIO 的关系

SDIO (Secure Digital Input Output) 是一种通信协议,用于与 SD/SDHC/SDXC 存储卡进行数据交互。而 FAT_FS 则是一种文件系统,用于管理存储在这些存储卡上的文件数据。

通常情况下,嵌入式系统会将 FAT_FS 文件系统与 SDIO 驱动程序集成在一起,形成一个完整的存储子系统。SDIO 驱动程序负责与物理存储卡进行底层的数据交互,而 FAT_FS 则提供上层的文件系统功能,使得应用程序可以方便地访问存储卡上的文件数据。

这种组合使得嵌入式系统能够轻松地支持基于 SD 卡的文件存储和交换功能,广泛应用于各种电子设备中。

fat_fs仓库地址:FatFs - Generic FAT Filesystem Module

1. SDIO

  1. 从GD32固件库的SDIO文件夹中复制sdcard.hsdcard.c文件到自己的工程中
  2. 核对2366行代码中,引脚是否与自己的开发板相符合,若不相符,则修改引脚

  1. 在sdcard.c文件中,声明变量
sd_card_info_struct sd_cardinfo;  
  1. 在sd_init函数中,增加获取sd卡信息的函数,方便后续调用
if(SD_OK == status) {
    status = sd_card_information_get(&sd_cardinfo);
}

2. fat_fs

将下载的文件导入到工程中

替换diskio.c文件内容

📎diskio.c

2.1. 测试代码

#include "ff.h"
FATFS fs;
u8 buff_tx[512]="SD卡扇区读写测试,fat文件系统读写测试www.icheima.com\r\n";
u8 buff_rx[512];
void test_fatfs_write(const TCHAR *file_name,u8 *buff,u32 len);
void test_fatfs_read(const TCHAR *file_name,u8 *buff,u32 len);

void test_fatfs(){
  uint8_t stat=f_mount(&fs,"0:",1);//SD卡挂载
  printf("stat=%d\r\n",stat);
  if(stat==0) printf("磁盘挂载成功\r\n");
  test_fatfs_write("0:/icheima.txt",buff_tx,strlen((char *)buff_tx));
  test_fatfs_read("0:/icheima.txt",buff_rx,strlen((char *)buff_tx));
  printf("rx:%s\r\n",buff_rx);
  //while(1){}
}
void test_fatfs_write(const TCHAR *file_name,u8 *buff,u32 len)
{
	/*1.打开文件*/
	FIL fp;
	FRESULT res;
	UINT bw;
	res=f_open(&fp,file_name,FA_WRITE|FA_CREATE_ALWAYS);//写+创建
	if(res!=FR_OK)
	{
		printf("文件打开或创建失败:ERR%d\r\n",res);
		return ;
	}
	printf("文件创建或打开成功\r\n");
	res=f_write(&fp,buff,len,&bw);
	if(res==FR_OK)
	{
		printf("数据写入成功 %d Byte\r\n",bw);
	}
	else printf("写入失败ERR:%d\r\n",res);
	f_close(&fp);//关闭文件
}

void test_fatfs_read(const TCHAR *file_name,u8 *buff,u32 len)
{
		/*1.打开文件*/
	FIL fp;
	FRESULT res;
	UINT br;
	res=f_open(&fp,file_name,FA_READ);//读
	if(res!=FR_OK)
	{
		printf("文件打开失败:ERR%d\r\n",res);
		return ;
	}
	printf("文件打开成功\r\n");
	res=f_read(&fp,buff,len,&br);
	if(res!=FR_OK)
	{
		printf("读取数据失败ERR:%d \r\n",res);
	}
	else
	{
		printf("读取数据成功 %d byte\r\n",br);
	}
	f_close(&fp);//关闭文件
}

2.2. error:13

uint8_t stat=f_mount(&fs,"0:",1);//SD卡挂载

调用以上代码,如果出现13错误码,则使用SDFormatter对SD卡进行格式化即可

3. lvgl中启用文件系统

3.1. 模拟器中

在lv_conf配置文件中,启用文件系统

#define LV_USE_FS_WIN32 1
#if LV_USE_FS_WIN32
    #define LV_FS_WIN32_LETTER  'D'    /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
    #define LV_FS_WIN32_PATH "D:/videos/code/lv_port_pc_eclipse-release-v8.3/images"         /*Set the working directory. File/directory paths will be appended to it.*/
    #define LV_FS_WIN32_CACHE_SIZE 0    /*>0 to cache this number of bytes in lv_fs_read()*/
#endif

其中“D:/videos/code/lv_port_pc_eclipse-release-v8.3/images”表示windows上面的路径,我们将它映射为lvgl中的文件盘符为D

例如,我们想访问“D:/videos/code/lv_port_pc_eclipse-release-v8.3/images”下的aaa.txt文件,在代码中我们其实只需要写"D:/aaa.txt"即可

在代码中调用

void demo14(){
  printf("demo14\n");

      lv_fs_dir_t d;
    if (lv_fs_dir_open(&d, "/") == LV_FS_RES_OK)
    {
        char b[50];
        memset(b, 0, 50);
        while (lv_fs_dir_read(&d, b) == LV_FS_RES_OK)
        {
            printf("%s\n", b);
        }
        lv_fs_dir_close(&d);
  } 
  lv_fs_file_t  file_p;
  lv_fs_res_t res = lv_fs_open(&file_p,"D:/mergeBinFile.c",LV_FS_MODE_RD);
  // 1. 获取屏幕
  lv_obj_t* screen = lv_scr_act();
  // 2. 创建要显示的内容
  lv_obj_t* img = lv_img_create(screen);
  // 3. 对内容进行设置  参数1:img, 参数2:要显示的图片
  lv_img_set_src(img,"D:/a0001.bin");

  int i = 1;
  int time_count=0;
  char buffer[10];

  while(1){
    if(time_count%5 == 0){
      
      if(i > 392){
        i=0;
      }
      sprintf(buffer, "D:/a%04d.bin", i);
      printf("%s \n",buffer);
      lv_img_set_src(img,buffer);
      i++;
    }
    time_count++;
    lv_timer_handler();
    usleep(5 * 1000);
  } 
}

运行上述代码,我们可以看到视频画面

3.2. 单片机中

在lv_conf文件中配置

在代码中,初始化SD卡

uint8_t stat=f_mount(&fs,"D",1);//SD卡挂载
printf("stat=%d\r\n",stat);

初始化lvgl中的文件系统

lv_fs_fatfs_init();

参考示例代码

     // 1. 获取屏幕
    lv_obj_t* screen = lv_scr_act();
    // 2. 创建要显示的内容
    lv_obj_t* img = lv_img_create(screen);
    // 3. 对内容进行设置  参数1:img, 参数2:要显示的图片
    lv_img_set_src(img,"D:/images/a0001.bin");

注: 上面代码需要在sd根目录新建images文件夹,并在其中放入a0001.bin文件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1838665.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【JS重点15】原型对象概述

目录 一:构造函数缺陷 二:原型 1 原型是是什么 2 原型对象的作用 3 原型对象this指向问题 4 利用原型对象添加方法 给JS内置构造函数Array添加最大值方法 给JS内置构造函数Array添加求和方法 三:Constructor属性 四:如何…

应用无感,透明加密!麒麟信安商用密码改造方案助力密改合规

数字信息化时代,在产业政策与市场驱动的共同作用下,密码产品和应用服务需求日趋旺盛,合规、正确、有效地使用密码,是数据安全防护体系中的有效手段。但当前,各行各业信息系统中国产密码算法应用不合规、未使用、使用不…

使用Python实现自动化查询IP威胁情报

解决的问题 一名网络安全从业人员在做日常网络安全运营分析时,就从防火墙、IDP、WAF等安全设备的日志分析计算,基本都会面对成千上万条日志,好一点的可能会有态势感知之类安全产品提供辅助分析,如果没有的就只能单条进行分析&…

彻底卸载Ubuntu双系统

操作系统 文章目录 操作系统前言一、把开机启动项设为默认Windows启动二、删除Ubuntu系统分区三、删除开机启动引导项 前言 我们卸载Ubuntu双系统,可能出于以下原因: 1、Ubuntu系统内核损坏无法正常进入 2、Ubuntu系统分配空间不足,直接扩区…

如何规范信息技术课堂纪律

在信息技术课堂上,为了营造一个良好的学习环境,确保学生能够专注于学习任务,我们需要采取一系列措施来规范课堂纪律。以下是一些具体而详细的建议: 一、明确课堂规则 上课座位固定:学生的座位应固定,未经…

分享一个dnslog在线平台

DNSLog Platform 页面只有两个按钮,点击Get Subdomain可以随机生成一个dnslog 点击Refresh Record,刷新这个dnslog的记录。可以查看到这条dnslog的IP地址和创建时间。

vue elementui table给表格中满足条件的每一条记录添加计时器

需求: 在前端给表格中给满足条件的每一条记录增加一个计时器,用于计算工作时长。 1.数据库中存储的有每条记录的作业开始时间,将当前时间和作业开始时间计算一个差值,作为作业时长的初始值; 2.把满足条件的每条记录绑…

为什么很多Java程序员会下意识觉得Java的就是最好的?

在开始前刚好我有一些资料,是我根据网友给的问题精心整理了一份「Java的资料从专业入门到高级教程」, 点个关注在评论区回复“888”之后私信回复“888”,全部无偿共享给大家!!!做为一个真正热爱编程&#…

信捷PLC与上位机通讯-以太网通讯dll

应用场景 最近做项目,电气部分PLC选用了国产的信捷PLC,需要考虑上位机与信捷PLC通讯的问题,直接读写寄存器或线圈。 解决方案 信捷官网找资料,介绍的各种通讯方法,感觉都不是很好理解,而且也没办法直接拿…

二刷算法训练营Day27 (Day26 休息) | 回溯算法(3/6)

目录 详细布置: 1. 39. 组合总和 2. 40. 组合总和 II 3. 131. 分割回文串 详细布置: 1. 39. 组合总和 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同…

【数据结构】线性表之《无头单链表》超详细实现

单链表 一.链表的概念及结构二.顺序表与链表的区别与联系三.单链表的实现1.创建单链表2.初始化单链表3.购买节点4.打印单链表5.插入操作1.头插2.尾插3.给定位置之前插入 6.删除操作1.头删2.尾删3.删除给定位置的结点 7.查找数据8.修改数据9.求单链表长度10.清空单链表11.销毁单…

python代码

# 请在______处使用一行代码或表达式替换# 注意:请不要修改其他已给出代码s input("请输入一个字符串:") print("{:*^30}".format(s))# 请在______处使用一行代码或表达式替换 # # 注意:请不要修改其他已给出代码a, b 0, 1 while …

程序员们,能告诉我你们为什么选择arch linux吗?

在开始前刚好我有一些资料,是我根据网友给的问题精心整理了一份「linux的资料从专业入门到高级教程」, 点个关注在评论区回复“888”之后私信回复“888”,全部无偿共享给大家!!! Arch Linux 受到程序员青…

Qt|海康摄像头多个页面展示问题

为大家分享一个使用海康摄像头的小功能,希望对大家有用~ 使用场景: 在程序中多个不同功能页面需要展示摄像头的实时预览画面,该如何高效的展示呢? 对于海康摄像头的实时预览接口调用流程,如下所示: 按照流…

GD32F4xx 移植agile_modbus软件包与电能表通信

目录 1. agile_modbus1.1 简介1.2 下载2. agile_modbus使用2.1 源码目录2.2 移植3. 通信调试3.1 代码3.3 通信测试1. agile_modbus 1.1 简介 agile_modbus是一个轻量级的Modbus协议栈,主要特点: 支持RTU和TCP协议,采用纯C语言开发,不涉及任何硬件接口,可直接在任何形式的…

Java学习 (一) 环境安装及入门程序

一、安装java环境 1、获取软件包 https://www.oracle.com/java/technologies/downloads/ .exe 文件一路装过去就行,最好别装c盘 ,我这里演示的时候是云主机只有C盘 2、配置环境变量 我的电脑--右键属性--高级系统设置--环境变量 在环境变量中添加如下配…

有路网整体布局

有路网地址 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><style>.…

昇思25天学习打卡营第1天 | 快速入门

内容介绍&#xff1a;通过MindSpore的API来快速实现一个简单的深度学习模型。 具体内容&#xff1a; 1. 导包 import mindspore from mindspore import nn from mindspore.dataset import vision, transforms from mindspore.dataset import MnistDataset 2. 处理数据 fro…

Gobject tutorial 六

Instantiatable classed types Initialization and destruction 类型的实例化是通过函数g_tpye_create_instance()实现的。这个函数首先会查找与类型相关的GTypeInfo结构体&#xff0c;之后&#xff0c;查询结构体中的instance_size和 instance policy即 n_preallocs(在 2.10版…

Nuxt3页面开发实战探索

title: Nuxt3页面开发实战探索 date: 2024/6/19 updated: 2024/6/19 author: cmdragon excerpt: 摘要&#xff1a;这篇文章是关于Nuxt3页面开发实战探索的。它介绍了Nuxt3的基础入门&#xff0c;安装与配置&#xff0c;项目结构&#xff0c;内置组件与功能&#xff0c;以及页…