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_