📄 sd.c
字号:
#include<iom16v.h>
#include<main.h>
#include<sd.h>
extern uint8 BUFFER[512];
uint8 SPI_ReadByte(void)
{
SPDR = 0xFF;
while (!(SPSR & 0x80));
return SPDR;
}
void SPI_TransferByte(uint8 cmp1)
{
SPDR=cmp1;
while(!(SPSR&(1<<SPIF)));
}
void SD_Port_Init(void)
//****************************************************************************
{
SD_PORT |= (1<<SD_SS);//(1<<SD_SCK)
SD_DDR |= (1<<SD_SCK)|(1<<SD_MOSI)|(1<<SD_SS);
SD_DDR &= ~(1<<SD_MISO);
SD_Disable();
}
//****************************************************************************
//Routine for Init MMC/SD card(SPI-MODE)
uint8 SD_Init(void)
//****************************************************************************
{
uint8 retry,temp;
uint8 i;
uint8 CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};
SD_Port_Init(); //Init SPI port
for (i = 0; i < 200; i++) asm("nop"); //Wait MMC/SD ready...
//Active SPI bus at low speed
SPCR=0x53; //SPI Master,MSB First
SPSR=0x00; //double speed disable,Fsck=Fosc/128
for (i = 0; i < 16; i++)
SPI_TransferByte(0xff); //send 74 clock at least!!!
//Send Command CMD0 to MMC/SD Card
SD_Enable();
retry = 0;
do
{ //retry 200 times to send CMD0 command
temp = Write_Command_SD(CMD);
if (retry++ == 200)
return INIT_CMD0_ERROR;//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_SD(CMD);
if (retry++ == 100)
return INIT_CMD1_ERROR;//CMD1 Error!
}
while (temp != 0);
//Active High-speed SPI mode(Fsck=Fosc/2)
SPCR = 0x50;
SPSR = 0x00;
SD_Disable(); //set MMC_Chip_Select to high
return INIT_OK; //All commands have been taken.
}
//****************************************************************************
//Send a Command to MMC/SD-Card
//Return: the second byte of response register of MMC/SD-Card
uint8 Write_Command_SD(uint8 *cmd)
//****************************************************************************
{
uint8 tmp,i;
uint8 retry=0;
SD_Disable();
SPI_TransferByte(0xFF);
SD_Enable();
for(i=0;i<6;i++)
{
SPI_TransferByte(*cmd++);
}
SPI_ReadByte();
do{
tmp = SPI_ReadByte();
}while((tmp==0xff)&&(retry++ <100));
return(tmp);
}
uint8 SD_Read_Block(uint8 *CMD,uint8 *Buffer,uint16 Bytes)
//****************************************************************************
{
uint16 i;
uint8 retry, temp;
//Send Command CMD to MMC/SD-Card
retry=0;
do
{ //Retry 100 times to send command.
temp=Write_Command_SD(CMD);
if(retry++ == 100)
return READ_BLOCK_ERROR; //block write Error!
}
while (temp != 0);
//Read Start Byte form MMC/SD-Card (FEh/Start Byte)
while (SPI_ReadByte() != 0xfe);
//Write blocks(normal 512Bytes) to MMC/SD-Card
for (i = 0; i < Bytes; i++)
{
*Buffer++ = SPI_ReadByte();
// put_c(*Buffer);
}
//CRC-Byte
SPI_ReadByte();//CRC - Byte
SPI_ReadByte();//CRC - Byte
//set MMC_Chip_Select to high (MMC/SD-Card invalid)
SD_Disable();
return READ_BLOCK_OK;
}
//****************************************************************************
//Routine for writing a Block(512Byte) to MMC/SD-Card
//Return 0 if sector writing is completed.
uint8 SD_read_sector(uint32 addr,uint8 *Buffer)
//****************************************************************************
{
//Command 16 is reading Blocks from MMC/SD-Card
uint8 CMD[] = {0x51,0x00,0x00,0x00,0x00,0xFF};
asm("cli"); //clear all interrupt.
//Address conversation(logic block address-->byte address)
addr = addr << 9; //addr = addr * 512
CMD[1] = ((addr & 0xFF000000) >>24 );
CMD[2] = ((addr & 0x00FF0000) >>16 );
CMD[3] = ((addr & 0x0000FF00) >>8 );
return SD_Read_Block(CMD, Buffer, 512);
}
uint8 SD_write_sector(uint32 addr,uint8 *Buffer)
//****************************************************************************
{
uint8 tmp,retry;
uint16 i;
//Command 24 is a writing blocks command for MMC/SD-Card.
uint8 CMD[] = {0x58,0x00,0x00,0x00,0x00,0xFF};
asm("cli"); //clear all interrupt.
addr = addr << 9; //addr = addr * 512
CMD[1] = ((addr & 0xFF000000) >>24 );
CMD[2] = ((addr & 0x00FF0000) >>16 );
CMD[3] = ((addr & 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_SD(CMD);
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++)
SPI_ReadByte();
//Send Start Byte to MMC/SD-Card
SPI_TransferByte(0xFE);
//Now send real data Bolck (512Bytes) to MMC/SD-Card
for (i = 0; i < 512; i++)
SPI_TransferByte(*Buffer++); //send 512 bytes to Card
//CRC-Byte
SPI_TransferByte(0xFF); //Dummy CRC
SPI_TransferByte(0xFF); //CRC Code
tmp=SPI_ReadByte(); // read response
if((tmp & 0x1F) != 0x05) // data block accepted ?
{
SD_Disable();
return WRITE_BLOCK_ERROR; //Error!
}
//Wait till MMC/SD-Card is not busy
while (SPI_ReadByte() != 0xFF){};
//set MMC_Chip_Select to high (MMC/SD-Card Invalid)
SD_Disable();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -