中文字幕理论片,69视频免费在线观看,亚洲成人app,国产1级毛片,刘涛最大尺度戏视频,欧美亚洲美女视频,2021韩国美女仙女屋vip视频

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
深入理解SD卡基礎(chǔ)原理以及內(nèi)部結(jié)構(gòu)的總結(jié)
1、 簡介:
SD卡(Secure Digital Memory Card)是一種為滿足安全性、容量、性能和使用環(huán)境等各方面的需求而設(shè)計的一種新型存儲器件,SD卡允許在兩種模式下工作,即SD模式和SPI模式,本 系統(tǒng)采用SPI模式。本小節(jié)僅簡要介紹在SPI模式下,STM32處理器如何讀寫SD卡,如果讀者如希望詳細了解SD卡,可以參考相關(guān)資料。
SD 卡內(nèi)部結(jié)構(gòu)及引腳如下圖所示:

 


SD卡內(nèi)部圖.JPG



2、SD卡管腳圖:

SD卡圖.JPG



3、SPI模式下SD各管腳名稱為:
sd 卡:

SPI模式下SD各管腳名稱 為.JPG



注: 一般SD有兩種模式:SD模式和SPI模式,管腳定義如下:
(A)、SD MODE 1、CD/DATA3   2、CMD 3、VSS1 4、VDD 5、CLK 6、VSS2 7、DATA0 8、DATA1 9、DATA2
(B)、SPI MODE 1、CS             2、DI 3、VSS 4、VDD 5、SCLK 6、VSS2 7、DO           8、RSV 9、RSV

SD 卡主要引腳和功能為:
CLK:時鐘信號,每個時鐘周期傳輸一個命令或數(shù)據(jù)位,頻率可在0~25MHz之間變化,SD卡的總線管理器可以不受任何限制的自由產(chǎn)生0~25MHz 的頻率;
CMD:雙向命令和回復線,命令是一次主機到從卡操作的開始,命令可以是從主機到單卡尋址,也可以是到所有卡;回復是對之前命令的回答,回復可以來自單 卡或所有卡;
DAT0~3:數(shù)據(jù)線,數(shù)據(jù)可以從卡傳向主機也可以從主機傳向卡。
SD卡以命令形式來控制SD卡的讀寫等操作??筛鶕?jù)命令對多塊或單塊進行讀寫操作。在SPI模式下其命令由6個字節(jié)構(gòu)成,其中高位在前。SD卡命令 的格式如表1所示,其中相關(guān)參數(shù)可以查閱SD卡規(guī)范。


4、MicroSD卡管腳圖:

MicroSD卡管腳圖.JPG


5、MicroSD卡管腳名稱:

MicroSD卡管腳名 稱.JPG



SD 卡與MicroSD卡僅僅是封裝上的不同,MicroSD卡更小,大小上和一個SIM卡差不多,但是協(xié)議與SD卡相同。
一般我們用單片機操作SD 卡時,都不需要對FAT分區(qū)表信息做處理,原因如下:
1)、操作FAT分區(qū)表要增加程序代碼量、增加SRAM的消耗,對于便攜應(yīng)用來說代碼大小和 占用SRAM的多少至關(guān)重要。
2)、即使我們對FAT分區(qū)表不做任何了解,實際上我們一樣可以向SD卡上寫入數(shù)據(jù),這就表明使用FAT對我們做數(shù) 據(jù)存儲應(yīng)用來說如同雞肋。
3)、耗費大量經(jīng)歷和時間去了解FAT分區(qū)表對于我們做嵌入式軟件開發(fā)的人來說有些得不償失。
4)、SD卡支持 兩種操作模式,SD模式和SPI模式,SPI模式做SD數(shù)據(jù)操作時根本不需要知道FAT,這時候SD卡對于我們來說實際上就是個大的、快速的、方便的、容 量可變的外部存儲器。
基于以上原因,一般情況下對SD卡的操作只需要了解SPI通訊就可以了,而現(xiàn)在大部分單片機都有SPI接口,那么操作SD卡 易如反掌。


以下是做SD卡試驗時使用的電路圖:

SD卡試驗時使用的電路 圖.JPG


SD_CS/ 連接到單片機的片選SD管腳,只有單片機設(shè)置SD_CS/為低電平時才可以操作SD卡。
MOSI連接單片機SPI總線的MOSI管腳(SPI數(shù)據(jù) 輸入),單片機從這個管腳讀取SD卡內(nèi)的數(shù)據(jù)。
MISO連接單片機SPI總線的MISO管腳(SPI數(shù)據(jù)輸出)、單片機通過這個管腳向SD卡內(nèi)寫 入數(shù)據(jù)。
SCK連接單片機SPI總線的SCK(SPI時鐘)
SD管腳實際上在SD卡內(nèi)部連接到了GND,當SD插座上沒插入SD卡時,單 片機從這個管腳能讀到高電平(前提是使用單片機內(nèi)部上拉輸入,或者外部增加一個上拉電阻),一旦插入SD卡,這個管腳就變成低電平,這個功能用來檢測是否 插入SD卡。
RSV1和RSV2是保留功能管腳,不需要操作。
MicroSD卡的連接和SD卡大同小異,只是MicroSD卡比SD卡少 一個GND管腳,所以不能使用上面做的這種插入卡的檢測,實際上現(xiàn)在很多SD卡/MicroSD卡插座都有插入檢測管腳,當然,一分錢一分貨,價格上當然 也要貴一些
順便提一下,普通SD卡插座最多5塊錢。

SPI命令格式

Byte 1

Byte2-5

Byte 6

7

6

5        0

31       0

7

0

0

1

Command

Command Argument

CRC

1


以下是一個簡單的測試SD卡讀 寫的程序,程序是基于Atmega128單片機編寫的,對于Atmega的其他單片機僅需要做管腳改動就可以使用,其他單片機更改要更大。
sd.h
//******************************************************************
//SPI 各線所占用的端口
#define SD_SS          PB6                         
#define SD_SCK         PB1
#define SD_MOSI        PB2
#define SD_MISO        PB3
//******************************************************************

#define SD_DDR         DDRB
#define SD_PORT        PORTB
#define SD_PIN         PINB

#define SD_SS_H        SD_PORT |= (1<
#define SDSS_L        SD_PORT &= ~(1<
#define SD_SCK_H       SD_PORT |= (1<
#define SD_SCK_L       SD_PORT &= ~(1<
#define SD_MOSI_H      SD_PORT |= (1<
#define SD_MOSI_L      SD_PORT &= ~(1<

#define SD_MISO_IN     (SD_PIN&(1<
//-------------------------------------------------------------
// 錯誤號
//-------------------------------------------------------------
#define INIT_CMD0_ERROR         0xFF
#define INIT_CMD1_ERROR         0xFE
#define WRITE_BLOCK_ERROR       0xFD
#define READ_BLOCK_ERROR        0xFC
#define TRUE                    0x01
//-------------------------------------------------------------
// MMC/SD 命令(命令號從40開始,只列出基本命令,并沒有都使用)
//-------------------------------------------------------------
#define SD_RESET                0x40 + 0                  
#define SD_INIT                0x40 + 1
#define SD_READ_CSD            0x40 + 9
#define SD_READ_CID            0x40 + 10
#define SD_STOP_TRANSMISSION    0x40 + 12
#define SD_SEND_STATUS            0x40 + 13
#define SD_SET_BLOCKLEN        0x40 + 16
#define SD_READ_BLOCK            0x40 + 17
#define SD_READ_MULTI_BLOCK    0x40 + 18
#define SD_WRITE_BLOCK            0x40 + 24
#define SD_WRITE_MULTI_BLOCK    0x40 + 25

//片選關(guān)(MMC/SD-Card Invalid)
#define SD_Disable()   SD_SS_H
//片選開 (MMC/SD-Card Active)
#define SD_Enable()    SD_SS_L

SD_TEST.C
//****************************************************************************************/
//ICC-AVR application builder : 03-5-20 8:39:11
// Target : M128
// Crystal: 3.6864Mhz

#include
#include
#include 'sd.h'
void uart0_init(void);
void putchar(unsigned char content);
void putstr(unsigned char *s);
void SD_Port_Init(void);
unsigned char SD_Init(void);
unsigned char SD_write_sector(unsigned long addr,unsigned char *Buffer);
unsigned char SD_read_sector(unsigned long addr,unsigned char *Buffer);
unsigned char SPI_TransferByte(unsigned char byte);
unsigned char Write_Command_SD(unsigned char cmd,unsigned long address);
unsigned long SD_find(void);
//**************************************************************************
// 串口調(diào)試程序
//**************************************************************************
void uart0_init(void)
{
UCSR0B = 0x00; //disable while setting baud rate
UCSR0A = 0x00;
UCSR0C = 0x06; // 00000110 UART0設(shè)置為異步模式、無奇偶校驗、1位停止位、8位數(shù)據(jù)位
UBRR0L = 0x17; //set baud rate lo
UBRR0H = 0x00; //set baud rate hi 設(shè)置UART0口通信速率9600
UCSR0B = 0x18;
}
void putchar(unsigned char content)
{

while(!(UCSR0A & (1 << UDRE0))); /*    判斷上次發(fā)送有沒有完成    */
UDR0 = content;    /*    發(fā)送數(shù)據(jù)    */

}
void putstr(unsigned char *s)
{

while(*s)
{
putchar(*s);
s++;
}

}

//****************************************************************************
// 端口初始化
void SD_Port_Init(void)
//****************************************************************************
{
SD_PORT        |= (1<<
SD_DDR         |= (1<<<
SD_DDR         &= ~(1<
}

//****************************************************************************
// 初始化 MMC/SD 卡為SPI模式
unsigned char SD_Init(void)
//****************************************************************************
{
unsigned char retry,temp;
unsigned char i;


SPCR=0x53;                           //設(shè)定SPI為128分頻,慢速進行初始化
SPSR=0x00;

for (i=0;i<0x0f;i++)          
{
SPI_TransferByte(0xff); //延遲74個以上的時鐘
}

SD_Enable();                    //開片選

SPI_TransferByte(SD_RESET);    //發(fā)送復位命令
SPI_TransferByte(0x00);
SPI_TransferByte(0x00);
SPI_TransferByte(0x00);
SPI_TransferByte(0x00);
SPI_TransferByte(0x95);          

SPI_TransferByte(0xff);
SPI_TransferByte(0xff);

retry=0;
do{
temp="Write"_Command_SD(SD_INIT,0);      //發(fā)送初始化命令
retry++;
if(retry==100)                             //重試100次
{
SD_Disable();                     //關(guān)片選

return(INIT_CMD1_ERROR);      //如果重試100次失敗返回錯誤號

}
}while(temp!=0);                            

MSD_Disable();                                  //關(guān)片選

SPCR=0x50;                                        //設(shè)置SPI為2分頻。進行高速讀寫
SPSR=0x01;

return(TRUE);                                  //返回成功
}

//****************************************************************************
// 發(fā)送命令給 MMC/SD卡
//Return: 返回MMC/SD卡對命令響應(yīng)的第2字節(jié),作為命令成功判斷
unsigned char Write_Command_SD(unsigned char cmd,unsigned long address)
//****************************************************************************
{
unsigned char tmp;
unsigned char retry="0";

SD_Disable();
SPI_TransferByte(0xFF);

SD_Enable();

SPI_TransferByte(cmd);                     //將32位地址進行移位作為地址字節(jié)                                    
SPI_TransferByte(address>>24);
SPI_TransferByte(address>>16);
SPI_TransferByte(address>>8);
SPI_TransferByte(address);
SPI_TransferByte(0xFF);

SPI_TransferByte(0xFF);

do{
tmp = SPI_TransferByte(0xFF);    //發(fā)送8個時鐘接受最后一個字節(jié)                                                                  
retry++;
}while((tmp==0xff)&&(retry<8));
return(tmp);

}


//****************************************************************************
// 寫一個扇區(qū)(512Byte) to MMC/SD-Card
//如果寫完成返回TRUE
unsigned char SD_write_sector(unsigned long addr,unsigned char *Buffer)
//****************************************************************************
{
unsigned char temp;
unsigned int i;

SPI_TransferByte(0xFF);                                    //延遲8個時鐘            
SD_Enable();                                            //開片選

temp = Write_Command_MMC(MMC_WRITE_BLOCK,addr<<9);        //發(fā)送寫扇區(qū)命令
if(temp != 0x00)
{
SD_Disable();
return(temp);
}

SPI_TransferByte(0xFF);
SPI_TransferByte(0xFF);
SPI_TransferByte(0xFE);

for (i=0;i<512;i++)
{
SPI_TransferByte(*Buffer++); //發(fā)送512字節(jié)數(shù)據(jù)
}

//CRC-Byte
SPI_TransferByte(0xFF); //Dummy CRC
SPI_TransferByte(0xFF); //CRC Code

temp = SPI_TransferByte(0xFF);   //讀SD卡運行響應(yīng)
if((temp & 0x1F)!=0x05)             //如果最后4位為0101,為操作成功。否則為操作失敗。
{
SD_Disable();

return(WRITE_BLOCK_ERROR); //返回錯誤
}

while (SPI_TransferByte(0xFF) != 0xFF);

SD_Disable();
return(TRUE);                            //返回成功
}
//****************************************************************************
// 讀512字節(jié) from MMC/SD-Card
//如果成功返回TRUE
unsigned char SD_read_sector(unsigned long addr,unsigned char *Buffer)
//****************************************************************************
{
unsigned char temp;
unsigned int i;
unsigned char data;



SPI_TransferByte(0xff);                                                

MMC_Enable();

temp = Write_Command_SD(SD_READ_BLOCK,addr<<9);//發(fā)送讀扇區(qū)命令

if(temp != 0x00)
{
SD_Disable();

return(READ_BLOCK_ERROR);                //返回錯誤號               
}

while(SPI_TransferByte(0xff) != 0xfe);


for(i=0;i<512;i++)
{
data = SPI_TransferByte(0xff);        //存數(shù)據(jù)

*Buffer++=data;


}

SPI_TransferByte(0xff);                        //讀CRC碼
SPI_TransferByte(0xff);                        //讀CRC碼

SD_Disable();

return(TRUE);                                    //返回成功
}
//**************************************************************************
// 查找數(shù)據(jù)開始標志(預設(shè)DATASTART)根據(jù)實際需要刪改
//**************************************************************************
unsigned long SD_find(void)                      
{    
unsigned long tmp="400";
unsigned char data[512];

do
{
SD_read_sector(tmp,data);                    //從0扇區(qū)開始查找
tmp++;                                        //查找DATASTART      

}while(!((data[0]=='D')&&(data[1]=='A')&&(data[2]=='T')&&(data[3]=='A')&&(data[4]=='S')&&(data[5]=='T')&&(data[6]=='A')&&(data[7]=='R')&&(data[8]=='T')));
return tmp;                                    //返回開始標志的下一個扇區(qū)
}    
//**************************************************************************
// 發(fā)送一個字節(jié)
//**************************************************************************
unsigned char SPI_TransferByte(unsigned char byte)
{
SPDR = byte;
while (!(SPSR & 0x80));                               //檢測線路是否空閑                      
return SPDR;
}

//**************************************************************************
// 主程序例子
//**************************************************************************
void main(void)
{   
unsigned long temp;
unsigned char data[512];
unsigned char data2[512]={'sssssssssssssssssssssssss'};
unsigned char comm1[]={'\r\nhello world\r\n'};
unsigned char comm2[]={'\r\nSD_INIT OK\r\n'};
uart0_init();
SD_Port_Init();                     //端口初始化
if(SD_Init()== 0x01)
{                                      //SD卡初始化,并讀取返回值
putstr(comm2);
}
temp="SD"_find();                      //查找DATASTART數(shù)據(jù)開始標志,返回下一扇區(qū)地址
SD_read_sector(1001,data);             //讀取temp地址的512字節(jié)數(shù)據(jù),512字節(jié)數(shù)據(jù)存入data數(shù)組
putstr(data);               
SD_write_sector(temp,data2);         //將data2數(shù)組512字節(jié)數(shù)據(jù)寫入temp扇區(qū)
}

測試程序很簡單,僅僅是做了一下讀寫SD卡的測試。

關(guān)于SD卡的幾點注意事項。
1、無論我們愿意不愿意,SD卡每次讀寫數(shù)據(jù)的最小單位是1個扇區(qū),即512個字節(jié)。
2、SD卡與單片機連接的 SPI總線不能太長,要盡量短。這樣的好處是速度可以更快,也不容易出錯。
3、雖然我們并不關(guān)心FAT文件表,但是我們?nèi)匀灰P(guān)心SD卡的存儲結(jié)構(gòu),如果我們不想使用PC機來讀取保存在SD卡上的數(shù)據(jù)那我們就不用關(guān)心SD存儲結(jié)構(gòu)了。但,作為一個大容量的可移動存儲設(shè)備,不能用PC機來讀取是個很大的遺憾,我解決這個遺憾的方法如下:
3-1、因為我不了解FAT復雜的結(jié)構(gòu),所以我做的程序沒法去按照FAT表的各項功能來進行創(chuàng)建文件、刪除文件、創(chuàng)建目錄等等操作。
3-2、雖然我們的單片機不能創(chuàng)建文件,但是PC機是可以創(chuàng)建文件的??!所以我使用PC機將SD卡格式化,之后在SD卡上創(chuàng)建一個大文件,比如我的128M的SD卡上我建立了一個100M的文件。這里需要注意一下,一般使用windows創(chuàng)建文件的功能時是沒有辦法指定創(chuàng)建文件的大小的,空文件就是0個字節(jié)的長度,而我們是需要一個固定長度的文件的,所以我用VC編寫了一個小軟件,這個軟件可以為我創(chuàng)建一個100M長度的空文件,記住,這點很重要:一個固定長度的空文件
3-3、雖然我們建立了個文件在SD卡上,可是我們因為不去了解FAT表,所以我們一樣不知道這個文件到底位于SD卡的什么地方,不要以為它會在0字節(jié)的地方開始,為了找到這個文件的開始位置,我們可以在建立的那個空文件的開頭寫上幾個字符,比如我程序里面寫的“DATASTART”,接下來我們要做的就是一個扇區(qū)一個扇區(qū)的去找這個幾個特殊的字符,這是個笨方法,但卻是最簡單直觀的方法。這個方法有兩個缺點:a、如果文件建立在整個SD卡的后面,那找到這個文件需要漫長的等待。b、如果碰巧某個文件里面也有我們定義的那個特殊字符串的話,那就亂套了!不過好在我們使用的SD卡一般都是專用的,并不能拿去做其他應(yīng)用,比如從公司copy點文件回家之類的,那就能保證這個SD卡上文件的簡單性,即只有我們需要的那個文件,其他文件并不存在,而且這個文件肯定會從SD卡開始的那些扇區(qū)中的某一個開始。這樣說來的話找到這個字符串也不是那么慢嘛!^_^。不過這里要建議一下,在使用SD卡之前最好用windows將它完全格式話一下。
3-4、一旦我們找到了我們要寫入文件的起始位置(它一般表示為一個扇區(qū)號),那我們就可以在這個起始扇區(qū)的下一個扇區(qū)寫入數(shù)據(jù)了。
4、OK,看起來很簡單!有了這種存儲方式我們還需要IIC接口的 EEPROM干嗎呢?
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
基于AT89C52單片機的SD卡讀寫設(shè)計
ATMEGA128相關(guān)例程
MMC卡讀寫C代碼
nRF905
單片機讀寫SD卡最簡單最基本的程序
【青風帶你學stm32f051系列教程】第13課 通過SPI讀寫SD卡 | 愛板網(wǎng)
更多類似文章 >>
生活服務(wù)
熱點新聞
分享 收藏 導長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服