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

📄 mmc.c

📁 MMC/SD卡的AVR Studio 4 的 GCC 程序 和 Proteus仿真程序.
💻 C
字号:
//=====================================================================



//=====================================================================
#include "mmc.h"
//=====================================================================

//---------------------------------------------------------------------
//Init MMC/SD card(SPI-MODE)
//---------------------------------------------------------------------
U08 mmc_init ()
{
	U08 Timeout = 0;
	MMC_Direction_REG &=~(1<<SPI_DI);			//MMC_DI    Input
	MMC_Direction_REG |= (1<<SPI_Clock);		//MMC_Clock Output
	MMC_Direction_REG |= (1<<SPI_DO);			//MMC_DO    Output
	MMC_Direction_REG |= (1<<MMC_Chip_Select);	//MMC_CS    Output
	MMC_Direction_REG |= (1<<SPI_SS);	
	MMC_Write |= (1<<MMC_Chip_Select);			//MMC_CS    HIGH
    
	unsigned char a;
    for(a=0;a<200;a++){nop(); };		//Wait ......

	#if SPI_Mode   //SPI INIT
		SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1); //Enable SPI, SPI in Master Mode	
		SPSR = (0<<SPI2X);
	#endif
	for (a = 0;a<0x0f;a++){mmc_write_byte(0xff);}//wait  >74  Clk
	
	//--------- send CMD0  ---------
	U08 CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};
	while(mmc_write_command (CMD) !=1)
	{
		if (Timeout++ > 200)
		   { return(1); }// CMD0 Error!
	}
    //--------- send CMD1  ---------
	Timeout = 0;
	CMD[0] = 0x41;
	CMD[5] = 0xFF;
	while( mmc_write_command (CMD) !=0)
	{
		if (Timeout++ > 100)
			{
			return(2); //CMD1 Error!
			}
	}
	#if SPI_Mode    // SPI clk 
		SPCR &= ~((1<<SPR0) | (1<<SPR1));
		SPSR = SPSR|(1<<SPI2X);
	#endif
	MMC_Disable();//MMC_CS = high
	return(0);
}

//---------------------------------------------------------------------
//Send a Command to MMC/SD-Card
//Return: the second byte of response register of MMC/SD-Card
//---------------------------------------------------------------------
U08 mmc_write_command (U08 *cmd)
{
	U08 tmp = 0xff;
	U16 Timeout = 0;

	MMC_Disable();        //MMC_CS = HIGH
	mmc_write_byte(0xFF); //send 8 Clock Impulse
	MMC_Enable();         //MMC_CS = LOW   

	//send 6 Byte Command
    U08 a;
	for (a = 0;a<0x06;a++)  
		{
		  mmc_write_byte(*cmd++);
		}

	//get 16 bit response
	while (tmp == 0xff)	
		{
		tmp = mmc_read_byte();  //Only last 8 bit is used here.Read it out. 
		if (Timeout++ > 500){break;}
		}
	return(tmp);
}

//---------------------------------------------------------------------
//Routine for reading a byte from MMC/SD-Card
//---------------------------------------------------------------------
inline U08 mmc_read_byte (void)
{
	U08 Byte = 0;

    #if SPI_Mode	 
	  SPDR = 0xff;
	  while(!(SPSR & (1<<SPIF))){};
	  Byte = SPDR;
    #else			//Software SPI
	
	  for (U08 a=8; a>0; a--) //1 Byte  ( MSB First)
	      {
             MMC_Write &=~(1<<SPI_Clock); //MMC_SCK (Low) 
		     if (bit_is_set(MMC_Read,SPI_DI) > 0)  
		        {
			    	Byte |= (1<<(a-1));
			     }
			  else
			     {
			         Byte &=~(1<<(a-1));
				  }
		       MMC_Write |=(1<<SPI_Clock); //MMC_SCK (High)		
		  }
    #endif
	return (Byte);
}

//---------------------------------------------------------------------
//Routine for sending a byte to MMC/SD-Card
//---------------------------------------------------------------------
inline void mmc_write_byte (U08 Byte)
{
    #if SPI_Mode		 
	  SPDR = Byte; 	 
	  while(!(SPSR & (1<<SPIF))) {}
    #else			
	  for (U08 a=8; a>0; a--) // 1 Byte ( MSB First)
	    {
		  if (bit_is_set(Byte,(a-1))>0)	{MMC_Write |= (1<<SPI_DO); }//MMC.DO  High
		  else {MMC_Write &= ~(1<<SPI_DO);}//MMC.DO  Low
		  MMC_Write &= ~(1<<SPI_Clock);	//MMC.SCK  (LOW)
		  MMC_Write |= (1<<SPI_Clock);   //MMC.SCK  (High)
	     }
	   MMC_Write |= (1<<SPI_DO);	       //MMC.DO  High
    #endif
}

//---------------------------------------------------------------------
//Blocks(512Byte) 
//Routine for writing a Block(512Byte) to MMC/SD-Card
//---------------------------------------------------------------------
U08 mmc_write_sector (U32 addr,U08 *Buffer)
{
	unsigned char tmp;
	unsigned char cmd[] = {0x58,0x00,0x00,0x00,0x00,0xFF}; //CMD 24  

	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)
	tmp = mmc_write_command (cmd);
	if (tmp != 0) { return(tmp); }  ////send commamd Error!

	//Before writing,send 100 clock to MMC/SD-Card
	unsigned char  a;

	for (a=0;a<100;a++)
		{
		mmc_read_byte();
		}
 
 	mmc_write_byte(0xFE);//Send Start Byte to MMC/SD-Card	


	//Now send real data Bolck (512Bytes) to MMC/SD-Card
    int   b;
    for (b=0;b<512;a++)
		{
		mmc_write_byte(*Buffer++);
		}
	
	//CRC-Byte  
	mmc_write_byte(0xFF); //Dummy CRC
	mmc_write_byte(0xFF); //CRC Code 
	
	//Wait till MMC/SD-Card is not busy
	while (mmc_read_byte() != 0xff){};
	
	//set MMC_CS    high 
	MMC_Disable();
	
return(0);
}

//---------------------------------------------------------------------
//Routine for reading data Registers of MMC/SD-Card
//Return 0 if no Error.
//---------------------------------------------------------------------

void mmc_read_block(U08 *cmd,U08 *Buffer,U16 Bytes)
{	
	//Send CMD0
	if (mmc_write_command (cmd) != 0)
			{
			 return;//block write Error!
			}

	//Read Start Byte form MMC/SD-Card (FEh/Start Byte)
	while (mmc_read_byte() != 0xfe){};

	//Write blocks(normal 512Bytes) to MMC/SD-Card
    int   a;
	for (a=0;a<Bytes;a++)
		{
		*Buffer++ = mmc_read_byte();
		}
	//CRC-Byte  
	mmc_read_byte();//CRC - Byte 
	mmc_read_byte();//CRC - Byte 
	
	MMC_Disable();//MMC_CS = high (MMC/SD-Card no active )
	
	return;
}

//---------------------------------------------------------------------
//Routine for reading Blocks(512Byte) from MMC/SD-Card
//Return 0 if no Error.
//---------------------------------------------------------------------
U08 mmc_read_sector (U32 addr,U08 *Buffer)
{	
	//Command 16 is reading Blocks from MMC/SD-Card
	U08 cmd[] = {0x51,0x00,0x00,0x00,0x00,0xFF}; 
	
	//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 );

    mmc_read_block(cmd,Buffer,512);

	return(0);
}

//---------------------------------------------------------------------
//Routine for reading CID Registers from MMC/SD-Card (16Bytes) 
//Return 0 if no Error.
//---------------------------------------------------------------------
U08 mmc_read_cid (U08 *Buffer)
{
	U08 cmd[] = {0x4A,0x00,0x00,0x00,0x00,0xFF}; //Command for reading CID Registers
	mmc_read_block(cmd,Buffer,16);
	return(0);
}

//---------------------------------------------------------------------
//Routine for reading CSD Registers from MMC/SD-Card (16Bytes)
//Return 0 if no Error.
//---------------------------------------------------------------------
U08 mmc_read_csd (U08 *Buffer)
{	
	U08 cmd[] = {0x49,0x00,0x00,0x00,0x00,0xFF}; //Command for reading CSD Registers
	mmc_read_block(cmd,Buffer,16);
	return(0);
}
 

//---------------------------------------------------------------------


//---------------------------------------------------------------------

//---------------------------------------------------------------------


//---------------------------------------------------------------------


//---------------------------------------------------------------------

//---------------------------------------------------------------------


//---------------------------------------------------------------------





⌨️ 快捷键说明

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