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

📄 sd.c

📁 AVR单片机做的MP3
💻 C
字号:
#include<iom16v.h>
#include<main.h>
#include<sd.h>


extern uint8 BUFFER[512];

uint8 SPI_ReadByte(void)
{
   SPDR = 0xFF;
   while (!(SPSR & 0x80)); 
   return SPDR;
}
void SPI_TransferByte(uint8 cmp1)  
{   
 SPDR=cmp1;
 while(!(SPSR&(1<<SPIF)));    
} 

void SD_Port_Init(void)
//****************************************************************************
{
        SD_PORT        |=  (1<<SD_SS);//(1<<SD_SCK)
        SD_DDR         |=  (1<<SD_SCK)|(1<<SD_MOSI)|(1<<SD_SS);
        SD_DDR         &= ~(1<<SD_MISO);
		SD_Disable();
}

//****************************************************************************
//Routine for Init MMC/SD card(SPI-MODE)
uint8 SD_Init(void)
//****************************************************************************
{
        uint8 retry,temp;
        uint8 i;

       uint8 CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};
   SD_Port_Init(); //Init SPI port  

   for (i = 0; i < 200; i++) asm("nop"); //Wait MMC/SD ready...
   
   //Active SPI bus at low speed 
   SPCR=0x53; //SPI Master,MSB First 
   SPSR=0x00; //double speed disable,Fsck=Fosc/128 

   for (i = 0; i < 16; i++)
      SPI_TransferByte(0xff); //send 74 clock at least!!! 
	
   //Send Command CMD0 to MMC/SD Card
   SD_Enable();
   retry = 0;
   do
   { //retry 200 times to send CMD0 command 
     temp = Write_Command_SD(CMD);
     if (retry++ == 200) 
       return INIT_CMD0_ERROR;//CMD0 Error!
   }
   while (temp != 1);
   
   //Send Command CMD1 to MMC/SD-Card
   CMD[0] = 0x41; //Command 1
   CMD[5] = 0xFF;
   retry = 0;
   do
   { //retry 100 times to send CMD1 command 
     temp = Write_Command_SD(CMD);
     if (retry++ == 100) 
       return INIT_CMD1_ERROR;//CMD1 Error!
   } 
   while (temp != 0);
   
   //Active High-speed SPI mode(Fsck=Fosc/2) 
   SPCR = 0x50; 
   SPSR = 0x00; 

   SD_Disable();  //set MMC_Chip_Select to high 
   return INIT_OK; //All commands have been taken.
}

//****************************************************************************
//Send a Command to MMC/SD-Card
//Return: the second byte of response register of MMC/SD-Card
uint8 Write_Command_SD(uint8 *cmd)
//****************************************************************************
{
        uint8 tmp,i;
        uint8 retry=0;
        SD_Disable();
		SPI_TransferByte(0xFF);
		SD_Enable();
		for(i=0;i<6;i++)
		{
        SPI_TransferByte(*cmd++);
        }
        SPI_ReadByte();
        
        do{
                tmp = SPI_ReadByte();
        }while((tmp==0xff)&&(retry++ <100));
        return(tmp);
}

uint8 SD_Read_Block(uint8 *CMD,uint8 *Buffer,uint16 Bytes)
//****************************************************************************
{  
   uint16 i;
   uint8 retry, temp;
    
   //Send Command CMD to MMC/SD-Card
   retry=0;
   do
   {  //Retry 100 times to send command.
      temp=Write_Command_SD(CMD);
      if(retry++ == 100) 
        return READ_BLOCK_ERROR; //block write Error!
   }
   while (temp != 0); 
   			
   //Read Start Byte form MMC/SD-Card (FEh/Start Byte)
   while (SPI_ReadByte() != 0xfe);
	
   //Write blocks(normal 512Bytes) to MMC/SD-Card
   for (i = 0; i < Bytes; i++)
   {
      *Buffer++ = SPI_ReadByte();
	 // put_c(*Buffer);
   }
   
   //CRC-Byte
   SPI_ReadByte();//CRC - Byte 
   SPI_ReadByte();//CRC - Byte
	
   //set MMC_Chip_Select to high (MMC/SD-Card invalid)
   SD_Disable();
   return READ_BLOCK_OK;
}

//****************************************************************************
//Routine for writing a Block(512Byte) to MMC/SD-Card
//Return 0 if sector writing is completed.
uint8 SD_read_sector(uint32 addr,uint8 *Buffer)
//****************************************************************************
{
       //Command 16 is reading Blocks from MMC/SD-Card
   uint8 CMD[] = {0x51,0x00,0x00,0x00,0x00,0xFF}; 
   
   asm("cli"); //clear all interrupt.
   //Address conversation(logic block address-->byte address)  
   addr = addr << 9; //addr = addr * 512

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

   return SD_Read_Block(CMD, Buffer, 512);
        
}
uint8 SD_write_sector(uint32 addr,uint8 *Buffer)
//****************************************************************************
{  
   uint8 tmp,retry;
   uint16 i;
   //Command 24 is a writing blocks command for MMC/SD-Card.
   uint8 CMD[] = {0x58,0x00,0x00,0x00,0x00,0xFF}; 
   
   asm("cli"); //clear all interrupt.
   addr = addr << 9; //addr = addr * 512
	
   CMD[1] = ((addr & 0xFF000000) >>24 );
   CMD[2] = ((addr & 0x00FF0000) >>16 );
   CMD[3] = ((addr & 0x0000FF00) >>8 );

   //Send Command CMD24 to MMC/SD-Card (Write 1 Block/512 Bytes)
   retry=0;
   do
   {  //Retry 100 times to send command.
      tmp = Write_Command_SD(CMD);
      if(retry++ == 100) 
        return(tmp); //send commamd Error!
   }
   while(tmp != 0); 
   
   //Before writing,send 100 clock to MMC/SD-Card
   for (i = 0; i < 100; i++)
      SPI_ReadByte();
	
   //Send Start Byte to MMC/SD-Card
   SPI_TransferByte(0xFE);	
	
   //Now send real data Bolck (512Bytes) to MMC/SD-Card
   for (i = 0; i < 512; i++)
      SPI_TransferByte(*Buffer++); //send 512 bytes to Card

   //CRC-Byte 
   SPI_TransferByte(0xFF); //Dummy CRC
   SPI_TransferByte(0xFF); //CRC Code
   
    
   tmp=SPI_ReadByte();   // read response
   if((tmp & 0x1F) != 0x05) // data block accepted ?
   {
     SD_Disable();
     return WRITE_BLOCK_ERROR; //Error!
   }
   //Wait till MMC/SD-Card is not busy
   while (SPI_ReadByte() != 0xFF){};
	
   //set MMC_Chip_Select to high (MMC/SD-Card Invalid)
   SD_Disable();
   return 0;
} 

⌨️ 快捷键说明

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