讀寫SD是嵌入式系統中一個比較基礎的功能,在很多應用中都可以用得上SD卡。折騰了幾天,總算移植成功了 最新版Fatfs(Fatfs R0.09) ,成功讀寫SD卡下文件。
FatFs (http://elm-chan.org/fsw/ff/00index_e.html)是一個通用的文件系統模塊,用于在小型嵌入式系統中實現FAT文件系統。 FatFs 的編寫遵循ANSI C,因此不依賴于硬件平臺。它可以嵌入到便宜的微控制器中,如 8051, PIC, AVR, SH, Z80, H8, ARM 等等,不需要做任何修改。
1. SD卡/TF卡 硬件接口
SD卡有兩種操作接口,SDIO和SPI。 使用SDIO口的速度比較快,SPI的速度比較慢 。
SD卡引腳描述如下: SD卡SPI接法如下:
我使用的是正點原子的開發板,所以采用的是SPI接口的模式。
TF卡SDIO 模式和SPI模式 引腳定義:
可以發現Micro SD卡只有8個引腳是因為比SD卡少了一個Vss。使用TF轉SD的卡套套在Micro SD卡上,這樣一來大小就和SD卡一樣大,這時候卡套上的9個引腳就和SD卡一樣了,你可以完全當做SD卡來操作。
2. SD卡底層驅動
SD卡的操作比較復雜,需要多看看一些文檔 。 這里附上SD底層驅動代碼,代碼說明詳見注釋
Sd卡SPi操作底層代碼 :sdcard.csdcard.h
3. Fatfs 移植
FatFs 軟件包中相關文件:
ffconf.h FatFs 模塊配置文件
ff.h FatFs 和應用模塊公用的包含文件
ff.c FatFs 模塊
diskio.h FatFs and disk I/O 模塊公用的包含文件
integer.h 數據類型定義
option 可選的外部功能
diskio.c FatFs 與disk I/O 模塊接口層文件(不屬于 FatFs 需要由用戶提供)
FatFs 配置,文件系統的配置項都在 ffconf.h 文件之中:
(1) _FS_TINY :這個選項在R0.07 版本之中開始出現,在之前的版本都是以獨立的文件出現,現在通過一個宏來修改使用起來更方便;
(2) _FS_MINIMIZE、_FS_READONLY、_USE_STRFUNC、_USE_MKFS、_USE_FORWARD 這些宏是用來對文件系統進行裁剪
(3) _CODE_PAGE :本選項用于設置語言碼的類型
(4) _USE_LFN :取值為0~3,主要用于長文件名的支持及緩沖區的動態分配:
0:不支持長文件名;
1:支持長文件名存儲的靜態分配,一般是存儲在BSS 段;
2:支持長文件名存儲的動態分配,存儲在棧上;
3:支持長文件名存儲的動態分配,存儲在堆上。
(5) _MAX_LFN :可存儲長文件的最大長度,其值一般為(12~255),但是緩沖區一般占(_MAX_LFN + 1) * 2 bytes;
(6) _LFN_UNICODE :為1 時才支持unicode 碼;
(7) _FS_RPATH :R0.08a 版本改動配置項,取值范圍0~2:
0:去除相對路徑支持和函數;
1:開啟相對路徑并且開啟f_chdrive()和f_chdir()兩個函數;
2:在1 的基礎上添加f_getcwd()函數。
(8) _VOLUMES :支持的邏輯設備數目;
(9) _MAX_SS :扇區緩沖的最大值,其值一般為512;
(10) _MULTI_PARTITION:定義為1 時,支持磁盤多個分區;
(11) _USE_ERASE :R0.08a 新加入的配置項,設置為1 時,支持扇區擦除;
(12) _WORD_ACCESS :如果定義為1,則可以使用word 訪問;
(13) _FS_REENTRANT :定義為1 時,文件系統支持重入,但是需要加上跟操作系統信號量相關的幾個函數,函數在syscall.c 文件中;
(14) _FS_SHARE :文件支持的共享數目。
Fatfs 開源文件系統 從R0.07e 之后 版本開始就不再提供底層接口文件 diskio.c 模板,這里附上根據
以上SD卡底層驅動對應的 diskio.c 源碼:
002 | /*-----------------------------------------------------------------------*/ |
003 | /* Inidialize a Drive */ |
005 | DSTATUS disk_initialize ( |
006 | BYTEdrv/* Physical drive nmuber (0..) */ |
013 | returnSTA_NOINIT;//僅支持磁盤0的操作 |
017 | if(state == STA_NODISK) |
023 | returnSTA_NOINIT;//其他錯誤:初始化失敗 |
033 | /*-----------------------------------------------------------------------*/ |
034 | /* Return Disk Status */ |
037 | BYTEdrv/* Physical drive nmuber (0..) */ |
042 | returnSTA_NOINIT;//僅支持磁盤0操作 |
055 | /*-----------------------------------------------------------------------*/ |
059 | BYTEdrv,/* Physical drive nmuber (0..) */ |
060 | BYTE*buff,/* Data buffer to store read data */ |
061 | DWORDsector,/* Sector address (LBA) */ |
062 | BYTEcount/* Number of sectors to read (1..255) */ |
068 | returnRES_PARERR;//僅支持單磁盤操作,count不能等于0,否則返回參數錯誤 |
072 | returnRES_NOTRDY;//沒有檢測到SD卡,報NOT READY錯誤 |
077 | if(count==1)//1個sector的讀操作 |
079 | res = SD_ReadSingleBlock(sector, buff); |
083 | res = SD_ReadMultiBlock(sector, buff, count); |
088 | if(SD_ReadSingleBlock(sector, buff)!=0) |
096 | //處理返回值,將SPI_SD_driver.c的返回值轉成ff.c的返回值 |
109 | /*-----------------------------------------------------------------------*/ |
114 | BYTEdrv,/* Physical drive nmuber (0..) */ |
115 | constBYTE*buff,/* Data to be written */ |
116 | DWORDsector,/* Sector address (LBA) */ |
117 | BYTEcount/* Number of sectors to write (1..255) */ |
124 | returnRES_PARERR;//僅支持單磁盤操作,count不能等于0,否則返回參數錯誤 |
128 | returnRES_NOTRDY;//沒有檢測到SD卡,報NOT READY錯誤 |
134 | res = SD_WriteSingleBlock(sector, buff); |
138 | res = SD_WriteMultiBlock(sector, buff, count); |
150 | #endif /* _READONLY */ |
154 | /*-----------------------------------------------------------------------*/ |
155 | /* Miscellaneous Functions */ |
158 | BYTEdrv,/* Physical drive nmuber (0..) */ |
159 | BYTEctrl,/* Control code */ |
160 | void*buff/* Buffer to send/receive control data */ |
技術專區
主站蜘蛛池模板:
津南区|
安平县|
定州市|
监利县|
兰考县|
同仁县|
五台县|
石狮市|
阿拉善左旗|
乌拉特前旗|
大英县|
北辰区|
缙云县|
如皋市|
淄博市|
宁远县|
石首市|
正镶白旗|
濉溪县|
多伦县|
绿春县|
衡东县|
宝坻区|
天全县|
汾阳市|
澜沧|
湖南省|
伊金霍洛旗|
高碑店市|
惠州市|
盐池县|
二连浩特市|
清原|
牡丹江市|
开远市|
会东县|
梁平县|
湄潭县|
连平县|
台前县|
巩义市|
評論