urgent: Interfacing SD Card to Atmega16

Hi friends,

I am working on my final year project. I want to interface SD card to Atmega16 microcontroller using SPI protocol. I tried interfacing but it didnt work. I need your help. Its very urgent. Please guide me on how to interface SD card and how to read and write data. I want to write three values(data) to SD card and I want to read them and display on LEDs. Please help me with interfacing and code. Its really urgent.

Thanks a lot.

Just a hint - if you want help, you need to provide more information, such as schematics and code that you’ve already tried, and the errors you’re having.

If you’re new to embedded electronics, I HIGHLY recommend you just get an Arduino and a suitable shield, since you’ll then be working with proven hardware and software.

Is your SD card running on 3.3V with 3.3v logic levels?

/mike

This is a well known topic, please google the 1000 other projects and instructables which detail how to do this. We don’t do coursework.

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.

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
_