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