新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 51單片機實現對SD卡的讀寫

        51單片機實現對SD卡的讀寫

        作者: 時間:2016-11-25 來源:網絡 收藏

        4)讀取CSD
        CSD(Card-Specific Data)寄存器提供了讀寫SD卡的一些信息。其中的一些單元可以由用戶重新編程。具體的CSD結構如下:

        本文引用地址:http://www.104case.com/article/201611/321134.htm

        名稱
        數據寬度
        單元類型
        CSD劃分
        CSD結構
        CSD_STRUCTURE
        2
        R
        [127:126]
        保留
        -
        6
        R
        [125:120]
        數據讀取時間1
        TAAC
        8
        R
        [119:112]
        數據在CLK周期內讀取時間2(NSAC*100)
        NSAC
        8
        R
        [111:104]
        最大數據傳輸率
        TRAN_SPEED
        8
        R
        [103:96]
        卡命令集合
        CCC
        12
        R
        [95:84]
        最大讀取數據塊長
        READ_BL_LEN
        4
        R
        [83:80]
        允許讀的部分塊
        READ_BL_PARTIAL
        1
        R
        [79:79]
        非線寫塊
        WRITE_BLK_MISALIGN
        1
        R
        [78:78]
        非線讀塊
        READ_BLK_MISALIGN
        1
        R
        [77:77]
        DSR條件
        DSR_IMP
        1
        R
        [76:76]
        保留
        -
        2
        R
        [75:74]
        設備容量
        C_SIZE
        12
        R
        [73:62]
        最大讀取電流@VDDmin
        VDD_R_CURR_MIN
        3
        R
        [61:59]
        最大讀取電流@VDDmax
        VDD_R_CURR_MAX
        3
        R
        [58:56]
        最大寫電流@VDDmin
        VDD_W_CURR_MIN
        3
        R
        [55:53]
        最大寫電流@VDDmax
        VDD_W_CURR_MAX
        3
        R
        [52:50]
        設備容量乘子
        C_SIZE_MULT
        3
        R
        [49:47]
        擦除單塊使能
        ERASE_BLK_EN
        1
        R
        [46:46]
        擦除扇區大小
        SECTOR_SIZE
        7
        R
        [45:39]
        寫保護群大小
        WP_GRP_SIZE
        7
        R
        [38:32]
        寫保護群使能
        WP_GRP_ENABLE
        1
        R
        [31:31]
        保留
        -
        2
        R
        [30:29]
        寫速度因子
        R2W_FACTOR
        3
        R
        [28:26]
        最大寫數據塊長度
        WRITE_BL_LEN
        4
        R
        [25:22]
        允許寫的部分部
        WRITE_BL_PARTIAL
        1
        R
        [21:21]
        保留
        -
        5
        R
        [20:16]
        文件系統群
        FILE_OFRMAT_GRP
        1
        R/W
        [15:15]
        拷貝標志
        COPY
        1
        R/W
        [14:14]
        永久寫保護
        PERM_WRITE_PROTECT
        1
        R/W
        [13:13]
        暫時寫保護
        TMP_WRITE_PROTECT
        1
        R/W
        [12:12]
        文件系統
        FIL_FORMAT
        2
        R/W
        [11:10]
        保留
        -
        2
        R/W
        [9:8]
        CRC
        CRC
        7
        R/W
        [7:1]
        未用,始終為1
        -
        1
        [0:0]

        讀取CSD 的時序:

        相應的程序例程如下:

        1. //-----------------------------------------------------------------------------------------
        2. 讀SD卡的CSD寄存器共16字節返回0說明讀取成功
        3. //-----------------------------------------------------------------------------------------
        4. unsignedcharRead_CSD_SD(unsignedchar*Buffer)
        5. {
        6. //讀取CSD寄存器的命令
        7. unsignedcharCMD[]={0x49,0x00,0x00,0x00,0x00,0xFF};
        8. unsignedchartemp;
        9. temp=SD_Read_Block(CMD,Buffer,16);//read16bytes
        10. return(temp);
        11. }

        4)讀取SD卡信息
        綜合上面對CID與CSD寄存器的讀取,可以知道很多關于SD卡的信息,以下程序可以獲取這些信息。如下:

        1. //-----------------------------------------------------------------------------------------------
        2. //返回
        3. //SD卡的容量,單位為M
        4. //sectorcountandmultiplierMBarein
        5. u08==C_SIZE/(2^(9-C_SIZE_MULT))
        6. //SD卡的名稱
        7. //-----------------------------------------------------------------------------------------------
        8. voidSD_get_volume_info()
        9. {
        10. unsignedchari;
        11. unsignedcharc_temp[5];
        12. VOLUME_INFO_TYPESD_volume_Info,*vinf;
        13. vinf=&SD_volume_Info;//Initthepointoer;
        14. /讀取CSD寄存器
        15. Read_CSD_SD(sectorBuffer.dat);
        16. //獲取總扇區數
        17. vinf->sector_count=sectorBuffer.dat[6]&0x03;
        18. vinf->sector_count<<=8;
        19. vinf->sector_count+=sectorBuffer.dat[7];
        20. vinf->sector_count<<=2;
        21. vinf->sector_count+=(sectorBuffer.dat[8]&0xc0)>>6;
        22. //獲取multiplier
        23. vinf->sector_multiply=sectorBuffer.dat[9]&0x03;
        24. vinf->sector_multiply<<=1;
        25. vinf->sector_multiply+=(sectorBuffer.dat[10]&0x80)>>7;
        26. //獲取SD卡的容量
        27. vinf->size_MB=vinf->sector_count>>(9-vinf->sector_multiply);
        28. //getthenameofthecard
        29. Read_CID_SD(sectorBuffer.dat);
        30. vinf->name[0]=sectorBuffer.dat[3];
        31. vinf->name[1]=sectorBuffer.dat[4];
        32. vinf->name[2]=sectorBuffer.dat[5];
        33. vinf->name[3]=sectorBuffer.dat[6];
        34. vinf->name[4]=sectorBuffer.dat[7];
        35. vinf->name[5]=0x00;//endflag
        36. }
        37. 以上程序將信息裝載到一個結構體中,這個結構體的定義如下:
        38. typedefstructSD_VOLUME_INFO
        39. {//SD/SDCardinfo
        40. unsignedintsize_MB;
        41. unsignedcharsector_multiply;
        42. unsignedintsector_count;
        43. unsignedcharname[6];
        44. }VOLUME_INFO_TYPE;

        5)扇區讀
        扇區讀是對SD卡驅動的目的之一。SD卡的每一個扇區中有512個字節,一次扇區讀操作將把某一個扇區內的512個字節全部讀出。過程很簡單,先寫入命令,在得到相應的回應后,開始數據讀取。
        扇區讀的時序:

        扇區讀的程序例程:

        1. unsignedcharSD_Read_Sector(unsignedlongsector,unsignedchar*buffer)
        2. {
        3. unsignedcharretry;
        4. //命令16
        5. unsignedcharCMD[]={0x51,0x00,0x00,0x00,0x00,0xFF};
        6. unsignedchartemp;
        7. //地址變換由邏輯塊地址轉為字節地址
        8. sector=sector<<9;//sector=sector*512
        9. CMD[1]=((sector&0xFF000000)>>24);
        10. CMD[2]=((sector&0x00FF0000)>>16);
        11. CMD[3]=((sector&0x0000FF00)>>8);
        12. //將命令16寫入SD卡
        13. retry=0;
        14. do
        15. {//為了保證寫入命令一共寫100次
        16. temp=Write_Command_MMC(CMD);
        17. retry++;
        18. if(retry==100)
        19. {
        20. return(READ_BLOCK_ERROR);//blockwriteError!
        21. }
        22. }
        23. while(temp!=0);
        24. //ReadStartByteformMMC/SD-Card(FEh/StartByte)
        25. //Nowdataisready,youcanreaditout.
        26. while(Read_Byte_MMC()!=0xfe);
        27. readPos=0;
        28. SD_get_data(512,buffer);//512字節被讀出到buffer中
        29. return0;
        30. }
        31. 其中SD_get_data函數如下:
        32. //----------------------------------------------------------------------------
        33. 獲取數據到buffer中
        34. //----------------------------------------------------------------------------
        35. voidSD_get_data(unsignedintBytes,unsignedchar*buffer)
        36. {
        37. unsignedintj;
        38. for(j=0;j
        39. *buffer++=Read_Byte_SD();
        40. }

        6)扇區寫
        扇區寫是SD卡驅動的另一目的。每次扇區寫操作將向SD卡的某個扇區中寫入512個字節。過程與扇區讀相似,只是數據的方向相反與寫入命令不同而已。
        扇區寫的時序:

        扇區寫的程序例程:

        1. //--------------------------------------------------------------------------------------------
        2. 寫512個字節到SD卡的某一個扇區中去返回0說明寫入成功
        3. //--------------------------------------------------------------------------------------------
        4. unsignedcharSD_write_sector(unsignedlongaddr,unsignedchar*Buffer)
        5. {
        6. unsignedchartmp,retry;
        7. unsignedinti;
        8. //命令24
        9. unsignedcharCMD[]={0x58,0x00,0x00,0x00,0x00,0xFF};
        10. addr=addr<<9;//addr=addr*512
        11. CMD[1]=((addr&0xFF000000)>>24);
        12. CMD[2]=((addr&0x00FF0000)>>16);
        13. CMD[3]=((addr&0x0000FF00)>>8);
        14. //寫命令24到SD卡中去
        15. retry=0;
        16. do
        17. {//為了可靠寫入,寫100次
        18. tmp=Write_Command_SD(CMD);
        19. retry++;
        20. if(retry==100)
        21. {
        22. return(tmp);//sendcommamdError!
        23. }
        24. }
        25. while(tmp!=0);
        26. //在寫之前先產生100個時鐘信號
        27. for(i=0;i<100;i++)
        28. {
        29. Read_Byte_SD();
        30. }
        31. //寫入開始字節
        32. Write_Byte_MMC(0xFE);
        33. //現在可以寫入512個字節
        34. for(i=0;i<512;i++)
        35. {
        36. Write_Byte_MMC(*Buffer++);
        37. }
        38. //CRC-Byte
        39. Write_Byte_MMC(0xFF);//DummyCRC
        40. Write_Byte_MMC(0xFF);//CRCCode
        41. tmp=Read_Byte_MMC();//readresponse
        42. if((tmp&0x1F)!=0x05)//寫入的512個字節是未被接受
        43. {
        44. SPI_CS=1;
        45. return(WRITE_BLOCK_ERROR);//Error!
        46. }
        47. //等到SD卡不忙為止
        48. //因為數據被接受后,SD卡在向儲存陣列中編程數據
        49. while(Read_Byte_MMC()!=0xff){};
        50. //禁止SD卡
        51. SPI_CS=1;
        52. return(0);//寫入成功
        53. }

        此上內容在筆者的實驗中都已調試通過。單片機采用STC89LE單片機(SD卡的初始化電壓為2.0V~3.6V,操作電壓為3.1V~3.5V, 因此不能用5V單片機,或進行分壓處理),工作于22.1184M的時鐘下,由于所采用的單片機中沒硬件SPI,采用軟件模擬SPI,因此讀寫速率都較 慢。如果要半SD卡應用于音頻、視頻等要求高速場合,則需要選用有硬件SPI的控制器,或使用SD模式,當然這就需要各位讀者對SD模式加以研究,有了 SPI模式的基礎,SD模式應該不是什么難事。



        上一頁 1 2 下一頁

        關鍵詞: 51單片機SD

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 佛冈县| 芒康县| 仁布县| 舒兰市| 泾阳县| 涞源县| 揭阳市| 赤水市| 偏关县| 盖州市| 营口市| 玉屏| 连南| 拜城县| 名山县| 荥阳市| 云阳县| 丰城市| 阿拉善盟| 寿阳县| 阜康市| 四川省| 睢宁县| 武定县| 双鸭山市| 香港| 汕尾市| 普兰店市| 治县。| 博客| 上饶县| 博白县| 东乡族自治县| 大渡口区| 诏安县| 新密市| 五河县| 湖口县| 大丰市| 会同县| 韶山市|