SD卡在現在的日常生活與工作中使用非常廣泛,時下已經成為最為通用的數據存儲卡。在諸如MP3、數碼相機等設備上也都采用SD卡作為其存儲設備
SD卡在現在的日常日子與作業中運用十分廣泛,時下已經成為最為通用的數據存儲卡。在比如MP3、數碼相機等設備上也都選用SD卡作為其存儲設備。SD卡之所以得到如此廣泛的運用,是由于它價格低廉、存儲容量大、運用便利、通用性與安全性強等長處。已然它有著這么多長處,那么假如將它加入到單片機應用開發體系中來,將使體系變得愈加超卓。這就要求對SD卡的硬件與讀寫時序進行研究。關于SD卡的硬件結構,在官方的文檔上有很具體的介紹,如SD卡內的存儲器結構、存儲單元安排辦法等內容。要完成對它的讀寫,最中心的是它的時序,筆者在經過了實踐的測驗后,運用51單片機成功完成了對SD卡的扇區讀寫,并對其讀寫速度進行了評價。下面先來解說SD卡的讀寫時序。
(1)SD卡的引腳界說:
SD卡引腳功用臚陳:
引腳 編號 |
SD形式 | SPI形式 | ||||
稱號 | 類型 | 描繪 | 稱號 | 類型 | 描繪 | |
1 | CD/DAT3 | IO或PP |
卡檢測/ 數據線3 |
#CS | I | 片選 |
2 | CMD | PP |
指令/ 回應 |
DI | I | 數據輸入 |
3 | VSS1 | S | 電源地 | VSS | S | 電源地 |
4 | VDD | S | 電源 | VDD | S | 電源 |
5 | CLK | I | 時鐘 | SCLK | I | 時鐘 |
6 | VSS2 | S | 電源地 | VSS2 | S | 電源地 |
7 | DAT0 | IO或PP | 數據線0 | DO | O或PP | 數據輸出 |
8 | DAT1 | IO或PP | 數據線1 | RSV | ||
9 | DAT2 | IO或PP | 數據線2 | RSV |
注:S:電源供應I:輸入O:選用推拉驅動的輸出
PP:選用推拉驅動的輸入輸出 SD卡SPI形式下與單片機的銜接圖:
SD卡支撐兩種總線辦法:SD辦法與SPI辦法。其間SD辦法選用6線制,運用CLK、CMD、DAT0~DAT3進行數據通訊。而SPI辦法選用4線制,運用CS、CLK、DataIn、DataOut進行數據通訊。SD辦法時的數據傳輸速度與SPI辦法要快,選用單片機對SD卡進行讀寫時一般都選用SPI形式。選用不同的初始化辦法可以使SD卡作業于SD辦法或SPI辦法。這兒只對其SPI辦法進行介紹。
(2)SPI辦法驅動SD卡的辦法
SD卡的SPI通訊接口使其可以經過SPI通道進行數據讀寫。從運用的視點來看,選用SPI接口的優點在于,許多單片機內部自帶SPI控制器,不但給開發上帶來便利,一起也見降低了開發本錢。但是,它也有欠好的當地,如失去了SD卡的功能優勢,要處理這一問題,就要用SD辦法,由于它供給更大的總線數據帶寬。SPI接口的選用是在上電初始時向其寫入第一個指令時進行的。以下介紹SD卡的驅動辦法,只完成簡略的扇區讀寫。
1)指令與數據傳輸
1.指令傳輸
SD卡本身有齊備的指令體系,以完成各項操作。指令格局如下:
指令的傳輸進程選用發送應對機制,進程如下:
每一個指令都有自己指令應對格局。在SPI形式中界說了三種應對格局,如下表所示:
字節 | 位 | 意義 |
1 | 7 | 開端位,一直為0 |
6 | 參數過錯 | |
5 | 地址過錯 | |
4 | 擦除序列過錯 | |
3 | CRC過錯 | |
2 | 不合法指令 | |
1 | 擦除復位 | |
0 | 擱置狀況 |
字節 | 位 | 意義 |
1 | 7 | 開端位,一直為0 |
6 | 參數過錯 | |
5 | 地址過錯 | |
4 | 擦除序列過錯 | |
3 | CRC過錯 | |
2 | 不合法指令 | |
1 | 擦除復位 | |
0 | 擱置狀況 | |
2 | 7 | 溢出,CSD掩蓋 |
6 | 擦除參數 | |
5 | 寫保護不合法 | |
4 | 卡ECC失利 | |
3 | 卡控制器過錯 | |
2 | 不知道過錯 | |
1 | 寫保護擦除越過,鎖/解鎖失利 | |
0 | 鎖卡 |
字節 | 位 | 意義 |
1 | 7 | 開端位,一直為0 |
6 | 參數過錯 | |
5 | 地址過錯 | |
4 | 擦除序列過錯 | |
3 | CRC過錯 | |
2 | 不合法指令 | |
1 | 擦除復位 | |
0 | 擱置狀況 | |
2~5 | 悉數 | 操作條件寄存器,高位在前 |
寫指令的例程:
//-----------------------------------------------------------------------------------------------
向SD卡中寫入指令,并回來回應的第二個字節
//-----------------------------------------------------------------------------------------------
unsignedcharWrite_Command_SD(unsignedchar*CMD)
{
unsignedchartmp;
unsignedcharretry=0;
unsignedchari;
//制止SD卡片選
SPI_CS=1;
//發送8個時鐘信號
Write_Byte_SD(0xFF);
//使能SD卡片選
SPI_CS=0;
//向SD卡發送6字節指令
for(i=0;i<0x06;i++)
{
Write_Byte_SD(*CMD++);
}
//取得16位的回應
Read_Byte_SD();//readthefirstbyte,ignoreit.
do
{//讀取后8位
tmp=Read_Byte_SD();
retry++;
}
while((tmp==0xff)&&(retry<100));
return(tmp);
}
2)初始化
SD卡的初始化是十分重要的,只要進行了正確的初始化,才干進行后邊的各項操作。在初始化進程中,SPI的時鐘不能太快,否則會造初始化失利。在初始化成功后,應盡量進步SPI的速率。在剛開端要先發送至少74個時鐘信號,這是有必要的。在許多讀者的試驗中,許多是由于忽略了這一點,而使初始化不成功。隨后便是寫入兩個指令CMD0與CMD1,使SD卡進入SPI形式
初始化時序圖:
初始化例程:
//--------------------------------------------------------------------------
初始化SD卡到SPI形式
//--------------------------------------------------------------------------
unsignedcharSD_Init()
{
unsignedcharretry,temp;
unsignedchari;
unsignedcharCMD[]={0x40,0x00,0x00,0x00,0x00,0x95};
SD_Port_Init();//初始化驅動端口
Init_Flag=1;//將初始化標志置1
for(i=0;i<0x0f;i++)
{
Write_Byte_SD(0xff);//發送至少74個時鐘信號
}
//向SD卡發送CMD0
retry=0;
do
{//為了可以成功寫入CMD0,在這兒寫200次
temp=Write_Command_SD(CMD);
retry++;
if(retry==200)
{//超越200次
return(INIT_CMD0_ERROR);//CMD0Error!
}
}
while(temp!=1);//回應01h,中止寫入
//發送CMD1到SD卡
CMD[0]=0x41;//CMD1
CMD[5]=0xFF;
retry=0;
do
{//為了能成功寫入CMD1,寫100次
temp=Write_Command_SD(CMD);
retry++;
if(retry==100)
{//超越100次
return(INIT_CMD1_ERROR);//CMD1Error!
}
}
while(temp!=0);//回應00h中止寫入
Init_Flag=0;//初始化結束,初始化標志清零
SPI_CS=1;//片選無效
return(0);//初始化成功
}
3)讀取CID
CID寄存器存儲了SD卡的標識碼。每一個卡都有僅有的標識碼。
CID寄存器長度為128位。它的寄存器結構如下:
稱號 | 域 | 數據寬度 | CID區分 |
出產標識號 | MID | 8 | [127:120] |
OEM/運用標識 | OID | 16 | [119:104] |
產品稱號 | PNM | 40 | [103:64] |
產品版別 | PRV | 8 | [63:56] |
產品序列號 | PSN | 32 | [55:24] |
保存 | - | 4 | [23:20] |
出產日期 | MDT | 12 | [19:8] |
CRC7校驗合 | CRC | 7 | [7:1] |
未運用,一直為1 | - | 1 | [0:0] |
它的讀取時序如下:
與此時序相對應的程序如下:
//------------------------------------------------------------------------------------
讀取SD卡的CID寄存器16字節成功回來0
//-------------------------------------------------------------------------------------
unsignedcharRead_CID_SD(unsignedchar*Buffer)
{
//讀取CID寄存器的指令
unsignedcharCMD[]={0x4A,0x00,0x00,0x00,0x00,0xFF};
unsignedchartemp;
temp=SD_Read_Block(CMD,Buffer,16);//read16bytes
return(temp);
}
審核編輯黃昊宇
-
單片機
+關注
關注
6037文章
44562瀏覽量
635760 -
SD卡
+關注
關注
2文章
565瀏覽量
63926
發布評論請先 登錄
相關推薦
評論