⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sd_dri.c

📁 收集了单片机对SD卡读写源码
💻 C
字号:
/*!
 *@file     sd_dri.c
 *
 * 
 *
 *@version  v1.0.0
 *@date     2007
 *@author   jacky291@126.com
*/

#include "sd_dri.h"

#ifndef __SD_CONFIG_H
#include "sd_cfg.h"
#endif
#ifndef __SD_DATA_H
#include "sd_dat.h"
#endif
#ifndef __SD_API_H
#include "sd_api.h"
#endif
#ifndef __SD_CMD_H
#include "sd_cmd.h"
#endif

SD_CARD sd;
/*!
 *@brief
 *        SD_info()
 *        read the info data from the sd card
 *
 *@param  none
 *@retval none
 */
uint32 SD_info(SD_CARD *s)
{
     uint8 i, buff[16];
     SD_ReadCID(16,buff);
     s->MID=buff[0];
     s->OID=buff[1]<<8|buff[2];
     /**< card name */
     for(i=0;i<5;i++){
         s->PNM[i]=buff[i+3];
     }
     s->PRV = buff[9];
     /**< serial Num */
     for(i=0;i<4;i++){
        s->PSN[i]=buff[3+i];
     };
     /**< read the current VDD */
     SD_ReadOCR(4, buff);
     /**< read the other informations */
     if(SD_ReadCSD(16,buff)!=0){
        return 0xFF;
     };
     return 0;
}

 /*!
*@brief
*        SD_ActiveInit()
*        active the sd card
*
*@param  none
*@retval none
*/
uint8 SD_ActiveInit(void)
{
	uint8 param[4] = {0,0,0,0},resp,ret;
	uint32 i = 0;
 	do 
    {												  /**< send CMD1 to poll card status */
        ret = SD_SendCMD(CMD1, param, R1, &resp);
        if (ret==0&&resp==0)return ret;
        i++;
    }
	while (i < SD_IDLE_WAIT_MAX);																			
    if (i >= SD_IDLE_WAIT_MAX) return SD_ERR_TIMEOUT_WAITIDLE;
             			                             /**< time out,return error */
	return 0;
}







 /*!
*@brief
*        SD_init()
*        read the info data from the sd card
*
*@param  none
*@retval none
*/

uint32 SD_init()
{
   
     SD_SPI_Init();
     SD_SPI_Clk(SD_INIT_CLK);
     SD_powerOff();
     SD_powerOn();
     SD_SPI_SendByte(0xFF);
     SD_SPI_SendByte(0xFF);
     SD_SPI_SendByte(0xFF);
     SD_SPI_SendByte(0xFF);
     if(SD_ResetSD()!=0){                         /**< reset the card */
           return SD_INIT_FAILED;
     };
     if(SD_ActiveInit()==WAIT_IDLE_TIMEOUT){
           return WAIT_IDLE_TIMEOUT;
     };
     #if SD_CRC_EN  
        SD_EnableCRC(1);
     #endif
     SD_SPI_Clk(SD_MAX_CLK);
     SD_SetBlockLen(SD_BLOCKSIZE);
     if(SD_info(&sd)!=0){
          return 0xFF;
     };
     return 0;
}










 /*!
*@brief
*        SD_read()
*        read the data from the sd card
*        when the addr is block_start addr and the len is READ_BL_LEN it will be the fast!
*@param  uint32 addr:start address
*@param  uint32 len:the lenth read
*@param  uint8 *buff:the receive buff
*@retval return the readed byte length
*/
uint32 SD_read(uint32 addr,uint32 len,uint8 *buff)
{
       uint8  readed[READ_BL_LEN];
       uint32 i,j,blocks;
       uint32 offset_fst=(addr + READ_BL_LEN)%READ_BL_LEN;
       uint32 offset_lst=(addr + len)%READ_BL_LEN;
       uint32 start_block=addr/READ_BL_LEN;
       uint32 end_block=(addr + len -1)/READ_BL_LEN;
       
       blocks =end_block-start_block;
       
       if( blocks==0 ){
              SD_ReadSingleBlock(start_block*READ_BL_LEN);
              if(SD_ReadBlockData(READ_BL_LEN,readed)==0){            /**< read a sigle sector */
                    for(i=0;i<len;i++){                               /**< copy the data to the buff */
                             *buff++ = readed[offset_fst + i];
                    };
              }else{
                    return SD_READ_FAILED;
              };
          
       }else{
         
              if(SD_ReadMultipleBlock(start_block*READ_BL_LEN)!=0){      /**< send the read command */
                     return SD_READ_FAILED;   
              };                                         
              SD_ReadBlockData(READ_BL_LEN,readed);
              for(i=offset_fst;i<READ_BL_LEN;i++){                      /* copy the data in first sector to the buff */
                                      
                          *buff++ = readed[i];
              };
              for(i=1;i<blocks;i++){                                    /* the last block maybe not include all  data needed */
                     if(SD_ReadBlockData(READ_BL_LEN,readed)==0){
                         for(j=0;j<READ_BL_LEN;j++){                    /* copy the data to the buff */
                                      
                                *buff++ = readed[i];
                         };
                     };
                                                                        
              };
              if(SD_ReadBlockData(READ_BL_LEN,readed)==0){
                   for(i=0;i<offset_lst;i++){                           /* copy the data in last sector to the buff */
                                      
                         *buff++ = readed[i];
                   };
              };
              SD_StopTransmission();
       }; 
       return 0;
}





 /*!
*@brief
*        SD_write()
*        write the data to the sd card
*        when the addr is block_start addr and the len is READ_BL_LEN it will be the fast!
*@param  uint32 addr:start address
*@param  uint32 len:the lenth write
*@param  uint8 *buff:the write buff
*@retval return the writed byte length
*/
uint32 SD_write(uint32 addr,uint32 len,uint8 *buff)
{
      
       uint32 i;
       uint32 offset_fst=(addr + READ_BL_LEN)%READ_BL_LEN;
       uint32 offset_lst=(addr + len)%READ_BL_LEN;
       uint32 start_block=addr/READ_BL_LEN;
       uint32 end_block=(addr + len -1)/READ_BL_LEN;
       uint32 blocks =end_block-start_block;
       uint8  readed[READ_BL_LEN];
       if( blocks==0 ){
              SD_ReadSingleBlock(start_block*READ_BL_LEN);
              if(SD_ReadBlockData(READ_BL_LEN,readed)==0){                /* read a sigle sector */
                    for(i=0;i<len;i++){                                   /* copy the data to the buff to write */
                             readed[offset_fst + i]=*buff++;       
                    };
                    
                    if(SD_WriteSingleBlock(start_block*READ_BL_LEN)==0){  /**< write back the old data and append the new data */
                    
                               SD_WriteBlockData(0,READ_BL_LEN,readed);
                               
                    }else{
                               return SD_WRITE_FAILED;
                               
                    };  
                     
               }else{
                                                        
                    return SD_READ_FAILED;
              };
              
      }else{
 
             if(SD_ReadSingleBlock(start_block*READ_BL_LEN)!=0){            /**< send the read command */
              
                    return 255;
              };
              
              SD_ReadBlockData(READ_BL_LEN,readed);
              
              for(i=offset_fst;i<READ_BL_LEN;i++){                           /**< copy the data in first sector to the buff */
                       
                           readed[i] =*buff++;
              };
              
              if(SD_WriteSingleBlock(start_block*READ_BL_LEN)!=0){
              
                  return SD_WRITE_FAILED;
              };
              
              SD_WriteBlockData(0,READ_BL_LEN,readed);
              
              for(i=1;i<blocks;i++){                                 /**< the last block maybe not include all  data needed */
              
                      if(SD_ReadSingleBlock((start_block + i)*READ_BL_LEN)!=0){
                     
                                    return 255;
                  
                       };
            
                      if(SD_ReadBlockData(READ_BL_LEN,readed)==0){
              
                             for(i=0;i<READ_BL_LEN;i++){                          /**< copy the data to the buff */            
                                            readed[i]=*buff++;
                             };  
                       };
                        
                      if(SD_WriteSingleBlock(start_block + i)!=0){           /**< write back */
                     
                            return SD_WRITE_FAILED;
                            
                      }else{
                        
                            SD_WriteBlockData(0,READ_BL_LEN,readed);
                      };                                        
              };
              
              
              if(SD_ReadSingleBlock(end_block*READ_BL_LEN)!=0) return 255;
              if(SD_ReadBlockData(READ_BL_LEN,readed)==0){
                    for(i=0;i<offset_lst;i++){                    /**< copy the data to the buff */    
                    
                           readed[i] = *buff++;
                           
                    };
              };
               
              if(SD_WriteSingleBlock(end_block*READ_BL_LEN)==0){
              
                    SD_WriteBlockData(0,READ_BL_LEN,readed);
                    
              };
              
     };
     
       return 0;
}




 /*!
*@brief
*        SD_eraser()
*        eraser the data from the sd card
*        when the addr is block_start addr and the len is READ_BL_LEN it will be the fast!
*@param  uint32 addr:start address
*@param  uint32 len:the lenth eraser
*@retval return the erasered byte length
*/
uint32 SD_eraser(uint32 addr,uint32 len)
{
       uint32 i;
       uint32 offset_fst=(addr + READ_BL_LEN)%READ_BL_LEN;
       uint32 offset_lst=(addr + len)%READ_BL_LEN;
       uint32 start_sec=addr/READ_BL_LEN;
       uint32 end_sec=(addr + len -1)/READ_BL_LEN;
       uint32 blocks =end_sec-start_sec;
       uint8  readed[READ_BL_LEN];
      
       blocks = end_sec -  start_sec;
       
       if( blocks==0 ){
              SD_ReadSingleBlock(start_sec*READ_BL_LEN);
              if(SD_ReadBlockData(READ_BL_LEN,readed)==0){                /**< read a sigle sector */
              
                    for(i=offset_fst;i<offset_fst + len;i++){                     /**< copy the data to the buff to write */
                             readed[i] = 0x00;
                    };
                    
                    if(SD_WriteSingleBlock(start_sec*READ_BL_LEN)==0){     /**< write back the old data and append the new data */
                               SD_WriteBlockData(0,READ_BL_LEN,readed);
                               
                    }else{
                               return SD_WRITE_FAILED;
                    };  
                     
               }else{
                                                        
                    return SD_READ_FAILED;
              };
              
        }else{
         
              SD_ReadSingleBlock(start_sec*READ_BL_LEN);               /**< send the read command */
              SD_ReadBlockData(READ_BL_LEN,readed);
              for(i=offset_fst;i<READ_BL_LEN;i++){                     /**< copy the data in first sector to the buff */
                       
                          readed[i] = 0x00;
              };
              
              if(SD_WriteSingleBlock(start_sec*READ_BL_LEN)!=0){
                  return SD_WRITE_FAILED;
              }else{
                  SD_WriteBlockData(0,READ_BL_LEN,readed);
              };
              
              
              if(blocks==1){
              
                   SD_EraseStartBlock((start_sec+1)*READ_BL_LEN);         /**< Erase */ 
                   SD_EraseEndBlock((start_sec+2)*READ_BL_LEN); 
                   SD_EraseSelectedBlock();
                  
              }else{
              
                   SD_EraseStartBlock((start_sec+1)*READ_BL_LEN);         /**< Erase */ 
                   SD_EraseEndBlock((end_sec-1)*READ_BL_LEN); 
                   SD_EraseSelectedBlock();
                  
                   SD_ReadSingleBlock(end_sec*READ_BL_LEN);
                   SD_ReadBlockData(READ_BL_LEN,readed);
                   for(i=0;i<offset_lst;i++){                                  /**< copy the data to the buff */    
                         readed[i] = 0x00;
                    };
                   SD_WriteSingleBlock(end_sec*READ_BL_LEN);
                   SD_WriteBlockData(0,READ_BL_LEN,readed);
                   SD_StopTransmission();
              };
              
              
       }; 
       return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -