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

📄 sd.c

📁 LED条屏显示程序,但是对初学者
💻 C
字号:
//ICC-AVR application builder : 2005-11-12 17:11:59
// Target : M16
// Crystal: 8.0000Mhz
// copyright:鲁军波(endylu)
// www.shop34612283.taobao.com
// www.adembed.com
#include <iom16v.h>
#include <macros.h>
#include "main.h"

//=======================================================================
uint8 Read_Byte_SD(void) 
{ 
 //char Byte; 
 SPDR=0xff; 
 while(!(SPSR&(1<<SPIF)));
 
 //Byte=SPDR;
 return(SPDR); 
}

//=======================================================================
void Write_Byte_SD(uint8 Byte) 
{ 
 SPDR=Byte; 
 while(!(SPSR&(1<<SPIF)));
} 

//=======================================================================
uint8 Write_Command_SD1(uint8*CMD) 
{ 
 uint8 a; 
 uint8 tmp=0xff; 
 uint8 Timeout=0; 

 // Raise chip select 
 SD_Disable(); 

 // Send an 8 bit pulse 
 Write_Byte_SD(0xFF); 
 
 // Lower chip select 
 SD_Enable(); 

 //Send the 6 byte command 
 for(a=0;a<0x06;a++) 
    {
     Write_Byte_SD(*CMD++); 
    } 

 //Wait for the response 
 while(tmp==0xff)
      {
       tmp=Read_Byte_SD(); 
       if(Timeout++>100) 
         { 
          break; 
         } 
      } 
 //SD_Disable(); 
 //for some reason we need to delay  10here 
 return(tmp); 
}

//=======================================================================
uint8 Write_Command_SD(uint8 CMD,uint32 address) 
{ 
 
 uint8 tmp; 
 uint8 Timeout=0; 
 
 // Raise chip select 
 SD_Disable(); 

 // Send an 8 bit pulse 
 Write_Byte_SD(0xFF); 
 
 // Lower chip select 
 SD_Enable(); 
 //Send the 6 byte command  
  Write_Byte_SD(CMD);
  Write_Byte_SD(address>>24);
  Write_Byte_SD(address>>16);
  Write_Byte_SD(address>>8);
  Write_Byte_SD(address);
  Write_Byte_SD(0xff);
  

 //Wait for the response 
 tmp=Read_Byte_SD();
 while((tmp==0xff)&(Timeout++<8)) 
      {
       tmp=Read_Byte_SD();  
      } 
 //SD_Disable(); 
 return(tmp); 
}

//=======================================================================
uint8 SDInit(void)
{ 
 uint8 a,b,retry; 
 uint8 CMD[]={0x40,0x00,0x00,0x00,0x00,0x95}; 
 
 asm("cli"); //clear all interrupt.
 // Set certain pins to inputs and others to outputs 
 // Only SPI_DI (data in) is an input 
 SD_Direction_REG&=~(1<<SPI_DI); 
 SD_Direction_REG|=(1<<SPI_Clock); 
 SD_Direction_REG|=(1<<SPI_DO); 
 SD_Direction_REG|=(1<<SD_Chip_Select); 
 SD_Write|=(1<<SD_Chip_Select); 
 SD_Write|=(1<<SPI_DI); 

 //We need to wait for the SD_Direction_REG to be ready 
 for(a=0;a<200;a++) 
    {
     nop();
    }; 
 //Enable SPI in Master Mode with IDLE low and clock at 8M/128 
SPCR=(1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1); 
SPSR&=~(1<<SPI2X); 
  
 // We need to give the card about a Hundred cycles to load 
 for (b=0;b<0x0f;++b) 
     {
      Write_Byte_SD(0xff); 
     } 

 //Send the initialization commands to the card 
 retry=0; 
  
 while(Write_Command_SD1(CMD)!=0X01)
 {
  Delay_ms(10);              //很重要,要不然就要REST才可以
 //fail and return 
 if(retry++>50) 
 { 
 return 1; 
 } 
 } 

//Send the 2nd command 
 retry=0; 
 CMD[0]=0x41; 
 CMD[5]=0xFF; 

while(Write_Command_SD1(CMD)!=0) 
      {
	   Delay_ms(10);
       if (retry++>50) 
          {
          return 2; 
          } 
       } 

 //Set the SPI bus to full speed 8M/2
 SPCR&=~((1<<SPR0)|(1<<SPR1)); 
 SPSR|=(1<<SPI2X); 
 
 //Raise Chip Select 

 SD_Disable(); 
 asm("sei");
 return 0; 
} 

//=======================================================================
uint8 SD_set_length(uint16 length)
{
 uint8 retry;
 //Command to set the block length;

 while(Write_Command_SD(0x50,length)!=0) 
      {
       if (retry++>10) 
          { 
		   return 1;
          } 
       }
 SD_Disable(); 
 return 0;
}

//=======================================================================
uint8 SD_start_read(uint32 addr)
{
 uint8 retry; 
  // Send the read command  
 while(Write_Command_SD(0x51,addr<<9)!=0) 
      {
       if (retry++>10) 
          { 
          return 1; 
          } 
      }  
 //SD_Enable();
 //Send the start byte 
 while(Read_Byte_SD()!=0xfe);
 
 SD_Disable();
 return 0;  //open successfully!
}

//=======================================================================
void SD_get_date(uint8 *Buffer,uint16 Number)
{
 uint16 a;
 SD_Enable();
 
 for(a=0;a<Number;a++) 
 {
 *Buffer++=Read_Byte_SD(); 
 
 }  
  SD_Disable();          // Set SD_Chip_Select to high 
}

//=======================================================================
uint8 SD_read_sector2(uint32 addr,uint8*Buffer,uint16 Bytes) 
{ 
 uint8 i;
 uint16 a;
 uint8 retry=0;
 
 if(SD_set_length(Bytes))
     {
	 return 1; 
	 }
 
 // Send the read command  
 while(Write_Command_SD(0x51,addr)!=0) 
      {
       if (retry++>10) 
          { 
           return 2; 
          } 
      } 
 
 // Raise chip select 

 //SD_Enable(); 
 //receive the start byte 
 while(Read_Byte_SD()!=0xfe);
                                                                            
 //Read off all the bytes in the block 
 for(a=0;a<Bytes;a++) 
  {
   *Buffer++=Read_Byte_SD();  
  }
 //Read CRC byte 
 Read_Byte_SD(); 
 Read_Byte_SD(); 
 
 SD_set_length(512);
 // Set SD_Chip_Select to high 
 SD_Disable(); 

 return 0; 
} 

/*
//=======================================================================
//Routine for writing a Block(512Byte) to MMC/SD-Card
//Return 0 if sector writing is completed.
unsigned char SD_write_sector(unsigned long addr,unsigned char *Buffer)
{  
   unsigned char tmp,retry;
   unsigned int i;
   #asm("cli"); //clear all interrupt.
   //Command 24 is a writing blocks command for MMC/SD-Card.
    while(Write_Command_SD(0x58,addr)!=0) 
      {
       if (retry++>10) 
          { 
          return 1; 
          } 
      }
   
   //Before writing,send 100 clock to MMC/SD-Card
   for (i=0;i<100;i++)
   {
      Read_Byte_SD();
   }
	
   //Send Start Byte to MMC/SD-Card
   Write_Byte_SD(0xFE);	
	
   //Now send real data Bolck (512Bytes) to MMC/SD-Card
   for (i=0;i<512;i++)
   {
      Write_Byte_SD(*Buffer++); //send 512 bytes to Card
   }

   //CRC-Byte 
   Write_Byte_SD(0xFF); //Dummy CRC
   Write_Byte_SD(0xFF); //CRC Code
   
    
   tmp=Read_Byte_SD();   // read response
   
   if((tmp & 0x1F)!=0x05) // data block accepted ?
   {
     SD_Disable();
     return 1; //Error!
   }
   //Wait till MMC/SD-Card is not busy
   while (Read_Byte_SD()!=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 + -