zoukankan      html  css  js  c++  java
  • 基于STM32F429,Cubemx的SDHC卡的基本Fatfs文件移植

    本博文要求各位初步了解Fatfs文件系统

    友情提示Fatfs官网:http://elm-chan.org/fsw/ff/00index_e.html

    1.开发软件

      keil5,Cube5.21

    2.实验目的

      往SDHC卡上移植Fatfs文件

    SDHC:

      SDHC是"Secure Digital High Capacity“的缩写,即“高容量SD存储卡”。2006年5月SD协会发布了SD 2.0的系统规范,并在其中规定SDHC是符合该规范、SDHC存储卡容量为“4GB-32GB”。

      SDHC最大的特点就是高容量(4GB-32GB)。另外,SD协会规定SDHC必须采用FAT32 文件系统,这是因为之前在SD卡中使用的FAT16文件系统所支持的最大容量为2GB,并不能满足SDHC的要求。
      作为SD卡的继任者,SDHC主要特征在于文件格式从以前的FAT12、FAT16提升到了FAT32,而且最高支持32GB。同时传输速度被重新定义为Class2、Class4、Class6等级别,高速的SD卡可以支持高分辨视频录制的实时存储。
      SDHC卡的外形尺寸与SD卡一样,著作权保护机能等也和以前相同,但是由于文件系统被变更,以前只支持FAT12/16格式的SD设备存在不兼容现象,而支持FAT32(SDHC)的机器,仍可以读取现存的FAT12/16格式的SD卡。
    FATFS:
      FatFs是一个通用的文件系统(FAT/exFAT)模块,用于在小型嵌入式系统中实现FAT文件系统。 FatFs 组件的编写遵循ANSI C(C89),完全分离于磁盘 I/O 层,因此不依赖于硬件平台。它可以嵌入到便宜的微控制器中,如 8051, PIC, AVR, ARM, Z80, RX等等,不需要做任何修改。
    因为FatFs模块完全与磁盘I/O层分开,因此需要下面的函数来实现底层物理磁盘的读写与获取当前时间。底层磁盘I/O模块并不是FatFs的一部分,并且必须由用户提供。

    3.Cube配置

    (1)在Cube上点开芯片功能的SDIO,因为我用的是4GB的SDHC卡,所以用SD 4 bits,用默认配置即可与SD卡通信

     红框内为SDIO协议引用的引脚

    PC8 ------> SDIO_D0
    PC9 ------> SDIO_D1
    PC10 ------> SDIO_D2
    PC11 ------> SDIO_D3
    PC12 ------> SDIO_CK
    PD2 ------> SDIO_CMD

     

     

    (2)再点开下面的FATFS,即向工程里添加fatfs移植文件,然后再勾选SD Card,底层的disiko接口默认添加SD卡读写程序

    (3)配置时钟完成后,就可生成工程

    4.工程讲解

    (1)下面的文件是Cube帮你移植的Fatfs文件,但不用修改里面的程序

    (2)下面的两个C文件,一个是SD的diskio接口层,Cube已往里面调用了HAL库的SD卡读写函数,可以不修改,另一个是上层的fatfs文件功能函数,可根据需要添加函数,也可以不用修改。

     (3)虽然Cube使用了MX_SDIO_SD_Init();进行了SD卡的初始化,但还要用下面的初始化进行初始化才能使用SD卡,它们在stm32f4xx_hal_sd.c里

      HAL_SD_Init(&hsd);
      HAL_SD_InitCard(&hsd);

     5.程序测试

     (1)使用FATFS_GetAttachedDriversNbr()判断SD卡是否挂载上驱动

    i=FATFS_GetAttachedDriversNbr();
    printf("已挂载的驱动:%d",i);

     

    (2)调用ff.c的文件功能函数,如果返回FR_OK(0)则成功

    /* USER CODE BEGIN Application */
     void SD_Fatfs_Test(void)
     {
        printf("文件挂载
    " );
        retSD=f_mount(&SDFatFS, "0:/",0);  
        if(retSD==FR_OK)
        {
             printf("MOUNT OK
    ");
             printf("FAILED0: %d
    ",retSD);
        }
        else
            printf("FAILED2: %d
    ",retSD);
        printf("文件打开
    " );
        retSD=f_open(&SDFile, "0:hellow.txt", FA_CREATE_ALWAYS | FA_WRITE | FA_READ );  
        if(retSD==FR_OK)
        {
             printf("OPEN OK
    ");
        }
        else
            printf("FAILED3: %d
    ",retSD);
        
        
        
         printf("文件关闭
    " );
         retSD=f_close(&SDFile);
            
        if(retSD==FR_OK)
        {
             printf("closk OK
    ");
        }
        else
            printf("FAILED5: %d
    ",retSD);
         
        
     }    

     

    (3)HAL_SD_ReadBlocks()和HAL_SD_WriteBlocks()可以往SD卡读写数据

    (4)用以下的HAKL库函数可读取SD卡的信息,有兴趣可以去弄

    HAL_SD_CardStateTypeDef HAL_SD_GetCardState(SD_HandleTypeDef *hsd);
    HAL_StatusTypeDef HAL_SD_GetCardCID(SD_HandleTypeDef *hsd, HAL_SD_CardCIDTypeDef *pCID);
    HAL_StatusTypeDef HAL_SD_GetCardCSD(SD_HandleTypeDef *hsd, HAL_SD_CardCSDTypeDef *pCSD);
    HAL_StatusTypeDef HAL_SD_GetCardStatus(SD_HandleTypeDef *hsd, HAL_SD_CardStatusTypeDef *pStatus);
    HAL_StatusTypeDef HAL_SD_GetCardInfo(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypeDef *pCardInfo);

     

    6.Fatfs使用小经验

    (1)使用FATFS,FIL等类型的变量时,可能要先申请内存空间,才能使用。具体是怎样请先学习STM32的内存管理。

    (2)使用f_mount,f_close等文件功能函数出错时,请看其返回函数为何值,更容易调试。

    
    
    typedef enum {
        FR_OK = 0,                /* (0) Succeeded */
        FR_DISK_ERR,            /* (1) A hard error occurred in the low level disk I/O layer */
        FR_INT_ERR,                /* (2) Assertion failed */
        FR_NOT_READY,            /* (3) The physical drive cannot work */
        FR_NO_FILE,                /* (4) Could not find the file */
        FR_NO_PATH,                /* (5) Could not find the path */
        FR_INVALID_NAME,        /* (6) The path name format is invalid */
        FR_DENIED,                /* (7) Access denied due to prohibited access or directory full */
        FR_EXIST,                /* (8) Access denied due to prohibited access */
        FR_INVALID_OBJECT,        /* (9) The file/directory object is invalid */
        FR_WRITE_PROTECTED,        /* (10) The physical drive is write protected */
        FR_INVALID_DRIVE,        /* (11) The logical drive number is invalid */
        FR_NOT_ENABLED,            /* (12) The volume has no work area */
        FR_NO_FILESYSTEM,        /* (13) There is no valid FAT volume */
        FR_MKFS_ABORTED,        /* (14) The f_mkfs() aborted due to any problem */
        FR_TIMEOUT,                /* (15) Could not get a grant to access the volume within defined period */
        FR_LOCKED,                /* (16) The operation is rejected according to the file sharing policy */
        FR_NOT_ENOUGH_CORE,        /* (17) LFN working buffer could not be allocated */
        FR_TOO_MANY_OPEN_FILES,    /* (18) Number of open files > _FS_LOCK */
        FR_INVALID_PARAMETER    /* (19) Given parameter is invalid */
    } FRESULT;

    (3)要先加载文件卷,才能用文件功能函数。

    (4)程序出错一般是底层接口函数没写好。

      粗糙之作,有不合之处请多多指教。

  • 相关阅读:
    k8s安装
    jinja +grains 取变量
    项目跨域问题
    Node.js做Web后端优势为什么这么大?
    Chrome使用技巧
    看完这篇操作系统吊打面试官
    几款国产操作系统的区别
    如果红军是一家公司,依然是最后的大赢家
    RPA AI .NET Core 与未来--学习笔记
    Oracle中MERGE INTO用法解析
  • 原文地址:https://www.cnblogs.com/feiniaoliangtiangao/p/11023636.html
Copyright © 2011-2022 走看看