https://static.assets-stash.eet-china.com/album/old-resources/2009/3/13/87669dea-fc53-4cba-8d0d-e1fc25c795ff.rar
#include"lpc214x.h"
#include "head.h" //定义一些数据结构
#define SD_Disable() IO0SET |= 1 << 20 //SD Chip Select Pin is P0.7
#define SD_Enable() IO0CLR |= 1 << 20
INT8U CMD[]={0x40, 0x00, 0x00, 0x00, 0x00, 0x95};
INT8U SPI_RW(INT8U data)
{
SSPDR = data;
while((SSPSR & 0x01) == 0);
return(SSPDR);
}
void spi_init (void)
{
INT32U i;
/* SSEL is GPIO, output set to high. */
IODIR0 |= 1<<20;
IOSET0 = 1<<20;
/* SCK1, MISO1, MOSI1 are SSP pins. */
PINSEL1 = (PINSEL1 & ~0x000003FC) | 0x000000A8;
/* Enable SPI in Master Mode, CPOL="1", CPHA="1" (Clock low-active). */
SSPCR0 = 0x00C7;
SSPCR1 = 0x0002;
SSPCPSR = 0x7E;
/* Send SPI Command with card not selected at 400 KBit. */
for (i = 0; i < 16; i++) {
SPI_RW (0xFF);
}
/* Enable SSP auto select. */
}
INT8U Write_Command_SD(INT8U *CMD)
{
INT8U i = 0, response = 1, retry = 0;
SD_Disable();
SPI_RW(0xff);
SD_Enable();
for(i = 0; i < 0x06; i++)
{
SPI_RW(*CMD++);
}
SPI_RW(0xff);
do
{
response = SPI_RW(0xff);
retry++;
}
while((response== 0xff) && (retry < 100));
return(response);
}
INT8U SD_write_sector(INT32U Number_Sector, INT8U* Buffer)
{
INT8U response,response_1,retry;
INT16U i;
//Command 24 is a writing blocks command for SD/SD-Card.
INT8U CMD[] = {0x58, 0x00, 0x00, 0x00, 0x00, 0xFF};
INT8U CMD_SET_BLOCKLEN[]={0x50,0x00,0x00,0x02,0x00,0xFF}; //设定读取块大小
retry = 0;
SSPCPSR = 0x7E;
do
{ //Retry 100 times to send command.
response = Write_Command_SD(CMD_SET_BLOCKLEN);
if(++retry >= 100)
return(1); //block read Error!
}
while(response != 0);
SPI_RW(0XFF);
Number_Sector <<= 9; //addr = addr * 512
CMD[1] = ((Number_Sector & 0xFF000000) >> 24 );
CMD[2] = ((Number_Sector & 0x00FF0000) >> 16 );
CMD[3] = ((Number_Sector & 0x0000FF00) >> 8 );
CMD[4] = ((Number_Sector & 0x000000FF) >> 0) ;
//Send Command CMD24 to SD/SD-Card (Write 1 Block/512 Bytes)
retry = 0;
do
{ //Retry 100 times to send command.
response = Write_Command_SD(CMD);
if(++retry >= 100)
{
return(1); //send commamd Error!
}
}
while(response != 0);
// for(i = 0; i < 20; i++)
SPI_RW(0xff);
//Send Start Byte to SD/SD-Card
SPI_RW(0xfe);
SSPCPSR = 0x04;
//Now send real data Bolck (512Bytes) to SD/SD-Card
for(i = 0; i < 512; i++)
SPI_RW(* Buffer++); //send 512 bytes to Card
//CRC-Byte
SPI_RW(0xFF); //Dummy CRC
SPI_RW(0xFF); //CRC Code
// retry="0";
do
{
response="SPI"_RW(0xFF);//Read Response
}
while(response==0xff);
do
{
response_1=SPI_RW(0xFF);
}
while(response_1!=0xFF);
SD_Disable();
SPI_RW(0xff);
if ((response&0x1f)!=0x05) return(1);
return(0);
}
INT8U SD_Read_Block(INT8U *CMD, INT8U *Buffer, INT16U Bytes)
{
INT16U i;
INT8U retry,response;
INT16U Block_Len=0;
INT8U CMD_SET_BLOCKLEN[]={0x50,0x00,0x00,0x00,0x00,0xFF};
SSPCPSR = 0x7E;
if(Bytes != Block_Len)
{
CMD_SET_BLOCKLEN[3] = (INT8U)((Bytes & 0x0000FF00) >> 8 );
CMD_SET_BLOCKLEN[4] = (INT8U)((Bytes & 0x000000FF) >> 0 );
retry = 0;
do
{ //Retry 100 times to send command.
response = Write_Command_SD(CMD_SET_BLOCKLEN);
if(++retry >= 100)
return(1); //block read Error!
}
while(response != 0);
Block_Len = Bytes;
}
//Send reads a block Command CMD to SD/SD-Card
retry = 0;
do
{
response = Write_Command_SD(CMD);
if(++retry >= 100)
return(1); //block read Error!
}
while(response != 0);
//Read Start Byte form SD/SD-Card (FEh/Start Byte)
// while(SPI_RW(0xff) != 0xfe) ;
retry="0";
for(i=0;i<1000;i++)
{
response="SPI"_RW(0xff);
retry++;
if(response==0xfe)
i="1000";
if(retry==1000)
return(1);
}
SSPCPSR = 0x04;
//Write blocks(normal 512Bytes) to SD/SD-Card
for(i = 0; i < Bytes; i++)
*Buffer++ = SPI_RW(0xff);
//CRC-Byte
SPI_RW(0xff);//CRC - Byte
SPI_RW(0xff);//CRC - Byte
SD_Disable();
return(0);
}
SD_INIT()
{
INT8U retry, response;
INT16U i;
spi_init();
SD_Enable();
for(i=0;i<250;i++)
__asm
{
NOP
}
for(i = 0; i < 0x0f; i++)
{
SPI_RW(0xff);
}
//Send Command CMD0 to SD/SD Card
retry = 0;
do
{ //retry 200 times to send CMD0 command
response = Write_Command_SD(CMD); //CMD0 响应为01
retry++;
}
while((response != 1) && (retry < 200));
retry="0";
do
{
CMD[0]=0x77;
CMD[5]=0x55;
Write_Command_SD(CMD); //CMD55 响应为01
CMD[0]=0X69;
response="Write"_Command_SD(CMD); //ACMD41 响应为00
retry++;
}
while((response!=0)&&(retry<200)) ;
// return(response);
}
void SD_WRITE(INT8U* Buffer,INT32U Number_Sector)
{
INT8U retry, response;
retry="0";
do
{
response="SD"_write_sector(Number_Sector,Buffer);
retry++;
}
while((response!=0x00)&&(retry<20)) ;
}
void SD_READ(INT8U *Buffer, INT16U Bytes,INT32U Number_Sector)
{
INT8U response,retry;
INT8U CMD[]={0X51,0X00,0X00,0X00,0X00,0XFF};
Number_Sector=Number_Sector<<9;
CMD[1] = ((Number_Sector & 0xFF000000) >> 24 );
CMD[2] = ((Number_Sector & 0x00FF0000) >> 16 );
CMD[3] = ((Number_Sector & 0x0000FF00) >> 8 );
CMD[4] = ((Number_Sector & 0x000000FF) >> 0) ;
retry="0";
do
{
response="SD"_Read_Block(CMD,Buffer,Bytes);
retry++;
}
while((response!=0)&&(retry<100));
}
用户222464 2010-4-23 19:57
用户547952 2010-3-25 22:39