Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

SD card to small RAM PIC (PIC16f877A)

Status
Not open for further replies.

PICMICRO

New Member
I searched around and heard that SD cards work on blocks of 512 bytes so the PIC must have similar amount of free RAM, so its not possible to do with 16F877A.

Suppose I have 1GB SD card, then is it possible to atleast use 1/10th of its capacity i.e. 100MB in the following way.

Write the SD card in block of 512 bytes, but in PIC's RAM store only around 62 bytes. While writing to the card fill the rest 450bytes with same null character 0.

I know moving to higher-end PIC (18Fs) might be better option, but just want to know if its possible that way or not because, 100MB will be more than enough for my purpose.

Also, Is Read also restricted to 512bytes block?

Where can I find specific sequence of SPI commands for issuing write and read commands?
Any link to SD tutorials will be greatly appreciated.
Thanks.
 
Attached are two PDF documents that are excellent. Also attached is a big collection of documents including the official SD card specifications.

The SPI mode is quite simple, but remember to always send the additional clock cycles to the card. This really is essential or commands will mysteriously fail!

Also don't power cards from 5v, even accidentally for a second or two. They really don't like it.. :rolleyes:
 
That's because it's simply writing raw data to the card, no file system at all, so you can't read it on a PC etc.

Yeah.. I know... But the OP doesn't seem to want to read on a PC.... Reading raw is virtually the same as writing to EEprom... But oodles more.
 
Attached are two PDF documents that are excellent. Also attached is a big collection of documents including the official SD card specifications.

The SPI mode is quite simple, but remember to always send the additional clock cycles to the card. This really is essential or commands will mysteriously fail!

Also don't power cards from 5v, even accidentally for a second or two. They really don't like it.. :rolleyes:
Thank you very much.
I think I can now get started.
I will be filling the initial portions of the 512byte block with actual data, and fill the rest with dummy 0x00s.
One thing is bugging me though.
What will be the address of first writable block? 0x0000 ?
Also, I would like to learn to make the datas I write visible as mydata.txt on the SD card when browsed with computer.
Ofcourse, much of the portion of mydata.txt will be filled with dummy 0s, I can manage to write a computer software to sort it out.
 
If you want to write files in a format that a computer can read then FAT is a sensible choice of file system.

The code here is often recommended for microcontroller use:
 
Also, I would like to learn to make the datas I write visible as mydata.txt on the SD card when browsed with computer.
Ofcourse, much of the portion of mydata.txt will be filled with dummy 0s, I can manage to write a computer software to sort it out.

That's not going to be easy. In order for a computer to see it as a file, the card needs to contain a file system. You aren't going to be able to work with a filesystem when you are ignoring 90% of the card's contents.

You could use software on the PC to read and write the raw data from the card, but it's not a simple "double click and there is your data". If you are on a unix-like system you could probably open the device in your favourite editor (assuming appropriate permissions).

The only way that might possibly do what you want (and it's a long shot) would be to create the filesystem and create a large empty file in it, and then work out where the file starts on the physical device and start reading and writing from that location. It would be extremely risky because anything that relocates part of the file would cause corruption of the data. Wear levelling (at the file system level), file system fragmentation (and defragmentation) could all cause a lot of damage. I would strongly suggest that you avoid this option.

As long as you are writing software on the PC anyway, make the software read the data directly from the device rather than trying to use files.
 
I use an add on card... its very simple to use, and plugs onto the Rx and TX pins of my micro. Its an open logger... Primarily used as a data logger but can be used as a filing system.

https://www.sparkfun.com/products/9530

I use it as a datalogging facility...
 
Deleted:
 
Last edited:
That's not going to be easy. In order for a computer to see it as a file, the card needs to contain a file system. You aren't going to be able to work with a filesystem when you are ignoring 90% of the card's contents.

You could use software on the PC to read and write the raw data from the card, but it's not a simple "double click and there is your data". If you are on a unix-like system you could probably open the device in your favourite editor (assuming appropriate permissions).

The only way that might possibly do what you want (and it's a long shot) would be to create the filesystem and create a large empty file in it, and then work out where the file starts on the physical device and start reading and writing from that location. It would be extremely risky because anything that relocates part of the file would cause corruption of the data. Wear levelling (at the file system level), file system fragmentation (and defragmentation) could all cause a lot of damage. I would strongly suggest that you avoid this option.

As long as you are writing software on the PC anyway, make the software read the data directly from the device rather than trying to use files.


One thing is almost clear, I am not going to learn to work with file system <seems too complex>.
So, I will either try to find a way to write a software to read raw files directly from the Card <How easy is that?>, Or

Ian Rogers said:
I use an add on card... its very simple to use, and plugs onto the Rx and TX pins of my micro. Its an open logger... Primarily used as a data logger but can be used as a filing system.

https://www.sparkfun.com/products/9530

I use it as a datalogging facility...
Use another dedicated SD card handler.
Ian, do you make the product yourself?
Since Its an opensource thing, I will try to make that myself. I found the schematic on the link you provided, but I am not sure if I found the correct firmware.
Is this the right firmware: **broken link removed**
?
Thanks.
 
Last edited:
Nowadays I am searching information about using sd cards in my project, I will also use 16f877A in my project, as you mentioned about the problem of 512 bytes and I think another way to solve this problem, my solution is;
Up to 8K x 14 words of FLASH Program Memory,
Up to 368 x 8 bytes of Data Memory (RAM)
Up to 256 x 8 bytes of EEPROM Data Memory
as in the datasheet of the 16f877a, so we may use EEPROM 's 256 byte and then switching to bank1 and use A0h-EFh 80 bytes, then switch bank2 and use 120h-16Fh 80 bytes, bank3 1A0h-1FFh 96 bytes totally 256+256=512 bytes yes this is a hard way but I think it is possible but I didn't tried it yet.
I wanna say something about interfacing the sd card with microcontroller; I am searching this subject since a week ago and I run into chan' s library in everywhere, yes it is very helpfull I thank to chan, I am using assembly language and I am trying to write my program for all of the sd card procedure I found a few examples in assembly and sandisk sd card specification v1.9 is 113 pages I am trying to understand it with the helps of the other resources that I can found, after one week the things get understandable according to the time when I started to study about this subject, I mean don't give up at the and we will find solution.
If you don't want to spend too much afford I saw MDD microchip's multimedia card library it serves anything you want about sd card in a very simple way you don't need to do much thing, library do all of the things for you, but I wanna discovery America again so I had to write all procedures myself.
**broken link removed** at this link there is a gps data logger the program of it written in asm (for pic16f819).
http://antrak.org.tr/index.php?option=com_content&task=view&id=129&Itemid=83 there is another data logger for 18F452 in asm (in Turkish) 18F452 is pin compatible with 16f877a and spi is very similar, between two of them there is mainly stack pointer, 18F452 has 32 bit stack you don't need to page switch in some cases 16f877a needs. In addition to this in this link there is a command list of the sd card, with these commands hex values, it may be helpfull.
http://cubesat.wikidot.com/obdh-sd-card-spec-testing this is a very helpfull program for reading raw data that written to the sd card or any flash card or storage device I think it will help you because it helped me, you may see the blocks and and and what is written to the blocks bytes easily the link has instructions for how to use the program it is very simple.
 
Nowadays I am searching information about using sd cards in my project, I will also use 16f877A in my project, as you mentioned about the problem of 512 bytes and I think another way to solve this problem, my solution is;
Up to 8K x 14 words of FLASH Program Memory,
Up to 368 x 8 bytes of Data Memory (RAM)
Up to 256 x 8 bytes of EEPROM Data Memory
as in the datasheet of the 16f877a, so we may use EEPROM 's 256 byte and then switching to bank1 and use A0h-EFh 80 bytes, then switch bank2 and use 120h-16Fh 80 bytes, bank3 1A0h-1FFh 96 bytes totally 256+256=512 bytes yes this is a hard way but I think it is possible but I didn't tried it yet.

EEPROM is painfully slow, it makes FAR more sense to use a more modern higher spec PIC.
 
Got something

I searched around and found a simple SD card routines written for AVR.
I adapted it for PIC and it does work very well in Proteus ISIS simulation <using multimedia card>.

Code:
#include<htc.h>
//__CONFIG(HS & LVPDIS & BORDIS & PWRTDIS & WDTDIS & DEBUGDIS);

#define _XTAL_FREQ 20000000
#define CS RC0
#define CS_tris TRISC0

#define But_write RB2
#define But_read RB3
#define But_inc RB0
#define But_dec	RB1
#define BinToASCII(t) ((t<=9) ? (t|0x30):(t+55))
#define ASCIIToBin(t) ((t>='A'&& t<='F')?t-55:((t>='0'&& t<='9') ? t-'0':0))
#define BYTELOW(v)  (*((unsigned char *)(&v))) 
#define BYTEHIGH(v) (*(((unsigned char *)(&v) + 1)))
#define BLOCK_SIZE	512	

volatile bit command_aayo=0;
volatile char cmd;
const unsigned char  CMD0_RST_IDLE[]= {0x40,0x00,0x00,0x00,0x00,0x95};
					 //command 0 reset all card to idle state	
const unsigned char	 CMD1_SND_OPCND[]= {0x41,0x00,0x00,0x00,0x00,0xFF};
					 //command 1 for read OPERATION CONDITION register 
const unsigned char	 CMD16_SET_BLOCKLEN[]= {0x50,0x00,0x00,0x02,0x00,0xFF};
	  		   		 //command 16 TO SET BLOCK LENGHT=512 BYTE TO READ & WRITE
					 //0x000200=512 & 0x00000010=16
const unsigned char	MSGF[] ={"\rMMC CARD INTERFACE\r"};
const unsigned char	MSG0[] ={"\rMMC CARD COMMAND 0\r"};
const unsigned char	MSG1[] ={"\rMMC CARD COMMAND 1\r"};
const unsigned char	MSGB[] ={"\rMMC CARD COMMAND BLOCK=512\r"};
const unsigned char	MSGW[] ={"\rMMC CARD SECTOR WRITE\r"};
const unsigned char	MSGR[] ={"\rMMC CARD SECTOR READ\r"};
const unsigned char	MSG[]  ={"\nMMC CARD IS INITIALIZED SPI MODE\n"};
const unsigned char	CSD[]  ={"\rCSD INFORMATION:\r"};	
const unsigned char	CID[]  ={"\rCID INFORMATION:\r"};
const unsigned char	WACK[] ={"\rWRITE ACKNOLEDGE:\r"};
const unsigned char	WNFSH[]={"\rWRITE NOT FINISH:\r"};
const unsigned char	MSG_retry[]={"\r retry \r"};
const unsigned char	cmd_rcv[]  ={"\rCommand Recieved: \r"};
unsigned char TEMP;
unsigned int iSIZE;
unsigned int iSIZE1;
unsigned char BUFFER[50];


unsigned char adc_low,adc_high;
unsigned int timer0_counter=0;

unsigned char Data=65;

unsigned int RdFlag=0,WrtFlag=0;

void delay_10ms(char x)
{
	while(x--) __delay_ms(10);
	return;
}
void uart0_init(void)
{
 		TRISC6=0;
		TRISC7=1;
		SYNC=0;	 // no synch	
		SPBRG=10;	// 113636.36 baud at 20Mhz. Very Near to 115200. 1.35% error.
		BRGH=1;	// low baud rate
		SPEN=1; //enable the serial port
		TX9=0;	// no pairity bit
		TXEN=1;	// Start Transmission
		CREN=1; //recieve data too
		TXIE=0;	// no intrpt
		RCIF = 0;	
		RCIE = 1;
}
void SpiInit(){
SSPSTAT = 0b10000000; // middle/active->idle/...
TRISC4 = 1;
TRISC5 = 0;
TRISC3 = 0;
CS_tris = 0;
SSPCON = 0b00110010; //FOSC/64 <make b0-b3 = 0000 for fosc/4
}
unsigned char ReceiveByte()
{
	  while(!RCIF);
	  return RCREG;
}
void SEND_CHAR_UART(char ch)
{
	  while(!TXIF);
	  TXREG = ch;  
}
void SendStr(const char *ch)
{
      while(*ch != 0x00) 
	  SEND_CHAR_UART(*ch++);
}
void PRINT_ASCII (unsigned char PRNT)
{
	  unsigned char PRN=0;
	  PRN=PRNT>>4; 
 	  SEND_CHAR_UART(BinToASCII(PRN));  
      PRN=PRNT&0x0F;
	  SEND_CHAR_UART(BinToASCII(PRN));  	  
} 

unsigned char CHAR_SPI(unsigned char byte) //both reads and writes a byte
{
	  SSPIF = 0;
	  SSPBUF = byte;
      while (!SSPIF);
	  SSPIF = 0;
	  return SSPBUF;
	  
}
unsigned char MMC_RESPONCE(unsigned char RESPONSE )
{
		unsigned int COUNT=0xFFF; // for 64 MB card 
 	//	unsigned int COUNT=0xFFFF;  // for 1 GB
		unsigned  char  RESULT;
		while(COUNT!=0)
		{
			  RESULT = CHAR_SPI(0xFF);
    		  // PRINT_ASCII (RESULT);	 SEND_CHAR_UART('\r');	//debug
		 	  if(RESULT==RESPONSE) break;
			  COUNT--;
		}
		if(COUNT==0)return 1;
		else return 0;
}
/***************************************************/  
unsigned char MMC_WAIT_FOR_WRITE_FINISH( void ) 
{ 
		unsigned char LPCNT=0xFF;
		unsigned char  RESULT = 0;
		/* The delay is set to maximum considering the longest data block length to handle */
  		while( (RESULT == 0) && LPCNT ) 
 		{ 
		         RESULT = CHAR_SPI( 0XFF);
		  		 LPCNT--;
		}
		if (LPCNT== 0 ) 
   		return 1;    	 /* Failure, loop was exited due to timeout */ 
		else return 0;  /* Normal , loop was exited before timeout */
}
/*-----------------------------------------------------------------------------*/
unsigned char  MMC_INIT()
{
        unsigned char LPCNT=0;
		/* start off with 80 bits of high data with card deselected */
		CS = 1; //deselect
		for(LPCNT=0;LPCNT<10; LPCNT++)
		CHAR_SPI(0xff);
/*-----------------------------------------CMD 0-------------------------------*/		 
		CS=0;        /* select card */
		CHAR_SPI( 0X40);CHAR_SPI( 0X00);CHAR_SPI( 0X00);
		CHAR_SPI( 0X00);CHAR_SPI( 0X00);CHAR_SPI( 0X95);
		 
		if( (MMC_RESPONCE(0x01)) == 1 )
		{
			//fail
			CS = 1;
			return 1;
		}
		SendStr(MSG0);
/*-----------------------------------------------------------------------------*/ 
 	    CS = 1;
	    CHAR_SPI(0xFF); 
/*----------------------------------CMD1---------------------------------------*/ 
	    CS = 0;   
	    LPCNT=0xFF;
	    do
	    {
			   CHAR_SPI( 0X41);   CHAR_SPI( 0X00);     CHAR_SPI( 0X00);
		       CHAR_SPI( 0X00);   CHAR_SPI( 0X00);     CHAR_SPI( 0XFF);
		 	   LPCNT--;
	    } while ( (MMC_RESPONCE(0x00) != 0) && (LPCNT>0) );
		if(LPCNT==0)
		{	  
		     CS = 1; //fail 	   
		     return 1;   
		}
		
        SendStr(MSG1);		
/*--------------------------------------------------------------------*/ 
 	    CS = 1;
	    CHAR_SPI(0xFF); 
/*---------------------CMD16  SET BLOCK LENGTH------------------------*/ 	 
	
		CS = 0;        // select card 
		CHAR_SPI( 0X50); CHAR_SPI( 0X00);  CHAR_SPI( 0X00);
		CHAR_SPI( 0X02); CHAR_SPI( 0X00);  CHAR_SPI( 0XFF);
		if( (MMC_RESPONCE(0x00)) == 1 )
		{
			 CS = 1; //fail
			 return 1;
		}
        SendStr( MSGB);
        CS = 1;
        CHAR_SPI(0xFF); 
		
        return 0;
}
/*----------------------------------------------------------- */
void GET_CSD()
{
		 CS = 0;  
		 CHAR_SPI( 0x49);   CHAR_SPI( 0x00);     CHAR_SPI( 0X00);
		 CHAR_SPI( 0x00);   CHAR_SPI( 0x00);     CHAR_SPI( 0XFF);
         while ((MMC_RESPONCE(0x00)) == 1);
 	     while( (MMC_RESPONCE(0xFE)) == 1 );
		 for(TEMP=0;TEMP<=35;TEMP++)
		 BUFFER[TEMP]=CHAR_SPI(0xFF);
         SendStr(CSD);
		 for(TEMP=0;TEMP<=15;TEMP++)
		 PRINT_ASCII(BUFFER[TEMP]);
	     SEND_CHAR_UART('\n');
         CS = 1;       // Deselect card
}
/*----------------------------------------------------------- */
void GET_CID()
{
		 CS=0;       // select card 
		 CHAR_SPI(0x4A); CHAR_SPI(0x00);  CHAR_SPI(0X00);
		 CHAR_SPI(0x00); CHAR_SPI(0x00);  CHAR_SPI(0XFF);
         while ((MMC_RESPONCE(0x00)) == 1);
	     while( (MMC_RESPONCE(0xFE)) == 1 );
		 for(TEMP=0;TEMP<=35;TEMP++)
		 BUFFER[TEMP]=CHAR_SPI(0xFF);
         SendStr(CID);
		 for(TEMP=0;TEMP<=15;TEMP++)
		 PRINT_ASCII(BUFFER[TEMP]); 
         SEND_CHAR_UART('\n');
         CS=1;       // Deselect card
  
}
/*----------------------------------------------------*/
void INSULATOR()
{ 
     CHAR_SPI( 0xFF);CHAR_SPI( 0xFF);CHAR_SPI( 0xFF);
	 CHAR_SPI( 0xFF);CHAR_SPI( 0xFF);CHAR_SPI( 0xFF);
	 CHAR_SPI( 0xFF);CHAR_SPI( 0xFF);CHAR_SPI( 0xFF);
	 CHAR_SPI( 0xFF);CHAR_SPI( 0xFF);CHAR_SPI( 0xFF);
	 CHAR_SPI( 0xFF);CHAR_SPI( 0xFF);CHAR_SPI( 0xFF);
	 CHAR_SPI( 0xFF);CHAR_SPI( 0xFF);CHAR_SPI( 0xFF);
	 CHAR_SPI( 0xFF);CHAR_SPI( 0xFF);
}

/*--------------------------------------------------------------------------------------*/
unsigned char MMC_WRITE_BLOCK( unsigned   int SECTOR)
{
 		 unsigned char WRT=65;// A
		 unsigned int LPCNT=0;
 		 unsigned long ADDRESS=0;
		 ADDRESS=(unsigned long)SECTOR*BLOCK_SIZE;
 	 
/*-----------------------CMD24------------------------------------------------*/		 
		 CS = 0; 
		 
		 CHAR_SPI( 0x58); 
		 CHAR_SPI (ADDRESS>>24); 		 CHAR_SPI (ADDRESS>>16);
		 CHAR_SPI (ADDRESS>>8);  		 CHAR_SPI (ADDRESS>>0);     
		 CHAR_SPI( 0xFF);

		 
		 	 if( (MMC_RESPONCE(0x00)) == 1 )
			 {
				CS=1;
				return 1;
			  }
		   
		   CHAR_SPI(0xFF); 
		   CHAR_SPI(0xFE);					 //start of DATABLOCK

             			 
			 
			 for(LPCNT=0;LPCNT<511; LPCNT++) //12 times 
			 { 
			   	 CHAR_SPI(Data);
				 //CHAR_SPI(WRT);
				 //SEND_CHAR_UART(WRT);
			 }
			 /*for(LPCNT=0;LPCNT<10; LPCNT++) //10 times main loop
			 { 
				 unsigned char temp_data;
				temp_data = ReceiveByte();
				for (unsigned char j=0;j<50;j++){ //x50 = 500 times
			   	 CHAR_SPI(temp_data);
				}
				 //CHAR_SPI(WRT);
				 //SEND_CHAR_UART(WRT);
			 }
			 */
		   CHAR_SPI(0xFF); CHAR_SPI(0xFF);   // dummy chksum
		   
		   
		 LPCNT= CHAR_SPI(0xFF); 
		 
		 //SendStr(WACK);	PRINT_ASCII(LPCNT);	PRINT_ASCII((LPCNT & 0x0F)); // disabled for debugging 
 		 
		 if ( (LPCNT & 0x0F) != 0x05 )
	 		{
						CS=1;
						return 1;
			}
				
                   if( MMC_WAIT_FOR_WRITE_FINISH()==1)  //disabled for debugging
				    {
				   	   		SendStr(WNFSH); // disabled for debugging           //-----------------------
				   	 		CS = 1;
				    		    return 1;
                    }
//SendStr( MSGW); //disabled for debugging
/*----------------------------------------------------------------------------------------------------*/
CS=1;
CHAR_SPI(0xFF);  
return 0;
}    
/*----------------------------------------------------------------------------------------------------*/
unsigned char  MMC_READ_BLOCK( unsigned long SECTOR)
{

unsigned int LPCNT=0;
unsigned long ADDRESS=0;
unsigned char mmcData=0;

ADDRESS=(unsigned long)SECTOR*BLOCK_SIZE;
 
		 
/*-----------------------CMD17------------------------------------------------*/		 
// CMD17 READ_SINGLE_BLOCK
// Function : Single block read  
// [31:0] Data address R1

		 CS=0; // Deslect Card
		 
		 CHAR_SPI( 0x51); 
		 
		 CHAR_SPI (ADDRESS>>24); 		 CHAR_SPI (ADDRESS>>16);
		 CHAR_SPI (ADDRESS>>8);  		 CHAR_SPI (ADDRESS>>0);     
		 
		 CHAR_SPI( 0xFF);

		 	 if( (MMC_RESPONCE(0x00)) == 1 )
			 {  CS=1;
				return 1;
			 }
			 
			 //////////////////////////////////////////////////////////////////
             
			 //while( (MMC_RESPONCE(0xFE)) == 1 ) // disabled for debugging
			 //SEND_CHAR_UART('r');               // disabled for debugging
			 
			 //////////////////////////////////////////////////////////////////
			 	
			 
			 while( (MMC_RESPONCE(0xFE)) == 1 ); // added for debugging         //---------
			
			
			 for(LPCNT=0;LPCNT<512;LPCNT++)
			 {
			      
						
						if((LPCNT%32)==0){SEND_CHAR_UART('\n');SEND_CHAR_UART('\r');} 
						
						mmcData=CHAR_SPI(0xFF);
						SEND_CHAR_UART(mmcData); // added for debugging
				  		 
			  }	
			 	 			 

			CHAR_SPI(0xFF);  CHAR_SPI(0xFF);  //read CHKSUM
//SendStr( MSGR); // disabled for debugging
/*----------------------------------------------------------------------------*/
 CS=1;; // deslect card
 CHAR_SPI(0xFF);  

return 0;

}    						

void interrupt isr(void){
	if(RCIE && RCIF){
	command_aayo = 1;
	cmd = RCREG;
	}

}
void main()
{
       
		   
    	 int i=0,LPCNT=0;
        unsigned char rData;
    	 unsigned int SECT=200;
		OPTION = 0b10000111; //prescalare 1:256 for tmr0;
		TRISB = 0x00; //input
		TRISA = 0x00;
		TRISD = 0x00; //all output
	//	PORTD = SECT;
		TMR0IF = 0;
		TMR0IE = 1;
		SpiInit();
	    uart0_init(); // for baud rate of 115200 bps
		T0IE = 0;
		TMR1IE = 0;
		SSPIE = 0;
		PEIE = 1;
		GIE = 1;
	//	while(1){
		SEND_CHAR_UART('a');
  	    SEND_CHAR_UART('b');
	//	}
        SendStr( MSGF);   
		////////////////////////////////////////////////////////////////////////////////
  	 while ( MMC_INIT() != 0)
  	 { 
      	   SendStr( MSG_retry);
	  	   //SEND_CHAR_UART(0x0D);
      	   //SEND_CHAR_UART(0x0A);
	  	   //break; disabled for debugging 
  	 }
		 SEND_CHAR_UART(0x0D);	
  	 SEND_CHAR_UART(0x0A);	// MSG[]  ={"\nMMC CARD IS INITIALIZED SPI MODE  \n"};

  	 INSULATOR();
 
  	 GET_CSD();	   	 
  	 INSULATOR(); 
  	 GET_CID();	 	 
  	 INSULATOR(); 

	 RdFlag=0,WrtFlag=1;
  
    
   	 while(1)
   	 {//start of while loop for data read & write
   
   			
			  ////////////////////////// write routine ///////////////////////////
			if(command_aayo==1){ //flag to test if command recieved
			  if(cmd=='C'){
						SendStr(cmd_rcv);
					  	 GET_CID();	 	 
  						 INSULATOR();
				}
			  if(cmd=='W')
   			  {//if for write button
              
			        /////////////////////////////////////////////////////
  			        //Routines for writing data
  			     	SendStr(cmd_rcv);
					MMC_WRITE_BLOCK(SECT);
					
					INSULATOR();
					Data++;
		          	delay_10ms(50);
				
  			  }//end of if block for write button
			
 			  ///////////////// end of write routine /////////////////////////////
			
			  if(cmd=='R')
    		  {
					SendStr(cmd_rcv);
			         
			          // Routine for reading data
	 	          	 MMC_READ_BLOCK(SECT);INSULATOR();				 
					 delay_10ms(50);
				   	       
	 	   	  }// closing bracket of if block for reading data
			  
			command_aayo=0;
	  } 	 
   
     }//ending bracket for while loop for read & write 	    
		
}

However when connected to hardware its showing erroneous behaviors such as:
1.Not getting CID values
2.Getting corrupt CID values. <I know this because it changes every-time I manage to get CID>
3. Hanging up after command 0. <i.e. no response when command 1 is sent>
etc.

Could it be because there is different initialization routine for SD and MMC ?
Could it be because of too high frequency? < I am using Fosc / 64 (Fosc = 20mhz) >
Could it be because I am just using inline current limiting resisters (5k) for level translation ? (5v - 3.3V)
What else could it be?
 
As if I read in the SD specs.
Could it be because I am just using inline current limiting resisters (5k) for level translation ? (5v - 3.3V)
You must be capable of supplying at least 100 mA for card to read write properly but you just have to do it for VDD pin, for data pins you may use resistors for level translations.

Could it be because of too high frequency? < I am using Fosc / 64 (Fosc = 20mhz)
As Chan (we gave the link in our old messages, at chan's document "Initialization Procedure for SPI Mode" label ) and SD specs. shows there is a inialization procedure and at the time when the SD card in inialization you need to lower the SCK frequency up to 400 kHz.

Could it be because there is different initialization routine for SD and MMC ?
Chan's flowchart may be useful for supporting or defining to different card types.
 
Status
Not open for further replies.

Latest threads

Back
Top