原因自己去找,提醒一下SD卡未初始化时,SPI通信CLK频率一定要低。 #include "..incincludes.h"
#include "New_sd.h"
sbit c_SPI_CS = P2^4; //Sht-mp3 Config
//set MMC_Chip_Select to high (MMC/SD-Card Invalid) #define SD_Disable() c_SPI_CS = 1 //set MMC_Chip_Select to low (MMC/SD-Card Active) #define SD_Enable() c_SPI_CS = 0
sbit c_SPI_SI = P1^5; sbit c_SPI_SO = P1^6; sbit c_SPI_CLK = P1^7;
sbit c_SD_In = P2^7; sbit c_SD_WP = P2^6; sbit c_SD_Power = P2^3;
#define Macro_Set_SI_High() c_SPI_SI = 1 #define Macro_Set_SI_Low() c_SPI_SI = 0 #define Macro_Set_CLK_High() c_SPI_CLK = 1 #define Macro_Set_CLK_Low() c_SPI_CLK = 0
//bool bSPICLK_LowSpeed;
static void SD_PowerOn(void) { c_SD_Power = 0; } /* static void SD_PowerOff(void) { c_SD_Power = 1; } */ //extern uint8 BUFFER[512];
uint8 SD_SPI_ReadByte(void); void SD_SPI_WriteByte(uint8 ucSendData);
//#define SPI_ReadByte() SD_SPI_ReadByte() //#define SPI_TransferByte(x) SD_SPI_WriteByte(x) /* static uint8 SPI_ReadByte(void) { uchar ucReadData; uchar ucCount;
ucReadData = 0; Macro_Set_SI_High();
for(ucCount=0; ucCount<8; ucCount++) { ucReadData <<= 1; //降低时钟频率 Macro_Set_CLK_Low(); //降低时钟频率 // if(bSPICLK_LowSpeed) // { // Delay_100us(); // }
Macro_Set_CLK_High(); // if(bSPICLK_LowSpeed) // { // Delay_100us(); // } if(c_SPI_SO) { ucReadData |= 0x01; } }
return(ucReadData);
// SPDR = 0xFF; // while (!(SPSR & 0x80)); // return SPDR; } static void SPI_TransferByte(uint8 ucSendData) { uchar ucCount; uchar ucMaskCode;
ucMaskCode = 0x80; for(ucCount=0; ucCount<8; ucCount++) { Macro_Set_CLK_Low();
if(ucMaskCode & ucSendData) { Macro_Set_SI_High(); } else { Macro_Set_SI_Low(); } //降低时钟频率 // if(bSPICLK_LowSpeed) // { // Delay_100us(); // }
Macro_Set_CLK_High(); ucMaskCode >>= 1;
//降低时钟频率 // if(bSPICLK_LowSpeed) // { // Delay_100us(); // }
}
//SPDR=cmp1; //while(!(SPSR&(1<<SPIF))); } */
static uint8 SPI_ReadByte(void) { uchar ucReadData; uchar ucCount;
ucReadData = 0; Macro_Set_SI_High();
for(ucCount=0; ucCount<8; ucCount++) { ucReadData <<= 1; //降低时钟频率 Macro_Set_CLK_Low(); //降低时钟频率 // if(bSPICLK_LowSpeed) // { // Delay_100us(); // }
Macro_Set_CLK_High(); // if(bSPICLK_LowSpeed) // { // Delay_100us(); // } if(c_SPI_SO) { ucReadData |= 0x01; } }
return(ucReadData);
// SPDR = 0xFF; // while (!(SPSR & 0x80)); // return SPDR; } static void SPI_TransferByte(uint8 ucSendData) { uchar ucCount; uchar ucMaskCode;
ucMaskCode = 0x80; for(ucCount=0; ucCount<8; ucCount++) { Macro_Set_CLK_Low();
if(ucMaskCode & ucSendData) { Macro_Set_SI_High(); } else { Macro_Set_SI_Low(); } //降低时钟频率 // if(bSPICLK_LowSpeed) // { // Delay_100us(); // }
Macro_Set_CLK_High(); ucMaskCode >>= 1;
//降低时钟频率 // if(bSPICLK_LowSpeed) // { // Delay_100us(); // }
}
//SPDR=cmp1; //while(!(SPSR&(1<<SPIF))); }
void SD_Port_Init(void) //**************************************************************************** {
c_SPI_SO = 1; c_SD_In = 1; c_SD_WP = 1;
SD_PowerOn(); }
//**************************************************************************** //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); }
//**************************************************************************** //Send a Command to MMC/SD-Card //Return: the second byte of response register of MMC/SD-Card uint8 Write_Command_SD_HighSpeed(uint8 *cmd) //**************************************************************************** { uint8 tmp,i; uint8 retry=0; SD_Disable(); SD_SPI_WriteByte(0xFF); SD_Enable(); for(i=0;i<6;i++) { SD_SPI_WriteByte(*cmd++); } SD_SPI_ReadByte(); do{ tmp = SD_SPI_ReadByte(); }while((tmp==0xff)&&(retry++ <100)); return(tmp); }
//**************************************************************************** //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... for (i = 0; i < 200; i++) { _nop_(); } //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. }
uint8 SD_Read_Block(uint8 *CMD,uint8 *Buffer,uint16 Bytes) //**************************************************************************** { uint16 i; uint8 retry, temp; //Send Command CMD to MMC/SD-Card retry=0;
//#if 1 do { //Retry 100 times to send command. // temp=Write_Command_SD(CMD); temp=Write_Command_SD_HighSpeed(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); //#endif
//Read blocks(normal 512Bytes) to MMC/SD-Card #if 1 for (i = 0; i < Bytes; i++) //int count for loop cost 13 machine cycle { // *Buffer++ = SPI_ReadByte(); //Cost 70 Machine Cycle //When define point is a Xdata point then Cost 62 Machine Cycle *Buffer++ = SD_SPI_ReadByte(); //Cost 70 Machine Cycle // put_c(*Buffer); } #endif
/* i = Bytes; while(i--) //When Delete {} 2 Machine Cycle is save.
*Buffer++ = SPI_ReadByte(); //Cost 70 Machine Cycle */
//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; } */ extern unsigned char xdata Page_Buf[512]; //文件缓冲区。
void SD_SPI_WriteByte(uint8 ucSendData);
//测试SD卡SPI接口性能 void TestSD_SPIFunc(void) { uchar ucCount; uchar ucReadData;
ucCount = 0; //开始
for(ucCount=0; ucCount<10; ucCount++) { // SPI_TransferByte(0x88); //用C语言实现的写字节机器周期数为188 SD_SPI_WriteByte(0x88); //用C51的bData变量,采用位指令直接传送操作,共用机器机器49 }
for(ucCount=0; ucCount<50; ucCount++) { ucReadData = SPI_ReadByte(); //用C语言实现的SPI读字节机器赌周期为154 //自用C51的bData变量,采用位指令操作读字节机器周期为49
} ucCount= 88; //结束 SD_read_sector(0,Page_Buf); } |