新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > STM32+SDIO+FATFS文件系統 直讀SD卡

        STM32+SDIO+FATFS文件系統 直讀SD卡

        作者: 時間:2016-12-03 來源:網絡 收藏
        網上關于小型嵌入式文件系統有好多~當然要數 FATFS 很是出名 一來小巧,二來免費。當然了國產的振南的znFAT 一樣開源好用而且極其的省資源~!非常適合51單片。更重要的是國語的支持,呵呵!這次在STM32上為SD卡移植文件系統還是非常簡單順利的,這多虧了ST 官方提供的驅動,而我自己不用動手編寫SD卡的命令省了很多時間而且官方做的驅動雖然效率一般但是極其嚴謹我很是佩服。

        FATFS的官方網站是

        本文引用地址:http://www.104case.com/article/201612/325209.htm

        http://elm-chan.org/fsw/ff/00index_e.html

        znFAT的官方網站是

        http://www.znmcu.cn/softshow.asp?id=47

        今天上午問個妹子要電話,沒給我........唉~太失敗了。

        SD卡可以用SPI驅動 也可以直接用 SDIO 驅動 STM32 256KB FLASH 以上的片子全部都有SDIO,我們當然要用高速快捷的SDIO 方式了!至于 SDIO 又有 1位 4位 8 位的之分 我想不來8位SDIO 是怎么回事?SD卡上最多只能接4位嘛~網上有人說4位的SDIO 不好用多半是固件版本太老的緣故了。呵呵這里還是要靠庫~STM32真適合懶人用。

        網上關于的FATFS 的文章很多 不過都太老舊,很多東西已經不適用了 。我建議閣下到官方去下載最新的版本 目前是最新是R0.08b,使用最新的版本好處是很多網上很多要改來改去的地方只要你使用了新版本那就是完全可以規避的。另外STM32 的SDIO驅動也一定要用最新的,老版本問題很多不少人的失敗就在這。我這次用的是V3.3的庫沒有任何改動就可以了,現在最新的好像在3.4以上了。好了說說移植 ffconf.h是配置的頭文件 簡單的修改宏就可以了,英文注釋的很完全而且網上也有翻譯我不多說了自己看http://www.openrtos.cn/fatfs主要在這里進行功能裁剪寫寫我的配置。

        #define_FS_TINY0/* 0:Normal or 1:Tiny 完整的FATFS 精簡版的是Tiny */

        #define _FS_READONLY0/* 0:Read/Write or 1:Read only 能讀能寫*/

        #define _FS_MINIMIZE1/* 0 to 3 簡單的裁剪f_mkdir, f_chmod..這些功能沒法用的*/
        /* The _FS_MINIMIZE option defines minimization level to remove some functions.
        /
        / 0: Full function.
        / 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename
        / are removed.
        / 2: f_opendir and f_readdir are removed in addition to 1.
        / 3: f_lseek is removed in addition to 2. */


        #define_USE_STRFUNC0/* 0:Disable or 1/2:Enable是否使用字符串文件接口 */
        /* To enable string functions, set _USE_STRFUNC to 1 or 2. */


        #define_USE_MKFS0/* 0:Disable or 1:Enable制作文件系統我在PC上一般已經格式化好了*/
        /* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */


        #define_USE_FORWARD0/* 0:Disable or 1:Enable 發文件流?*/
        /* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */


        #define_USE_FASTSEEK0/* 0:Disable or 1:Enable 搜索*/
        /* To enable fast seek feature, set _USE_FASTSEEK to 1. */

        #define _CODE_PAGE1//1 - ASCII only (Valid for non LFN cfg.)

        #define_USE_LFN0/* 0 to 3 */
        #define_MAX_LFN255/* Maximum LFN length to handle (12 to 255) 這些都是長文件名或是漢字文件支持很費資源所以不開啟這些*/

        #define_FS_SHARE0/* 0:Disable or >=1:Enable 不使用相對路徑*/

        #define_FS_SHARE0/* 0:Disable or >=1:Enable 文件共享多任務的操作系統會用到的*/

        #define _FS_REENTRANT0/* 0:Disable or 1:Enable 這些是啥用?同步什么呢?默認就好了*/
        #define _FS_TIMEOUT1000/* Timeout period in unit of time ticks */
        #define_SYNC_tHANDLE/* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */

        integer.h主要定義了文件的類型 若是最新的可以不用修改。

        好了 說說最關鍵的I/O module 我自己建立一個文件diskio.c新的版本要自己建立函數文件官方連個模板都沒提供作者似乎不怎么照顧新人呢~

        都說要移植5個函數 其實兩個就足以了。

        /*-----------------------------------------------------------------------*/
        /* Low level disk I/O module skeleton for FatFs (C)ChaN, 2011 */
        /*-----------------------------------------------------------------------*/
        /* This is a stub disk I/O module that acts as front end of the existing */
        /* disk I/O modules and attach it to FatFs module with common interface. */
        /*-----------------------------------------------------------------------*/

        #include"diskio.h"
        #include"stm32f10x.h"
        #include"stm32_eval_sdio_sd.h"

        #defineBLOCK_SIZE 512/* Block Size in Bytes */

        /*-----------------------------------------------------------------------*/
        /* Inidialize a Drive */

        DSTATUS disk_initialize (
        BYTE drv/* Physical drive nmuber (0..) */
        )
        {
        SD_Error Status;
        /* Supports only singledriveFATFS支持多個設備所以有個設備號drive nmuber當然了我就一個SD卡所以只有零號*/
        if (drv)
        {
        return STA_NOINIT;
        }
        /*-------------------------- SD Init ----------------------------- */
        Status = SD_Init();
        if (Status!=SD_OK )
        {
        return STA_NOINIT;
        }
        else
        {
        return RES_OK;
        }

        }

        /*-----------------------------------------------------------------------*/
        /* Return Disk Status */

        DSTATUS disk_status (
        BYTE drv/* Physical drive nmuber (0..) */
        )
        {
        return RES_OK;//懶的管了 有空寫寫 可以加個
        }

        /*-----------------------------------------------------------------------*/
        /* Read Sector(s) */

        DRESULT disk_read (
        BYTE drv,/* Physical drive nmuber (0..) */
        BYTE *buff,/* Data buffer to store read data */
        DWORD sector,/* Sector address (LBA) 注意這個是扇區地址也就是第幾個扇區*/
        BYTE count/* Number of sectors to read (1..255) 讀取的扇區數*/
        )
        {
        //SD_Error Status;
        if (count > 1)
        {
        SD_ReadMultiBlocks(buff, sector*BLOCK_SIZE, BLOCK_SIZE, count);//扇區地址*512就是實際地址 默認一個扇區就是512個字節
        }
        else
        {
        SD_ReadBlock(buff, sector*BLOCK_SIZE, BLOCK_SIZE);
        }
        return RES_OK;
        }

        /*-----------------------------------------------------------------------*/
        /* Write Sector(s) */

        #if _READONLY == 0
        DRESULT disk_write (
        BYTE drv,/* Physical drive nmuber (0..) */
        const BYTE *buff,/* Data to be written */
        DWORD sector,/* Sector address (LBA) */
        BYTE count/* Number of sectors to write (1..255) */
        )
        {
        if (count > 1)
        {
        SD_WriteMultiBlocks((uint8_t *)buff, sector*BLOCK_SIZE, BLOCK_SIZE, count);

        /*這里大家看到了有個地址轉換 因為DMA僅僅支持4字節指針的所以在函數內部還是有個轉換的這里最好優化一下能提高效率*/
        }
        else
        {
        SD_WriteBlock((uint8_t *)buff,sector*BLOCK_SIZE, BLOCK_SIZE);
        }
        return RES_OK;
        }
        #endif/* _READONLY */


        /*-----------------------------------------------------------------------*/
        /* Miscellaneous Functions */

        DRESULT disk_ioctl (
        BYTE drv,/* Physical drive nmuber (0..) */
        BYTE ctrl,/* Control code */
        void *buff/* Buffer to send/receive control data 若是用到擦除函數這個函數一定要補完的有空再寫寫吧我這簡單的返回就好了*/
        )
        {
        return RES_OK;
        }

        /*-----------------------------------------------------------------------*/
        /* Get current time */
        /*-----------------------------------------------------------------------*/
        DWORD get_fattime(void)
        {
        return ((2011UL-1980) << 25)// Year = 2011
        | (3UL << 21)// Month = Mar
        | (26UL << 16)// Day = 26
        | (13U << 11)// Hour = 13
        | (19U << 5)// Min =19
        | (0U >> 1) // Sec = 0
        ;
        }

        最終無優化編譯后 :Program Size: Code=10904RO-data=336RW-data=56ZI-data=2304

        RO是程序中的指令和常量
        RW是程序中的已初始化變量
        ZI是程序中的未初始化的變量
        我覺得這個大小對于STM32103FZE來說完全可以接受


        評論


        技術專區

        關閉
        主站蜘蛛池模板: 昭苏县| 老河口市| 景东| 郯城县| 宜黄县| 东乡县| 金川县| 新闻| 修水县| 将乐县| 从化市| 金平| 宁陕县| 夏邑县| 德化县| 龙岩市| 镶黄旗| 崇礼县| 克拉玛依市| 奉化市| 同江市| 大田县| 济阳县| 侯马市| 龙川县| 灵璧县| 邮箱| 南宁市| 娄烦县| 阳谷县| 屯门区| 长宁区| 上思县| 塔城市| 汾阳市| 舒兰市| 利川市| 聊城市| 镇平县| 常宁市| 景洪市|