SPI SD卡 FATFS

2019-08-14 02:14发布

#include "sys.h"
#include "mmc_sd.h"               
#include "spi.h"
#include "usart.h"   
//////////////////////////////////////////////////////////////////////////////////     
//±¾³ÌÐòÖ»¹©Ñ§Ï°Ê¹Óã¬Î´¾­×÷ÕßÐí¿É£¬²»µÃÓÃÓÚÆäËüÈκÎÓÃ;
//ALIENTEK MiniSTM32¿ª·¢°å
//SD¿¨ Çý¶¯´úÂë      
//ÕýµãÔ­×Ó@ALIENTEK
//¼¼ÊõÂÛ̳:www.openedv.com
//ÐÞ¸ÄÈÕÆÚ:2014/3/13
//°æ±¾£ºV1.0
//°æȨËùÓУ¬µÁ°æ±Ø¾¿¡£
//Copyright(C) ¹ãÖÝÊÐÐÇÒíµç×ӿƼ¼ÓÐÏÞ¹«Ë¾ 2009-2019
//All rights reserved                                      
//////////////////////////////////////////////////////////////////////////////////
                       
u8  SD_Type=0;//SD¿¨µÄÀàÐÍ
////////////////////////////////////ÒÆÖ²ÐÞ¸ÄÇø///////////////////////////////////
//ÒÆֲʱºòµÄ½Ó¿Ú
//data:ҪдÈëµÄÊý¾Ý
//·µ»ØÖµ:¶Áµ½µÄÊý¾Ý
u8 SD_SPI_ReadWriteByte(u8 data)
{
    return SPI2_ReadWriteByte(data);
}      
//SD¿¨³õʼ»¯µÄʱºò,ÐèÒªµÍËÙ
void SD_SPI_SpeedLow(void)
{
     SPI2_SetSpeed(SPI_BaudRatePrescaler_256);//ÉèÖõ½µÍËÙģʽ   
}
//SD¿¨Õý³£¹¤×÷µÄʱºò,¿ÉÒÔ¸ßËÙÁË
void SD_SPI_SpeedHigh(void)
{
     SPI2_SetSpeed(SPI_BaudRatePrescaler_2);//ÉèÖõ½¸ßËÙģʽ   
}
//SPIÓ²¼þ²ã³õʼ»¯
void SD_SPI_Init(void)
{
  //ÉèÖÃÓ²¼þÉÏÓëSD¿¨Ïà¹ØÁªµÄ¿ØÖÆÒý½ÅÊä³ö
    //½ûÖ¹ÆäËûÍâÉè(NRF/W25Q64)¶ÔSD¿¨²úÉúÓ°Ïì
GPIO_InitTypeDef  GPIO_InitStructure;

     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOG, ENABLE);     //ʹÄ&#220B¶Ë¿ÚʱÖÓ

    //ÉèÖÃÓ²¼þÉÏÓëSD¿¨Ïà¹ØÁªµÄ¿ØÖÆÒý½ÅÊä³ö
    //±ÜÃâNRF24L01/W25Q32µÈµÄÓ°Ïì
    //ÕâÀ&#239B12º&#205G7À­¸ß,ÊÇΪÁË·ÀÖ¹Ó°ÏìFLASHµÄÉÕд.
    //ÒòΪËûÃǹ²ÓÃÒ»¸öSPI¿Ú.

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;                 //PB12 ÍÆÍì
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;          //ÍÆÍìÊä³ö
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_Init(GPIOB, &GPIO_InitStructure);
     GPIO_SetBits(GPIOB,GPIO_Pin_12);                         //PB12ÉÏÀ­
   
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;                 //PD2 ÍÆÍì
    GPIO_Init(GPIOD, &GPIO_InitStructure);
    GPIO_SetBits(GPIOD,GPIO_Pin_2);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;                 //PG7 ÍÆÍì
    GPIO_Init(GPIOG, &GPIO_InitStructure);
    GPIO_SetBits(GPIOG,GPIO_Pin_7);

  SPI2_Init();
    SD_CS=1;
}
///////////////////////////////////////////////////////////////////////////////////
//È¡ÏûÑ¡Ôñ,ÊÍ·ÅSPI×ÜÏß
void SD_DisSelect(void)
{
    SD_CS=1;
     SD_SPI_ReadWriteByte(0xff);//Ìṩ¶îÍâµÄ8¸öʱÖÓ
}
//Ñ¡Ôñsd¿¨,²¢Çҵȴý¿¨×¼±¸OK
//·µ»ØÖµ:0,³É¹¦;1,ʧ°Ü;
u8 SD_Select(void)
{
    SD_CS=0;
    if(SD_WaitReady()==0)return 0;//µÈ´ý³É¹¦
    SD_DisSelect();
    return 1;//µÈ´ýʧ°Ü
}
//µÈ´ý¿¨×¼±¸ºÃ
//·µ»ØÖµ:0,×¼±¸ºÃÁË;ÆäËû,´íÎó´úÂë
u8 SD_WaitReady(void)
{
    u32 t=0;
    do
    {
        if(SD_SPI_ReadWriteByte(0XFF)==0XFF)return 0;//OK
        t++;              
    }while(t<0XFFFFFF);//&#181;&#200;&#180;&#253;
    return 1;
}
//&#181;&#200;&#180;&#253;SD&#191;¨&#187;&#216;&#211;&#166;
//Response:&#210;&#170;&#181;&#195;&#181;&#189;&#181;&#196;&#187;&#216;&#211;&#166;&#214;&#181;
//·&#181;&#187;&#216;&#214;&#181;:0,&#179;&#201;&#185;&#166;&#181;&#195;&#181;&#189;&#193;&#203;&#184;&#195;&#187;&#216;&#211;&#166;&#214;&#181;
//    &#198;&#228;&#203;&#251;,&#181;&#195;&#181;&#189;&#187;&#216;&#211;&#166;&#214;&#181;&#202;§°&#220;
u8 SD_GetResponse(u8 Response)
{
    u16 Count=0xFFFF;//&#181;&#200;&#180;&#253;&#180;&#206;&#202;&#253;                                 
    while ((SD_SPI_ReadWriteByte(0XFF)!=Response)&&Count)Count--;//&#181;&#200;&#180;&#253;&#181;&#195;&#181;&#189;×&#188;&#200;·&#181;&#196;&#187;&#216;&#211;&#166;        
    if (Count==0)return MSD_RESPONSE_FAILURE;//&#181;&#195;&#181;&#189;&#187;&#216;&#211;&#166;&#202;§°&#220;   
    else return MSD_RESPONSE_NO_ERROR;//&#213;&#253;&#200;·&#187;&#216;&#211;&#166;
}
//&#180;&#211;sd&#191;¨&#182;&#193;&#200;&#161;&#210;&#187;&#184;&#246;&#202;&#253;&#190;&#221;°ü&#181;&#196;&#196;&#218;&#200;&#221;
//buf:&#202;&#253;&#190;&#221;&#187;&#186;&#180;&#230;&#199;&#248;
//len:&#210;&#170;&#182;&#193;&#200;&#161;&#181;&#196;&#202;&#253;&#190;&#221;&#179;¤&#182;&#200;.
//·&#181;&#187;&#216;&#214;&#181;:0,&#179;&#201;&#185;&#166;;&#198;&#228;&#203;&#251;,&#202;§°&#220;;   
u8 SD_RecvData(u8*buf,u16 len)
{                    
    if(SD_GetResponse(0xFE))return 1;//&#181;&#200;&#180;&#253;SD&#191;¨·&#162;&#187;&#216;&#202;&#253;&#190;&#221;&#198;&#240;&#202;&#188;&#193;&#238;&#197;&#198;0xFE
    while(len--)//&#191;&#170;&#202;&#188;&#189;&#211;&#202;&#213;&#202;&#253;&#190;&#221;
    {
        *buf=SPI2_ReadWriteByte(0xFF);
        buf++;
    }
    //&#207;&#194;&#195;&#230;&#202;&#199;2&#184;&#246;&#206;±CRC&#163;¨dummy CRC&#163;&#169;
    SD_SPI_ReadWriteByte(0xFF);
    SD_SPI_ReadWriteByte(0xFF);                                                              
    return 0;//&#182;&#193;&#200;&#161;&#179;&#201;&#185;&#166;
}
//&#207;òsd&#191;¨&#208;&#180;&#200;&#235;&#210;&#187;&#184;&#246;&#202;&#253;&#190;&#221;°ü&#181;&#196;&#196;&#218;&#200;&#221; 512×&#214;&#189;&#218;
//buf:&#202;&#253;&#190;&#221;&#187;&#186;&#180;&#230;&#199;&#248;
//cmd:&#214;&#184;&#193;&#238;
//·&#181;&#187;&#216;&#214;&#181;:0,&#179;&#201;&#185;&#166;;&#198;&#228;&#203;&#251;,&#202;§°&#220;;   
u8 SD_SendBlock(u8*buf,u8 cmd)
{   
    u16 t;               
    if(SD_WaitReady())return 1;//&#181;&#200;&#180;&#253;×&#188;±&#184;&#202;§&#208;§
    SD_SPI_ReadWriteByte(cmd);
    if(cmd!=0XFD)//&#178;&#187;&#202;&#199;&#189;á&#202;&#248;&#214;&#184;&#193;&#238;
    {
        for(t=0;t<512;t++)SPI2_ReadWriteByte(buf[t]);//&#204;á&#184;&#223;&#203;&#217;&#182;&#200;,&#188;&#245;&#201;&#217;&#186;&#175;&#202;&#253;&#180;&#171;&#178;&#206;&#202;±&#188;&#228;
        SD_SPI_ReadWriteByte(0xFF);//&#186;&#246;&#194;&#212;crc
        SD_SPI_ReadWriteByte(0xFF);
        t=SD_SPI_ReadWriteByte(0xFF);//&#189;&#211;&#202;&#213;&#207;ì&#211;&#166;
        if((t&0x1F)!=0x05)return 2;//&#207;ì&#211;&#166;&#180;í&#206;ó                                                              
    }                                                                                       
    return 0;//&#208;&#180;&#200;&#235;&#179;&#201;&#185;&#166;
}

//&#207;òSD&#191;¨·&#162;&#203;&#205;&#210;&#187;&#184;&#246;&#195;ü&#193;&#238;
//&#202;&#228;&#200;&#235;: u8 cmd   &#195;ü&#193;&#238;
//      u32 arg  &#195;ü&#193;&#238;&#178;&#206;&#202;&#253;
//      u8 crc   crc&#208;&#163;&#209;é&#214;&#181;      
//·&#181;&#187;&#216;&#214;&#181;:SD&#191;¨·&#181;&#187;&#216;&#181;&#196;&#207;ì&#211;&#166;                                                              
u8 SD_SendCmd(u8 cmd, u32 arg, u8 crc)
{
    u8 r1;   
    u8 Retry=0;
    SD_DisSelect();//&#200;&#161;&#207;&#251;&#201;&#207;&#180;&#206;&#198;&#172;&#209;&#161;
    if(SD_Select())return 0XFF;//&#198;&#172;&#209;&#161;&#202;§&#208;§
    //·&#162;&#203;&#205;
    SD_SPI_ReadWriteByte(cmd | 0x40);//·&#214;±&#240;&#208;&#180;&#200;&#235;&#195;ü&#193;&#238;
    SD_SPI_ReadWriteByte(arg >> 24);
    SD_SPI_ReadWriteByte(arg >> 16);
    SD_SPI_ReadWriteByte(arg >> 8);
    SD_SPI_ReadWriteByte(arg);      
    SD_SPI_ReadWriteByte(crc);
    if(cmd==CMD12)SD_SPI_ReadWriteByte(0xff);//Skip a stuff byte when stop reading
    //&#181;&#200;&#180;&#253;&#207;ì&#211;&#166;&#163;&#172;&#187;ò&#179;&#172;&#202;±&#205;&#203;&#179;&#246;
    Retry=0X1F;
    do
    {
        r1=SD_SPI_ReadWriteByte(0xFF);
    }while((r1&0X80) && Retry--);     
    //·&#181;&#187;&#216;×&#180;&#204;&#172;&#214;&#181;
    return r1;
}                                                                                          
//&#187;&#241;&#200;&#161;SD&#191;¨&#181;&#196;CID&#208;&#197;&#207;&#162;&#163;&#172;°ü&#192;¨&#214;&#198;&#212;ì&#201;&#204;&#208;&#197;&#207;&#162;
//&#202;&#228;&#200;&#235;: u8 *cid_data(&#180;&#230;·&#197;CID&#181;&#196;&#196;&#218;&#180;&#230;&#163;&#172;&#214;&#193;&#201;&#217;16Byte&#163;&#169;      
//·&#181;&#187;&#216;&#214;&#181;:0&#163;&#186;NO_ERR
//         1&#163;&#186;&#180;í&#206;ó                                                           
u8 SD_GetCID(u8 *cid_data)
{
    u8 r1;      
    //·&#162;CMD10&#195;ü&#193;&#238;&#163;&#172;&#182;&#193;CID
    r1=SD_SendCmd(CMD10,0,0x01);
    if(r1==0x00)
    {
        r1=SD_RecvData(cid_data,16);//&#189;&#211;&#202;&#213;16&#184;&#246;×&#214;&#189;&#218;&#181;&#196;&#202;&#253;&#190;&#221;     
    }
    SD_DisSelect();//&#200;&#161;&#207;&#251;&#198;&#172;&#209;&#161;
    if(r1)return 1;
    else return 0;
}                                                                                 
//&#187;&#241;&#200;&#161;SD&#191;¨&#181;&#196;CSD&#208;&#197;&#207;&#162;&#163;&#172;°ü&#192;¨&#200;&#221;&#193;&#191;&#186;&#205;&#203;&#217;&#182;&#200;&#208;&#197;&#207;&#162;
//&#202;&#228;&#200;&#235;:u8 *cid_data(&#180;&#230;·&#197;CID&#181;&#196;&#196;&#218;&#180;&#230;&#163;&#172;&#214;&#193;&#201;&#217;16Byte&#163;&#169;        
//·&#181;&#187;&#216;&#214;&#181;:0&#163;&#186;NO_ERR
//         1&#163;&#186;&#180;í&#206;ó                                                           
u8 SD_GetCSD(u8 *csd_data)
{
    u8 r1;     
    r1=SD_SendCmd(CMD9,0,0x01);//·&#162;CMD9&#195;ü&#193;&#238;&#163;&#172;&#182;&#193;CSD
    if(r1==0)
    {
        r1=SD_RecvData(csd_data, 16);//&#189;&#211;&#202;&#213;16&#184;&#246;×&#214;&#189;&#218;&#181;&#196;&#202;&#253;&#190;&#221;
    }
    SD_DisSelect();//&#200;&#161;&#207;&#251;&#198;&#172;&#209;&#161;
    if(r1)return 1;
    else return 0;
}  
//&#187;&#241;&#200;&#161;SD&#191;¨&#181;&#196;×&#220;&#201;&#200;&#199;&#248;&#202;&#253;&#163;¨&#201;&#200;&#199;&#248;&#202;&#253;&#163;&#169;   
//·&#181;&#187;&#216;&#214;&#181;:0&#163;&#186; &#200;&#161;&#200;&#221;&#193;&#191;&#179;&#246;&#180;í
//       &#198;&#228;&#203;&#251;:SD&#191;¨&#181;&#196;&#200;&#221;&#193;&#191;(&#201;&#200;&#199;&#248;&#202;&#253;/512×&#214;&#189;&#218;)
//&#195;&#191;&#201;&#200;&#199;&#248;&#181;&#196;×&#214;&#189;&#218;&#202;&#253;±&#216;&#206;&#170;512&#163;&#172;&#210;ò&#206;&#170;&#200;&#231;&#185;&#251;&#178;&#187;&#202;&#199;512&#163;&#172;&#212;ò&#179;&#245;&#202;&#188;&#187;&#175;&#178;&#187;&#196;&#220;&#205;¨&#185;&#253;.                                                         
u32 SD_GetSectorCount(void)
{
    u8 csd[16];
    u32 Capacity;  
    u8 n;
    u16 csize;                          
    //&#200;&#161;CSD&#208;&#197;&#207;&#162;&#163;&#172;&#200;&#231;&#185;&#251;&#198;&#218;&#188;&#228;&#179;&#246;&#180;í&#163;&#172;·&#181;&#187;&#216;0
    if(SD_GetCSD(csd)!=0) return 0;        
    //&#200;&#231;&#185;&#251;&#206;&#170;SDHC&#191;¨&#163;&#172;°&#180;&#213;&#213;&#207;&#194;&#195;&#230;·&#189;&#202;&#189;&#188;&#198;&#203;&#227;
    if((csd[0]&0xC0)==0x40)     //V2.00&#181;&#196;&#191;¨
    {   
        csize = csd[9] + ((u16)csd[8] << 8) + 1;
        Capacity = (u32)csize << 10;//&#181;&#195;&#181;&#189;&#201;&#200;&#199;&#248;&#202;&#253;               
    }else//V1.XX&#181;&#196;&#191;¨
    {   
        n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
        csize = (csd[8] >> 6) + ((u16)csd[7] << 2) + ((u16)(csd[6] & 3) << 10) + 1;
        Capacity= (u32)csize << (n - 9);//&#181;&#195;&#181;&#189;&#201;&#200;&#199;&#248;&#202;&#253;   
    }
    return Capacity;
}
//&#179;&#245;&#202;&#188;&#187;&#175;SD&#191;¨
u8 SD_Initialize(void)
{
   u8 r1;      // &#180;&#230;·&#197;SD&#191;¨&#181;&#196;·&#181;&#187;&#216;&#214;&#181;
    u16 retry;  // &#211;&#195;&#192;&#180;&#189;&#248;&#208;&#208;&#179;&#172;&#202;±&#188;&#198;&#202;&#253;
    u8 buf[4];  
    u16 i;

    SD_SPI_Init();        //&#179;&#245;&#202;&#188;&#187;&#175;IO
     SD_SPI_SpeedLow();    //&#201;è&#214;&#195;&#181;&#189;&#181;&#205;&#203;&#217;&#196;&#163;&#202;&#189;
     for(i=0;i<10;i++)SD_SPI_ReadWriteByte(0XFF);//·&#162;&#203;&#205;×&#238;&#201;&#217;74&#184;&#246;&#194;&#246;&#179;&#229;
    retry=20;
    do
    {
        r1=SD_SendCmd(CMD0,0,0x95);//&#189;&#248;&#200;&#235;IDLE×&#180;&#204;&#172;
    }while((r1!=0X01) && retry--);
     SD_Type=0;//&#196;&#172;&#200;&#207;&#206;&#222;&#191;¨
    if(r1==0X01)
    {
        if(SD_SendCmd(CMD8,0x1AA,0x87)==1)//SD V2.0
        {
            for(i=0;i<4;i++)buf=SD_SPI_ReadWriteByte(0XFF);    //Get trailing return value of R7 resp
            if(buf[2]==0X01&&buf[3]==0XAA)//&#191;¨&#202;&#199;·&#241;&#214;§&#179;&#214;2.7~3.6V
            {
                retry=0XFFFE;
                do
                {
                    SD_SendCmd(CMD55,0,0X01);    //·&#162;&#203;&#205;CMD55
                    r1=SD_SendCmd(CMD41,0x40000000,0X01);//·&#162;&#203;&#205;CMD41
                }while(r1&&retry--);
                if(retry&&SD_SendCmd(CMD58,0,0X01)==0)//&#188;&#248;±&#240;SD2.0&#191;¨°&#230;±&#190;&#191;&#170;&#202;&#188;
                {
                    for(i=0;i<4;i++)buf=SD_SPI_ReadWriteByte(0XFF);//&#181;&#195;&#181;&#189;OCR&#214;&#181;
                    if(buf[0]&0x40)SD_Type=SD_TYPE_V2HC;    //&#188;ì&#178;éCCS
                    else SD_Type=SD_TYPE_V2;   
                }
            }
        }else//SD V1.x/ MMC    V3
        {
            SD_SendCmd(CMD55,0,0X01);        //·&#162;&#203;&#205;CMD55
            r1=SD_SendCmd(CMD41,0,0X01);    //·&#162;&#203;&#205;CMD41
            if(r1<=1)
            {        
                SD_Type=SD_TYPE_V1;
                retry=0XFFFE;
                do //&#181;&#200;&#180;&#253;&#205;&#203;&#179;&#246;IDLE&#196;&#163;&#202;&#189;
                {
                    SD_SendCmd(CMD55,0,0X01);    //·&#162;&#203;&#205;CMD55
                    r1=SD_SendCmd(CMD41,0,0X01);//·&#162;&#203;&#205;CMD41
                }while(r1&&retry--);
            }else
            {
                SD_Type=SD_TYPE_MMC;//MMC V3
                retry=0XFFFE;
                do //&#181;&#200;&#180;&#253;&#205;&#203;&#179;&#246;IDLE&#196;&#163;&#202;&#189;
                {                                                
                    r1=SD_SendCmd(CMD1,0,0X01);//·&#162;&#203;&#205;CMD1
                }while(r1&&retry--);  
            }
            if(retry==0||SD_SendCmd(CMD16,512,0X01)!=0)SD_Type=SD_TYPE_ERR;//&#180;í&#206;ó&#181;&#196;&#191;¨
        }
    }
    SD_DisSelect();//&#200;&#161;&#207;&#251;&#198;&#172;&#209;&#161;
    SD_SPI_SpeedHigh();//&#184;&#223;&#203;&#217;
    if(SD_Type)return 0;
    else if(r1)return r1;        
    return 0xaa;//&#198;&#228;&#203;&#251;&#180;í&#206;ó
}
//&#182;&#193;SD&#191;¨
//buf:&#202;&#253;&#190;&#221;&#187;&#186;&#180;&#230;&#199;&#248;
//sector:&#201;&#200;&#199;&#248;
//cnt:&#201;&#200;&#199;&#248;&#202;&#253;
//·&#181;&#187;&#216;&#214;&#181;:0,ok;&#198;&#228;&#203;&#251;,&#202;§°&#220;.
u8 SD_ReadDisk(u8*buf,u32 sector,u8 cnt)
{
    u8 r1;
    if(SD_Type!=SD_TYPE_V2HC)sector <<= 9;//×&#170;&#187;&#187;&#206;&#170;×&#214;&#189;&#218;&#181;&#216;&#214;·
    if(cnt==1)
    {
        r1=SD_SendCmd(CMD17,sector,0X01);//&#182;&#193;&#195;ü&#193;&#238;
        if(r1==0)//&#214;&#184;&#193;&#238;·&#162;&#203;&#205;&#179;&#201;&#185;&#166;
        {
            r1=SD_RecvData(buf,512);//&#189;&#211;&#202;&#213;512&#184;&#246;×&#214;&#189;&#218;      
        }
    }else
    {
        r1=SD_SendCmd(CMD18,sector,0X01);//&#193;&#172;&#208;&#248;&#182;&#193;&#195;ü&#193;&#238;
        do
        {
            r1=SD_RecvData(buf,512);//&#189;&#211;&#202;&#213;512&#184;&#246;×&#214;&#189;&#218;     
            buf+=512;  
        }while(--cnt && r1==0);     
        SD_SendCmd(CMD12,0,0X01);    //·&#162;&#203;&#205;&#205;&#163;&#214;&#185;&#195;ü&#193;&#238;
    }   
    SD_DisSelect();//&#200;&#161;&#207;&#251;&#198;&#172;&#209;&#161;
    return r1;//
}
//&#208;&#180;SD&#191;¨
//buf:&#202;&#253;&#190;&#221;&#187;&#186;&#180;&#230;&#199;&#248;
//sector:&#198;&#240;&#202;&#188;&#201;&#200;&#199;&#248;
//cnt:&#201;&#200;&#199;&#248;&#202;&#253;
//·&#181;&#187;&#216;&#214;&#181;:0,ok;&#198;&#228;&#203;&#251;,&#202;§°&#220;.
u8 SD_WriteDisk(u8*buf,u32 sector,u8 cnt)
{
    u8 r1;
    if(SD_Type!=SD_TYPE_V2HC)sector *= 512;//×&#170;&#187;&#187;&#206;&#170;×&#214;&#189;&#218;&#181;&#216;&#214;·
    if(cnt==1)
    {
        r1=SD_SendCmd(CMD24,sector,0X01);//&#182;&#193;&#195;ü&#193;&#238;
        if(r1==0)//&#214;&#184;&#193;&#238;·&#162;&#203;&#205;&#179;&#201;&#185;&#166;
        {
            r1=SD_SendBlock(buf,0xFE);//&#208;&#180;512&#184;&#246;×&#214;&#189;&#218;      
        }
    }else
    {
        if(SD_Type!=SD_TYPE_MMC)
        {
            SD_SendCmd(CMD55,0,0X01);   
            SD_SendCmd(CMD23,cnt,0X01);//·&#162;&#203;&#205;&#214;&#184;&#193;&#238;   
        }
         r1=SD_SendCmd(CMD25,sector,0X01);//&#193;&#172;&#208;&#248;&#182;&#193;&#195;ü&#193;&#238;
        if(r1==0)
        {
            do
            {
                r1=SD_SendBlock(buf,0xFC);//&#189;&#211;&#202;&#213;512&#184;&#246;×&#214;&#189;&#218;     
                buf+=512;  
            }while(--cnt && r1==0);
            r1=SD_SendBlock(0,0xFD);//&#189;&#211;&#202;&#213;512&#184;&#246;×&#214;&#189;&#218;
        }
    }   
    SD_DisSelect();//&#200;&#161;&#207;&#251;&#198;&#172;&#209;&#161;
    return r1;//
}   



用这个程序能实现写文件到SD卡么,FATFS文件程序有,我就是不知道SD卡程序还要不要加其他程序,还是只要这个程序就可实现把数据保存到SD卡

0条回答

一周热门 更多>