SD卡檔案讀寫

來源:互聯網
上載者:User
SD卡檔案讀寫

象棋小子    1048272975

SD卡(Secure Digital Memory Card)具有體積小、容量大、資料轉送快、可插拔、安全性好等優點,被廣泛應用於攜帶型裝置上。例如作為數位相機的儲存卡,作為手機、平板多媒體擴充卡用的TF卡(micro sd)等等。 1. SD卡概述

SD卡技術是在MMC卡的基礎上發展起來的,其尺寸與MMC卡一樣,只是比MMC卡厚了0.7mm,因此SD主機可以識別並存取MMC卡。SD卡介面除了保留MMC卡的7針外,還在兩邊加了2針,作為資料線,目的是通過把傳輸方式由串列變成並行,以提高傳輸速率。此時的規範為SD1.0版本,最高容量只能到4GB。為了跟進產品的更新換代,SD聯合協會在06年發布了容量更大、儲存更快的下一代SD卡規範SD2.0。該規範重新定義了SD卡的速度等級,分為三檔:Class 2、4、6,分別對應寫入速度2MB/S、4MB/S、6MB/S。根據卡容量又分為標準卡(小於2GB)和高容量卡(2GB~32GB),目前市面上應用的SD卡絕大部分都是SD2.0版本的卡。為了讓儲存卡更加迷你,通過SD卡規範標準,又衍生了MiniSD卡和Micro SD卡,這些卡均比標準SD卡尺寸小,通過SD轉接套可以當作一般的SD卡使用。尤其是Micro SD卡,可以算是最小的儲存卡了,超小的體積可以極大的節省消費電子產品內部設計的空間,基本目前的Android手機均是選用Micro SD卡作為多媒體擴充儲存卡。隨著科技的進步,SD2.0規範SD卡也漸漸無法滿足應用的需求,在10年SD聯合協會又發布了新的SD3.0規範,該規範定義了sdxc和uhs,並增加了Class10,容量範圍為32GB~2TB。在sdxc卡仍需進一步坐等其價格下降的情況下,SD4.0規範已經開始在緊張的制訂中,這已超出本文的討論範圍內了。 2. SD卡驅動

SD卡共支援三種傳輸模式:SPI模式、1位SD模式、4位SD模式。所有的SD卡都必須支援較老的SPI/MMC模式,這個模式支援慢速的四線SPI介面,使很多微控制器都可以通過SPI或類比SPI介面來讀寫SD卡。萬利的LPC5411x開發板通過SPI介面擴充了一個TF卡槽,可以用SPI介面讀寫TF卡。

SD2.0標準定義了物理層相關規範以及主機控制器規範,SD卡驅動的編寫必須參考這兩個規範,遵循標準的SD卡均可以採用統一的軟體驅動實現資料訪問。NXP對於其全系列的晶片提供了sdmmc庫中介軟體用於支援SD/MMC卡的讀寫,可以在官網下載相應的BSP,裡麵包含sdmmc庫,fsl_sdspi.h/fsl_sdspi.c即為SPI模式訪問SD卡的標準驅動,可以直接應用到LPC5411x開發環境中。SD卡驅動最主要實現三個介面,分別是SD卡的識別初始化、SD卡的塊讀、SD卡的塊寫,具體實現可以參考fsl_sdspi.h/fsl_sdspi.c驅動檔案。 3. Fatfs

資料往往以檔案的形式儲存在儲存裝置中,對於SD卡,一般採用的是Fat32檔案系統,Fatfs由於其開源免費,支援Fat32,受到了廣泛的應用。

Fatfs是由日本工程師ChaN所編寫的Fat檔案系統模組,從06年發布第一個Fatfs版本開始,作者就從未停止維護和更新。Fatfs的編寫遵循ANSI C,並且完全與磁碟I/O層分開。它不依賴於硬體架構,代碼和工作區佔用空間小,使之可以嵌入到各個低成本的微控制器中,如AVR、8051、PIC、ARM、Z80、68K等。由於SD卡一般使用Fat32檔案系統,在使用到SD卡的系統中移植Fatfs,將很好地實現對SD卡檔案的管理。

Fatfs模組完全獨立於磁碟I/O層,因此底層磁碟I/O訪問並不屬於Fatfs的模組部分,使用者必須自己實現這部分用來訪問存放裝置。通常在diskio.c中實現這幾個函數disk_initialize()、disk_status()、disk_read()、disk_wirte()、disk_ioctl()即可,如果使能了OS相關的特性,則還需額外實現進程/記憶體函數。其中disk_initialize()對應SD卡驅動中的卡識別初始化介面,disk_read()對應SD卡的塊讀介面,disk_wirte()對應SD卡的塊寫介面。NXP對於其全系列的晶片提供了Fatfs中介軟體的支援,Fatfs對應SD卡驅動介面的具體實現可以參考BSP中已移植好的Fatfs中介軟體。 4. 讀寫測試

移植好SD卡驅動以及Fatfs底層對應介面後,就可以用Fatfs應用編程介面讀寫SD卡裡面的檔案。應用以2KB大小為讀寫單位,測試讀寫10MB大小檔案的平均讀寫速度。

uint8_t TestBuffer[2048];

int main()

{

uint32_t i;

FATFS fs;

FIL file;

FRESULT Res;     

uint32_t TimeCount;

uint32_t ByteWrite, ByteRead;

 

 /* Board pin, clock, debug console init */

 /*attach 12 MHz clock to FLEXCOMM0 (debug console) */

CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);

/* enable clock for GPIO*/

CLOCK_EnableClock(kCLOCK_Gpio0);

CLOCK_EnableClock(kCLOCK_Gpio1);

 

BOARD_InitPins();

BOARD_BootClockFROHF96M();

BOARD_InitDebugConsole();    

 

Gpio_Init();

 

f_mount(&fs, "4:" , 0);      

/*

Res = f_mkfs("", 0, 4096);

if (Res != RES_OK) {

       PRINTF("f_mkfs error %d\r\n",Res);

       while(1);

}

*/

PRINTF("Writing test.bin, file sise10MB\r\n");

 Res= f_open(&file, "4:test.bin", FA_WRITE | FA_CREATE_ALWAYS);

if (Res != RES_OK) {

       PRINTF("Createfile failed\r\n");

       while(1){

              GPIO_TogglePinsOutput(GPIO,0, 1u << 15);

              Delay_ms(300);                

       }

}

for (i=0; i<sizeof(TestBuffer); i++){

       TestBuffer[i]= i;

}

TimeCount =timer_get_current_milliseconds();

for (i=0;i<10*1024*1024/sizeof(TestBuffer); i++) {

       Res= f_write(&file, &TestBuffer, sizeof(TestBuffer), &ByteWrite);

       if(Res != RES_OK) {

              f_close(&file);

              PRINTF("Writefile error\r\n");

              while(1){

                     GPIO_TogglePinsOutput(GPIO,0, 1u << 15);

                     Delay_ms(300);

              }

       }

}

f_close(&file);

PRINTF("Sd write speed %dKB/s\r\n", 10*1024*1024/(timer_get_current_milliseconds()-TimeCount));

      

PRINTF("Reading test.bin, file sise10MB\r\n");

Res = f_open(&file, "4:test.bin", FA_READ | FA_OPEN_EXISTING);

if (Res != RES_OK) {

       PRINTF("Openfile failed\r\n");

       while(1){

              GPIO_TogglePinsOutput(GPIO,0, 1u << 15);

              Delay_ms(300);

       }

}

TimeCount =timer_get_current_milliseconds();

for (i=0;i<10*1024*1024/sizeof(TestBuffer); i++) {

       Res= f_read(&file, (unsigned char *)&TestBuffer, sizeof(TestBuffer),&ByteRead);

       if(Res != RES_OK) {

              f_close(&file);

              PRINTF("Readfile error\r\n");

              while(1){

                     GPIO_TogglePinsOutput(GPIO,0, 1u << 15);

                     Delay_ms(300);

              }

       }

}

f_close(&file);

PRINTF("Sd read speed %dKB/s\r\n", 10*1024*1024/(timer_get_current_milliseconds()-TimeCount));

 

while(1) {

       GPIO_TogglePinsOutput(GPIO,0, 1u << 15);

       Delay_ms(1000);

}

}

讀寫速度測試結果如下:

SD卡寫速度為872 KB/S,讀速度為1169 KB/S,SD卡通過SPI介面讀寫,SPI時鐘採用FRO 12M時鐘,因此這個讀寫速度是合適的。SD卡讀寫速度跟卡速度等級、資料轉送速率有關,讀寫多塊要比一塊一塊分多次讀寫快,此處測試一次性讀取8塊(512位元組/塊),2048位元組,讀寫速度主要受限於SPI的傳輸速率,LPC5411x的SPI介面最高支援48M的時鐘,SPI可以通過採用PLL時鐘、內部高速時鐘,進一步提高SPI的傳輸速率,從而進一步提高SD卡的讀寫速度。 5. 附錄

MDK工程,包含SPI模式的SD驅動,Fatfs檔案系統模組,SD卡讀寫速度測試應用常式。

https://pan.baidu.com/s/1cMz1G6

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.