📄 sdcard.c
字号:
#include "SDCard.h"
unsigned char sdBuffer[512];
unsigned char SPITransfer(unsigned char data)
{
/* 启动数据传输 */
SPDR = data;
/* 等待传输结束 */
while(!(SPSR & (1<<SPIF)));
// Fetch data
return SPDR;
}
unsigned char sdSendCommand(unsigned char index, unsigned long argument)
{
unsigned char result;
unsigned char cntNcr = 0;
//Transmit Command
//1. Transmit index
SPITransfer(index|0x40);
//2. Transimit argument
SPITransfer( *((unsigned char*)&argument+3) );
SPITransfer( *((unsigned char*)&argument+2) );
SPITransfer( *((unsigned char*)&argument+1) );
SPITransfer( *((unsigned char*)&argument+0) );
//3.Transimit CRC
if(!index) //CMD0
SPITransfer(0x95);
else
SPITransfer(0xff); //has 1 end bit
//Transimit Ncr H to wait for 1 byte Response
do
{
result = SPITransfer(0xff);
if(cntNcr++>8)
return 0xff; //No Card
}while(result&0x80); //the MSB = 1;
return result;
}
unsigned char sdReceiveDataBlock(unsigned short length, unsigned short timeout)
{
unsigned char result;
unsigned short cnt = 0;
//Transimit Ncr H to wait for StartBlock=0xFE
do
{
result = SPITransfer(0xff);
if(cnt++>timeout)
return SDERR_TIMEOUT; //No Card
}while(result!=0xFE); //theSTART Block;
//Receive datablock
for(cnt=0;cnt<length;cnt++)
sdBuffer[cnt] = SPITransfer(0xff); //Transfer H to get data
//Receive CRC
SPITransfer(0xff);
SPITransfer(0xff);
return 0;
}
//===========High level Command===========
unsigned char sdInitCard()
{
unsigned char result;
result = sdSendNoDataCommand(0x00,0x00); //Send Command 0 = 40 00 00 00 00 95h
result = sdSendNoDataCommand(0x00,0x00); //Send Command 0 = 40 00 00 00 00 95h
if(result==0xff)
return result; //No card! Exit 1 : CMD0 Error CMD0 Should return 0x01;
do
{
result = sdSendNoDataCommand(0x01,0x00); //Send Command 1. No argument = argument set to 0
}while(result);
return result; //0=OK, !=0 ==> Exit2 :CMD1 Error. At last should return 0x00;
}
unsigned char sdSendNoDataCommand(unsigned char index, unsigned long argument)
{ //used by init
unsigned char result;
// Assert SS
assertSS();
result = sdSendCommand(index,argument);
// Deassert CS
deassertSS();
SPITransfer(0xff);
return result;
}
unsigned char sdReadCSD()
{
unsigned char result;
// Assert SS
assertSS();
result = sdSendCommand(0x09,0x00); //No argument
sdReceiveDataBlock(16,8); //Length=16, timeout=8
deassertSS();
SPITransfer(0xff);
return result;
}
unsigned char sdReadData(unsigned long address) // 2 Error exits
{ //Only suitable for default 512 byte mode
unsigned char result;
// Assert SS
assertSS();
// send Command
result = sdSendCommand(0x11,address); //argument=address
if(result)
return result; //Exit 1: ersponse Error
result = sdReceiveDataBlock(512,256); //Length=16, timeout=256
deassertSS();
SPITransfer(0xff);
return result; // 0 = OK. !=0 --> Error. Exit 2: TimeOut
}
unsigned char sdWriteData(unsigned long address) //
{ //Only suitable for default 512 byte mode
unsigned char result;
unsigned short cnt;
// 1.Assert SS
assertSS();
// 2. Send Command & wait for Response
result = sdSendCommand(0x18,address); //argument=address
if(result)
return result; //Exit 1 : response Error
// 3. Write 1 byte H (Nwr>=1)
SPITransfer(0xFF);
SPITransfer(0xFF);
// 4. Write DataBlock
// 4.1 Start Token
SPITransfer(0xFE);
// 4.2 Data
for(cnt = 0;cnt<512;cnt++)
SPITransfer(sdBuffer[cnt]);
// 4.3 CRC & end bit. The last bit should be 1
SPITransfer(0xFF);
SPITransfer(0xFF);
//5. Read DataResponse (immediatly after DataBlock)
result = SPITransfer(0xFF);
result &= 0x1F; //only last 5 bits are meaningful
if(result!=0x05)
return result; //Exit 2 : data response Error
//6. Wait while Busy
while(SPITransfer(0xFF) != (unsigned char)0xFF);
//7. Dessert SS
deassertSS();
SPITransfer(0xff);
return 0; // 0=OK, check
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -