Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

SD Card interfacing with Atmega16

Status
Not open for further replies.

manojspam

Newbie level 2
Joined
Jan 20, 2010
Messages
2
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Location
Hubli
Activity points
1,346
Dear friends,
I am working on interfacing SD card with Atmega16. But its not working. I ve done the following work. I dont know where i am going wrong. Please help me. its urgent.

Hardware Interfacing: I ve interfaced Atmega16 to SD card using SPI protocol with voltage divider circuit.

Software Code: Following is the code which i ve written. I have written 0 to 511 in "buffer" array. I want this to be stored in sd card. Then I would like to read it back from sd card and display on lcd screen(I ve not written lcd module here).


/**********main.c file*************/



#include <avr/io.h>
#include "MMC_SD.h"
#include "MMC_SD.c"
#include<util/delay.h>

main()
{
unsigned int r1=1, capacity=0,i;
unsigned long sector = 10;
unsigned char buffer[512];

SPI_Init();
MMC_SD_Init();

do
{
r1 = MMC_SD_Reset(); // SD card reset and initialisation

}while(r1 != 0);


capacity = MMC_SD_ReadCapacity(); // Capacity of SD card

for( i=0 ; i<512 ; i++ )
buffer = i;



// writing block
// r1 = MMC_SD_WriteSingleBlock(sector, buffer);

r1 = 1;

do
{
r1 = MMC_SD_WriteSingleBlock(sector, buffer);

}while(r1 != 0);


// Reading Block
//r1 = MMC_SD_ReadSingleBlock(sector, buffer);
r1 = 1;
do
{
r1 = MMC_SD_ReadSingleBlock(sector, buffer);

}while(r1 != 0);

}


/***********MMC_SD.c file*********/


#include <avr/io.h>
#include "MMC_SD.h"




//spi low speed
void SPI_Low(void)
{
SPCR = _BV(SPE)|_BV(MSTR)|_BV(SPR1)|_BV(SPR0);
SPSR &= ~_BV(SPI2X);
}

//spi full speed
void SPI_High(void)
{
SPCR = _BV(SPE)|_BV(MSTR);
SPSR |= _BV(SPI2X);
}

//port initialize
void SPI_Init(void)
{
DDR_INI();
SPI_Low();
}

//read and write one byte
uint8 SPI_WriteByte(uint8 val)
{
SPDR = val;
while(!(SPSR & _BV(SPIF)));
return SPDR;
}

/*uint8 SPI_ReadByte(void)
{
SPDR = 0xff;
while(!(SPSR & _BV(SPIF)));
return SPDR;
}*/
//sd card initialize
void MMC_SD_Init(void)
{
SPI_Init();
SPI_CS_Deassert();
}

//sd send command
uint8 MMC_SD_SendCommand(uint8 cmd, uint32 arg)
{
uint8 r1;
uint8 retry=0;

SPI_WriteByte(0xff);
SPI_WriteByte(0xff);
SPI_WriteByte(0xff);
SPI_WriteByte(0xff);
SPI_WriteByte(0xff);
SPI_WriteByte(0xff);

SPI_CS_Assert();

SPI_WriteByte(cmd | 0x40); //send command
SPI_WriteByte(arg>>24);
SPI_WriteByte(arg>>16);
SPI_WriteByte(arg>>8);
SPI_WriteByte(arg);
SPI_WriteByte(0x95);

while((r1 = SPI_WriteByte(0xff)) == 0xff) //wait response
if(retry++ > 100) break; //time out error

SPI_CS_Deassert();

return r1; //return state
}

//reset sd card (software)
uint8 MMC_SD_Reset(void)
{
uint8 i;
uint8 retry;
uint8 r1=0;
retry = 0;
SPI_Low();

do
{
for(i=0;i<100;i++) SPI_WriteByte(0xff);
r1 = MMC_SD_SendCommand(0, 0); //send idle command
retry++;
if(retry>10) return 1; //time out
} while(r1 != 0x01);


retry = 0;
do
{
r1 = MMC_SD_SendCommand(1, 0); //send active command
retry++;
if(retry>100) return 1; //time out
} while(r1);
SPI_High();
r1 = MMC_SD_SendCommand(59, 0); //disable CRC

r1 = MMC_SD_SendCommand(16, 512); //set sector size to 512
return 0; //normal return
}

//read one sector
uint8 MMC_SD_ReadSingleBlock(uint32 sector, uint8 buffer[512])
{
uint8 r1;
uint16 i;
uint8 retry=0;

do
{
r1 = MMC_SD_SendCommand(17, sector<<9); //read command
retry++;
if(retry>10) return 1; //time out
} while(r1 != 0x00);


SPI_CS_Assert();
//wait to start recieve data
while(SPI_WriteByte(0xff) != 0xfe);//if(retry++ > 50){SPI_CS_Deassert();return 1;}

for(i=0; i<512; i++) //read 512 bytes
{
buffer = SPI_WriteByte(0xff);
}

SPI_WriteByte(0xff);//αcrc
SPI_WriteByte(0xff);

SPI_CS_Deassert();

return 0;
}


//wirite one sector //not used in this application
uint8 MMC_SD_WriteSingleBlock(uint32 sector, uint8 buffer[512])
{
uint8 r1;
uint16 i;
uint8 retry=0;

do
{
r1 = MMC_SD_SendCommand(24, sector<<9); //send command
retry++;
if(retry>10) return 1; //time out
} while(r1 != 0x00);



SPI_CS_Assert();

SPI_WriteByte(0xff);
SPI_WriteByte(0xff);
SPI_WriteByte(0xff);
SPI_WriteByte(0xff);
SPI_WriteByte(0xff);
SPI_WriteByte(0xff);

SPI_WriteByte(0xfe); //send start byte

for(i=0; i<512; i++) //send 512 bytes data
{
SPI_WriteByte(buffer);
}

SPI_WriteByte(0xff);
SPI_WriteByte(0xff);

r1 = SPI_WriteByte(0xff);

if( (r1&0x1f) != 0x05) //judge if it successful
{
SPI_CS_Deassert();
return r1;
}
//wait no busy
while(!SPI_WriteByte(0xff));//if(retry++ > 50){SPI_CS_Deassert();return 1;}

SPI_CS_Deassert();

return 0;
}

uint32 MMC_SD_ReadCapacity(void)
{
uint8 r1;
uint16 i;
uint16 temp;
uint8 buffer[16];
uint32 Capacity;
//uint8 retry=0;

r1 = MMC_SD_SendCommand(9, 0); //send command //READ CSD
if(r1 != 0x00)
return r1;

SPI_CS_Assert();
while(SPI_WriteByte(0xff) != 0xfe);

for(i=0;i<16;i++)
{
buffer=SPI_WriteByte(0xff);
}

SPI_WriteByte(0xff);
SPI_WriteByte(0xff);

SPI_WriteByte(0xff);

SPI_CS_Deassert();

/*********************************/
// C_SIZE
i = buffer[6]&0x03;
i<<=8;
i += buffer[7];
i<<=2;
i += ((buffer[8]&0xc0)>>6);

/**********************************/
// C_SIZE_MULT

r1 = buffer[9]&0x03;
r1<<=1;
r1 += ((buffer[10]&0x80)>>7);


/**********************************/
// BLOCKNR

r1+=2;

temp = 1;
while(r1)
{
temp*=2;
r1--;
}

Capacity = ((uint32)(i+1))*((uint32)temp);

/////////////////////////
// READ_BL_LEN

i = buffer[5]&0x0f;

/*************************/
//BLOCK_LEN

temp = 1;
while(i)
{
temp*=2;
i--;
}
/************************/



Capacity *= (uint32)temp;
return Capacity;
}



/****************MMC_DC.h File********* ****/

#ifndef __MMC_SD_h__
#define __MMC_SD_h__

#define uint8 unsigned char
#define int8 signed char
#define uint16 unsigned int
#define int16 signed int
#define uint32 unsigned long
#define int32 signed long



#define MMC_SD_PORT PORTB
//#define MMC_SD_CS_PIN 4
#define MMC_SD_CS_PIN 2 //mega8
//#define DDR_INI() DDRB |=_BV(4)|_BV(5)|_BV(7)
#define DDR_INI() DDRB |= _BV(2)|_BV(3)|_BV(5) //mega8
#define SPI_CS_Assert() MMC_SD_PORT &= ~_BV(MMC_SD_CS_PIN)
#define SPI_CS_Deassert() MMC_SD_PORT |= _BV(MMC_SD_CS_PIN)


extern void MMC_SD_Init(void);
extern uint8 MMC_SD_Reset(void);
extern uint8 MMC_SD_ReadSingleBlock(uint32 sector, uint8* buffer);
extern uint8 MMC_SD_WriteSingleBlock(uint32 sector, uint8* buffer);
extern void SPI_High(void);
extern uint8 MMC_SD_SendCommand(uint8 cmd, uint32 arg);
extern uint8 SPI_WriteByte(uint8 val);

extern uint32 MMC_SD_ReadCapacity(void);
#endif
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top