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

📄 mmc_spi.c

📁 使用IAR430编译源文件
💻 C
字号:
//###########################################################
// File: mmc_spi.c
//
// Read-/Writeroutines for MMC MultiMedia cards and
// SD SecureDigital cards in SPI mode.
//
// This will work only for MMC cards with 512 bytes block length !
// This will work only for MMC cards with a partition table !
//
//
//#########################################################################
// Last change: 21.05.2006
//#########################################################################


#include <msp430x16x.h>
#include "dos.h"

#ifdef MMC_CARD_SPI

#define set_SD_nCs     (P3OUT |=  BIT0)
#define clr_SD_nCs     (P3OUT &= ~BIT0)
#define set_SD_MOSI       (P3OUT |=  BIT1)
#define clr_SD_MOSI       (P3OUT &= ~BIT1)
#define SD_MISO           ((P3IN & ( BIT2))>>1)
#define set_SD_SCK        (P3OUT |=  BIT3)
#define clr_SD_SCK        (P3OUT &= ~BIT3)

//set MMC_Chip_Select to high (MMC/SD-Card Invalid)
#define MMC_Disable() set_SD_nCs;
//set MMC_Chip_Select to low (MMC/SD-Card Active)
#define MMC_Enable() clr_SD_nCs;
#define    SomeNOP   {_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();}        

unsigned char Init_Flag;    //Set it to 1 when Init is processing.
unsigned char Read_Byte_MMC(void);
void Write_Byte_MMC(unsigned char value);
unsigned char Write_Command_MMC(unsigned char *CMD);

//****************************************************************************
// Port Init
void MMC_Port_Init(void)
//****************************************************************************
{
    P3SEL = 0x00;    
    P3DIR |= (BIT0 + BIT1 + BIT3);
    P3DIR &= ~BIT2;
    set_SD_nCs;
    set_SD_SCK;
    set_SD_MOSI;
   
}

//****************************************************************************
//Routine for Init MMC/SD card(SPI-MODE)
unsigned char MMCIdentify(void)
//****************************************************************************
{  
   unsigned char retry,temp;
   unsigned char i;
   unsigned char CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};
   
   MMC_Port_Init(); //Init SPI port  

   for(i=0;i<250;i++) //Wait MMC/SD ready...
   {
        _NOP();
        _NOP();
        _NOP();
        _NOP();
        _NOP();
        _NOP();
        _NOP();                                                
        _NOP();
        _NOP();
        _NOP();
        _NOP();
        _NOP();
        _NOP();
        _NOP();                                                
        _NOP();
        _NOP();
        _NOP();
        _NOP();
        _NOP();
        _NOP();
        _NOP();                                                
        _NOP();
        _NOP();
        _NOP();
        _NOP();
        _NOP();
        _NOP();
        _NOP();                                                
        
   }
   
   Init_Flag=1; //Set the init flag

   for (i=0;i<0x0f;i++) 
   {
      Write_Byte_MMC(0xff); //send 74 clock at least!!!
   }
	
   //Send Command CMD0 to MMC/SD Card
   retry=0;
   do
   { //retry 200 times to send CMD0 command 
     temp=Write_Command_MMC(CMD);     
     retry++;
     if(retry==200) 
     { //time out
       return(1);//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_MMC(CMD);     
     retry++;
     if(retry==250) 
     { //time out
       return(1);//CMD1 Error!
     }
   } 
   while(temp!=0);
   
   Init_Flag=0; //Init is completed,clear the flag 
   
   MMC_Disable();  //set MMC_Chip_Select to high 
   return(0); //All commands have been taken.
} 
//****************************************************************************
//Send a Command to MMC/SD-Card
//Return: the second byte of response register of MMC/SD-Card
unsigned char Write_Command_MMC(unsigned char *CMD)
//****************************************************************************
{
   unsigned char tmp;
   unsigned char retry=0;
   unsigned char i;

   //set MMC_Chip_Select to high (MMC/SD-Card disable) 
   MMC_Disable();
   //send 8 Clock Impulse
   Write_Byte_MMC(0xFF);
   //set MMC_Chip_Select to low (MMC/SD-Card active)
   MMC_Enable();

   //send 6 Byte Command to MMC/SD-Card
   for (i=0;i<0x06;i++) 
   { 
      Write_Byte_MMC(*CMD++);
   }
   
   //get 16 bit response
   Read_Byte_MMC(); //read the first byte,ignore it. 
   do 
   {  //Only last 8 bit is used here.Read it out. 
      tmp = Read_Byte_MMC();
      retry++;
   }
   while((tmp==0xff)&&(retry<100)); 
   return(tmp);
}

//****************************************************************************
//Routine for reading a byte from MMC/SD-Card
unsigned char Read_Byte_MMC(void)
//****************************************************************************
{ 
    unsigned char i,rByte=0;
    for(i=0;i<8;i++){
        clr_SD_SCK;
        if(Init_Flag){
            SomeNOP;
        }
        rByte<<=1;
        if((P3IN & BIT2)){
            rByte |= 1;
        } else {
            rByte |= 0;
        }
        set_SD_SCK;
        if(Init_Flag){
            SomeNOP;
        }
    }
    return rByte;    
   
}

//****************************************************************************
//Routine for sending a byte to MMC/SD-Card
void Write_Byte_MMC(unsigned char value)
//****************************************************************************
{ 
    unsigned char i;
    for(i=0;i<8;i++){
        if ((value<<i) & 0x80) {
            set_SD_MOSI;
        } else {
            clr_SD_MOSI;
        }       
        clr_SD_SCK;
        if(Init_Flag){
            SomeNOP;
        }
        set_SD_SCK;
        if(Init_Flag){
            SomeNOP;
        }
    }     
    set_SD_MOSI;    
}
#ifdef DOS_WRITE
//****************************************************************************
//Routine for writing a Block(512Byte) to MMC/SD-Card
//Return 0 if sector writing is completed.
unsigned char MMCWriteSector(unsigned long sector, unsigned char *buf)
//unsigned char MMC_write_sector(unsigned long addr,unsigned char *Buffer)
//****************************************************************************
{  
   unsigned char tmp,retry;
   unsigned int i;
   //Command 24 is a writing blocks command for MMC/SD-Card.
   unsigned char CMD[] = {0x58,0x00,0x00,0x00,0x00,0xFF}; 
//   if(sector>=maxsect) return 1; //sectornumber too big
   
   sector = sector << 9; //addr = addr * 512
	
   CMD[1] = ((sector & 0xFF000000) >>24 );
   CMD[2] = ((sector & 0x00FF0000) >>16 );
   CMD[3] = ((sector & 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_MMC(CMD);
      retry++;
      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++)
   {
      Read_Byte_MMC();
   }
	
   //Send Start Byte to MMC/SD-Card
   Write_Byte_MMC(0xFE);	
	
   //Now send real data Bolck (512Bytes) to MMC/SD-Card
   for (i=0;i<512;i++)
   {
      Write_Byte_MMC(*buf++); //send 512 bytes to Card
   }

   //CRC-Byte 
   Write_Byte_MMC(0xFF); //Dummy CRC
   Write_Byte_MMC(0xFF); //CRC Code
   
    
   tmp=Read_Byte_MMC();   // read response
   if((tmp & 0x1F)!=0x05) // data block accepted ?
   {
     MMC_Disable();
     return(1); //Error!
   }
   //Wait till MMC/SD-Card is not busy
   while (Read_Byte_MMC()!=0xff){};
	
   //set MMC_Chip_Select to high (MMC/SD-Card Invalid)
   MMC_Disable();
   return(0);
} 
#endif
//****************************************************************************
//Routine for reading data Registers of MMC/SD-Card
//Return 0 if no Error.
unsigned char MMC_Read_Block(unsigned char *CMD,unsigned char *Buffer,unsigned int Bytes)
//****************************************************************************
{  
   unsigned int i; unsigned retry,temp;
    
   //Send Command CMD to MMC/SD-Card
   retry=0;
   do
   {  //Retry 100 times to send command.
      temp=Write_Command_MMC(CMD);
      retry++;
      if(retry==100) 
      {
        return(1); //block write Error!
      }
   }
   while(temp!=0); 
   			
   //Read Start Byte form MMC/SD-Card (FEh/Start Byte)
   while (Read_Byte_MMC() != 0xfe){};
	
   //Write blocks(normal 512Bytes) to MMC/SD-Card
   for (i=0;i<Bytes;i++)
   {
      *Buffer++ = Read_Byte_MMC();
   }
   
   //CRC-Byte
   Read_Byte_MMC();//CRC - Byte 
   Read_Byte_MMC();//CRC - Byte
	
   //set MMC_Chip_Select to high (MMC/SD-Card invalid)
   MMC_Disable();
   return(0);
}


//****************************************************************************
//Routine for reading Blocks(512Byte) from MMC/SD-Card
//Return 0 if no Error.
unsigned char MMCReadSector(unsigned long sector, unsigned char *buf)
//unsigned char MMC_read_sector(unsigned long addr,unsigned char *Buffer)
//****************************************************************************
{	
   //Command 16 is reading Blocks from MMC/SD-Card
   unsigned char CMD[] = {0x51,0x00,0x00,0x00,0x00,0xFF}; 
   unsigned char temp;
   
   //Address conversation(logic block address-->byte address)  
   sector = sector << 9; //   addr = addr * 512;

   CMD[1] = (unsigned char)((sector & 0xFF000000) >>24 );
   CMD[2] = (unsigned char)((sector & 0x00FF0000) >>16 );
   CMD[3] = (unsigned char)((sector & 0x0000FF00) >>8 );
   CMD[4] = (unsigned char)((sector & 0x000000FF) );
   temp=MMC_Read_Block(CMD,buf,512);   
   return(temp);
} 



#endif //MMC_CARD_SPI

⌨️ 快捷键说明

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