<li id="8g3ty"><tbody id="8g3ty"><th id="8g3ty"></th></tbody></li>
    <label id="8g3ty"><samp id="8g3ty"></samp></label>
  • <span id="8g3ty"></span>

    1. <center id="8g3ty"><optgroup id="8g3ty"></optgroup></center>
    2. <bdo id="8g3ty"><meter id="8g3ty"><bdo id="8g3ty"></bdo></meter></bdo><center id="8g3ty"><optgroup id="8g3ty"></optgroup></center>
      <label id="8g3ty"><samp id="8g3ty"></samp></label>

    3. 電子開(kāi)發(fā)網(wǎng)

      電子開(kāi)發(fā)網(wǎng)電子設(shè)計(jì) | 電子開(kāi)發(fā)網(wǎng)Rss 2.0 會(huì)員中心 會(huì)員注冊(cè)
      搜索: 您現(xiàn)在的位置: 電子開(kāi)發(fā)網(wǎng) >> 電子開(kāi)發(fā) >> 單片機(jī) >> 正文

      SD卡在單片機(jī)上的應(yīng)用

      作者:佚名    文章來(lái)源:本站原創(chuàng)    點(diǎn)擊數(shù):    更新時(shí)間:2011-5-30

      3) 讀取CID
      CID寄存器存儲(chǔ)了SD卡的標(biāo)識(shí)碼。每一個(gè)卡都有唯一的標(biāo)識(shí)碼。
      CID寄存器長(zhǎng)度為128位。它的寄存器結(jié)構(gòu)如下:

      名稱
      數(shù)據(jù)寬度
      CID劃分
      生產(chǎn)標(biāo)識(shí)號(hào)
      MID
      8
      [127:120]
      OEM/應(yīng)用標(biāo)識(shí)
      OID
      16
      [119:104]
      產(chǎn)品名稱
      PNM
      40
      [103:64]
      產(chǎn)品版本
      PRV
      8
      [63:56]
      產(chǎn)品序列號(hào)
      PSN
      32
      [55:24]
      保留
      4
      [23:20]
      生產(chǎn)日期
      MDT
      12
      [19:8]
      CRC7校驗(yàn)合
      CRC
      7
      [7:1]
      未使用,始終為1
      1
      [0:0]

      它的讀取時(shí)序如下:
        
              與此時(shí)序相對(duì)應(yīng)的程序如下:
      //------------------------------------------------------------------------------------
          讀取SD卡的CID寄存器   16字節(jié)   成功返回0
      //-------------------------------------------------------------------------------------
      unsigned char Read_CID_SD(unsigned char *Buffer)
      {
         //讀取CID寄存器的命令
         unsigned char CMD[] = {0x4A,0x00,0x00,0x00,0x00,0xFF};
         unsigned char temp;
         temp=SD_Read_Block(CMD,Buffer,16); //read 16 bytes
         return(temp);
      }

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

      名稱
      數(shù)據(jù)寬度
      單元類型
      CSD劃分
      CSD結(jié)構(gòu)
      CSD_STRUCTURE
      2
      R
      [127:126]
      保留
      -
      6
      R
      [125:120]
      數(shù)據(jù)讀取時(shí)間1
      TAAC
      8
      R
      [119:112]
      數(shù)據(jù)在CLK周期內(nèi)讀取時(shí)間2(NSAC*100)
      NSAC
      8
      R
      [111:104]
      最大數(shù)據(jù)傳輸率
      TRAN_SPEED
      8
      R
      [103:96]
      卡命令集合
      CCC
      12
      R
      [95:84]
      最大讀取數(shù)據(jù)塊長(zhǎng)
      READ_BL_LEN
      4
      R
      [83:80]
      允許讀的部分塊
      READ_BL_PARTIAL
      1
      R
      [79:79]
      非線寫(xiě)塊
      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]
      設(shè)備容量
      C_SIZE
      12
      R
      [73:62]
      最大讀取電流@VDD min
      VDD_R_CURR_MIN
      3
      R
      [61:59]
      最大讀取電流@VDD max
      VDD_R_CURR_MAX
      3
      R
      [58:56]
      最大寫(xiě)電流@VDD min
      VDD_W_CURR_MIN
      3
      R
      [55:53]
      最大寫(xiě)電流@VDD max
      VDD_W_CURR_MAX
      3
      R
      [52:50]
      設(shè)備容量乘子
      C_SIZE_MULT
      3
      R
      [49:47]
      擦除單塊使能
      ERASE_BLK_EN
      1
      R
      [46:46]
      擦除扇區(qū)大小
      SECTOR_SIZE
      7
      R
      [45:39]
      寫(xiě)保護(hù)群大小
      WP_GRP_SIZE
      7
      R
      [38:32]
      寫(xiě)保護(hù)群使能
      WP_GRP_ENABLE
      1
      R
      [31:31]
      保留
      -
      2
      R
      [30:29]
      寫(xiě)速度因子
      R2W_FACTOR
      3
      R
      [28:26]
      最大寫(xiě)數(shù)據(jù)塊長(zhǎng)度
      WRITE_BL_LEN
      4
      R
      [25:22]
      允許寫(xiě)的部分部
      WRITE_BL_PARTIAL
      1
      R
      [21:21]
      保留
      -
      5
      R
      [20:16]
      文件系統(tǒng)群
      FILE_OFRMAT_GRP
      1
      R/W
      [15:15]
      拷貝標(biāo)志
      COPY
      1
      R/W
      [14:14]
      永久寫(xiě)保護(hù)
      PERM_WRITE_PROTECT
      1
      R/W
      [13:13]
      暫時(shí)寫(xiě)保護(hù)
      TMP_WRITE_PROTECT
      1
      R/W
      [12:12]
      文件系統(tǒng)
      FIL_FORMAT
      2
      R/W
      [11:10]
      保留
      -
      2
      R/W
      [9:8]
      CRC
      CRC
      7
      R/W
      [7:1]
      未用,始終為1
      -
      1
       
      [0:0]

                 讀取CSD 的時(shí)序:
        
                 相應(yīng)的程序例程如下:
      //-----------------------------------------------------------------------------------------
          讀SD卡的CSD寄存器   共16字節(jié)    返回0說(shuō)明讀取成功
      //-----------------------------------------------------------------------------------------
      unsigned char Read_CSD_SD(unsigned char *Buffer)

         //讀取CSD寄存器的命令
         unsigned char CMD[] = {0x49,0x00,0x00,0x00,0x00,0xFF};
         unsigned char temp;
         temp=SD_Read_Block(CMD,Buffer,16); //read 16 bytes
         return(temp);
      }


      4) 讀取SD卡信息
      綜合上面對(duì)CID與CSD寄存器的讀取,可以知道很多關(guān)于SD卡的信息,以下程序可以獲取這些信息。如下:
      //-----------------------------------------------------------------------------------------------
      //返回
      //  SD卡的容量,單位為M
      //  sector count and multiplier MB are in
      u08 == C_SIZE / (2^(9-C_SIZE_MULT))
      //  SD卡的名稱
      //-----------------------------------------------------------------------------------------------
      void SD_get_volume_info()
      {  
          unsigned char i;
          unsigned char c_temp[5];
          VOLUME_INFO_TYPE SD_volume_Info,*vinf;
          vinf=&SD_volume_Info; //Init the pointoer;
      /讀取CSD寄存器
          Read_CSD_SD(sectorBuffer.dat);
      //獲取總扇區(qū)數(shù)
       vinf->sector_count = sectorBuffer.dat[6] & 0x03;
       vinf->sector_count <<= 8;
       vinf->sector_count += sectorBuffer.dat[7];
       vinf->sector_count <<= 2;
       vinf->sector_count += (sectorBuffer.dat[8] & 0xc0) >> 6;
       // 獲取multiplier
       vinf->sector_multiply = sectorBuffer.dat[9] & 0x03;
       vinf->sector_multiply <<= 1;
       vinf->sector_multiply += (sectorBuffer.dat[10] & 0x80) >> 7;
      //獲取SD卡的容量
       vinf->size_MB = vinf->sector_count >> (9-vinf->sector_multiply);
       // get the name of the card
       Read_CID_SD(sectorBuffer.dat);
       vinf->name[0] = sectorBuffer.dat[3];
       vinf->name[1] = sectorBuffer.dat[4];
       vinf->name[2] = sectorBuffer.dat[5];
       vinf->name[3] = sectorBuffer.dat[6];
       vinf->name[4] = sectorBuffer.dat[7];
       vinf->name[5] = 0x00; //end flag 
      }
               以上程序?qū)⑿畔⒀b載到一個(gè)結(jié)構(gòu)體中,這個(gè)結(jié)構(gòu)體的定義如下:
      typedef struct SD_VOLUME_INFO
      { //SD/SD Card info
        unsigned int  size_MB;
        unsigned char sector_multiply;
        unsigned int  sector_count;
        unsigned char name[6];
      } VOLUME_INFO_TYPE;

      5) 扇區(qū)讀
      扇區(qū)讀是對(duì)SD卡驅(qū)動(dòng)的目的之一。SD卡的每一個(gè)扇區(qū)中有512個(gè)字節(jié),一次扇區(qū)讀操作將把某一個(gè)扇區(qū)內(nèi)的512個(gè)字節(jié)全部讀出。過(guò)程很簡(jiǎn)單,先寫(xiě)入命令,在得到相應(yīng)的回應(yīng)后,開(kāi)始數(shù)據(jù)讀取。
      扇區(qū)讀的時(shí)序:
        
            扇區(qū)讀的程序例程:
      unsigned char SD_Read_Sector(unsigned long sector,unsigned char *buffer)

         unsigned char retry;
         //命令16
         unsigned char CMD[] = {0x51,0x00,0x00,0x00,0x00,0xFF};
         unsigned char temp;
        
         //地址變換   由邏輯塊地址轉(zhuǎn)為字節(jié)地址
         sector = sector << 9; //sector = sector * 512

         CMD[1] = ((sector & 0xFF000000) >>24 );
         CMD[2] = ((sector & 0x00FF0000) >>16 );
         CMD[3] = ((sector & 0x0000FF00) >>8 );

         //將命令16寫(xiě)入SD卡
         retry=0;
         do
         {  //為了保證寫(xiě)入命令  一共寫(xiě)100次
            temp=Write_Command_MMC(CMD);
            retry++;
            if(retry==100)
            {
              return(READ_BLOCK_ERROR); //block write Error!
            }
         }
         while(temp!=0);
            
         //Read Start Byte form MMC/SD-Card (FEh/Start Byte)
         //Now data is ready,you can read it out.
         while (Read_Byte_MMC() != 0xfe);
         readPos=0;
        SD_get_data(512,buffer) ;  //512字節(jié)被讀出到buffer中
       return 0;
      }
      其中SD_get_data函數(shù)如下:
      //----------------------------------------------------------------------------
          獲取數(shù)據(jù)到buffer中
      //----------------------------------------------------------------------------
      void SD_get_data(unsigned int Bytes,unsigned char *buffer)
      {
         unsigned int j;
         for (j=0;j<Bytes;j++)
            *buffer++ = Read_Byte_SD();
      }

      6) 扇區(qū)寫(xiě)
      扇區(qū)寫(xiě)是SD卡驅(qū)動(dòng)的另一目的。每次扇區(qū)寫(xiě)操作將向SD卡的某個(gè)扇區(qū)中寫(xiě)入512個(gè)字節(jié)。過(guò)程與扇區(qū)讀相似,只是數(shù)據(jù)的方向相反與寫(xiě)入命令不同而已。
          扇區(qū)寫(xiě)的時(shí)序:
       

      扇區(qū)寫(xiě)的程序例程:
      //--------------------------------------------------------------------------------------------
          寫(xiě)512個(gè)字節(jié)到SD卡的某一個(gè)扇區(qū)中去   返回0說(shuō)明寫(xiě)入成功
      //--------------------------------------------------------------------------------------------
      unsigned char SD_write_sector(unsigned long addr,unsigned char *Buffer)

         unsigned char tmp,retry;
         unsigned int i;
         //命令24
         unsigned char CMD[] = {0x58,0x00,0x00,0x00,0x00,0xFF};
         addr = addr << 9; //addr = addr * 512
       
         CMD[1] = ((addr & 0xFF000000) >>24 );
         CMD[2] = ((addr & 0x00FF0000) >>16 );
         CMD[3] = ((addr & 0x0000FF00) >>8 );

         //寫(xiě)命令24到SD卡中去
         retry=0;
         do
         {  //為了可靠寫(xiě)入,寫(xiě)100次
            tmp=Write_Command_SD(CMD);
            retry++;
            if(retry==100)
            {
              return(tmp); //send commamd Error!
            }
         }
         while(tmp!=0);
        

         //在寫(xiě)之前先產(chǎn)生100個(gè)時(shí)鐘信號(hào)
         for (i=0;i<100;i++)
         {
            Read_Byte_SD();
         }
       
         //寫(xiě)入開(kāi)始字節(jié)
         Write_Byte_MMC(0xFE); 
       
         //現(xiàn)在可以寫(xiě)入512個(gè)字節(jié)
         for (i=0;i<512;i++)
         {
            Write_Byte_MMC(*Buffer++);
         }

         //CRC-Byte
         Write_Byte_MMC(0xFF); //Dummy CRC
         Write_Byte_MMC(0xFF); //CRC Code
        
         
         tmp=Read_Byte_MMC();   // read response
         if((tmp & 0x1F)!=0x05) // 寫(xiě)入的512個(gè)字節(jié)是未被接受
         {
           SPI_CS=1;
           return(WRITE_BLOCK_ERROR); //Error!
         }
         //等到SD卡不忙為止
      //因?yàn)閿?shù)據(jù)被接受后,SD卡在向儲(chǔ)存陣列中編程數(shù)據(jù)
         while (Read_Byte_MMC()!=0xff){};
       
         //禁止SD卡
         SPI_CS=1;
         return(0);//寫(xiě)入成功
      }
      此上內(nèi)容在筆者的實(shí)驗(yàn)中都已調(diào)試通過(guò)。單片機(jī)采用STC89LE單片機(jī)(SD卡的初始化電壓為2.0V~3.6V,操作電壓為3.1V~3.5V,因此不能用5V單片機(jī),或進(jìn)行分壓處理),工作于22.1184M的時(shí)鐘下,由于所采用的單片機(jī)中沒(méi)硬件SPI,采用軟件模擬SPI,因此讀寫(xiě)速率都較慢。如果要半SD卡應(yīng)用于音頻、視頻等要求高速場(chǎng)合,則需要選用有硬件SPI的控制器,或使用SD模式,當(dāng)然這就需要各位讀者對(duì)SD模式加以研究,有了SPI模式的基礎(chǔ),SD模式應(yīng)該不是什么難事。
       

      上一頁(yè)  [1] [2] 

      Tags:SD卡,單片機(jī),應(yīng)用  
      責(zé)任編輯:admin
      請(qǐng)文明參與討論,禁止漫罵攻擊,不要惡意評(píng)論、違禁詞語(yǔ)。 昵稱:
      1分 2分 3分 4分 5分

      還可以輸入 200 個(gè)字
      [ 查看全部 ] 網(wǎng)友評(píng)論
      關(guān)于我們 - 聯(lián)系我們 - 廣告服務(wù) - 友情鏈接 - 網(wǎng)站地圖 - 版權(quán)聲明 - 在線幫助 - 文章列表
      返回頂部
      刷新頁(yè)面
      下到頁(yè)底
      晶體管查詢
      主站蜘蛛池模板: 久久综合视频网站| 亚洲综合色7777情网站777| 国产91色综合久久免费分享| 天天在线天天综合网色| 亚洲乱码中文字幕小综合| 丁香五月网久久综合| 久久综合狠狠综合久久综合88| 色综合久久无码五十路人妻| 日韩亚洲综合精品国产| 日韩欧国产精品一区综合无码| 国产成人综合在线视频| 久久88色综合色鬼| 狠狠色综合网站久久久久久久| 狠狠色丁香婷婷久久综合五月| 国产激情电影综合在线看| 色欲人妻综合AAAAAAAA网| 亚洲国产综合自在线另类| 亚洲综合国产精品第一页| 色天使亚洲综合一区二区| 久久婷婷五月综合国产尤物app| 亚洲国产免费综合| 五月天婷五月天综合网在线| 亚洲狠狠婷婷综合久久蜜芽| 亚洲人成在久久综合网站| 伊人久久大香线蕉综合Av| 五月天婷亚洲天综合网精品偷| 色婷婷天天综合在线| 伊人丁香狠狠色综合久久| 久久久久青草大香线综合精品| 激情综合婷婷丁香五月蜜桃| 亚洲综合精品网站| 日本一道综合色视频| 人人狠狠综合久久88成人| 亚洲狠狠久久综合一区77777| 色综合久久无码中文字幕| 色综合色天天久久婷婷基地| 久久乐国产综合亚洲精品| 伊人伊成久久人综合网777| 丁香六月婷婷综合| 久久综合亚洲色一区二区三区| 色欲综合久久躁天天躁蜜桃|