|
我用的是凌阳的单片机,Sd卡的初始化在发CMD0的时候回复为0,看了高手的代码,感觉没有什么大的差别的。
我的代码如下:
#include "SPCE061A.H"
#define uchar unsigned char
#define uint unsigned int
#define CMD0 (0x40|0) /* GO_IDLE_STATE */
#define CMD1 (0x40|1) /* SEND_OP_COND */
#define ACMD41 (0xC0|41) /* SEND_OP_COND */
#define CMD8 (0x40|8) /* SEND_IF_COND */
#define CMD9 (0x40|9) /* SEND_CSD */
#define CMD10 (0x40|10) /* SEND_CID */
#define CMD12 (0x40|12) /* STOP_TRANSMISSION */
#define ACMD13 (0xC0|13) /* SD_STATUS */
#define CMD16 (0x40|16) /* SET_BLOCKLEN */
#define CMD17 (0x40|17) /* READ_SINGLE_BLOCK */
#define CMD18 (0x40|18) /* READ_MULTIPLE_BLOCK */
#define ACMD23 (0xC0|23) /* SET_WR_BLK_ERASE_COUNT */
#define CMD24 (0x40|24) /* WRITE_BLOCK */
#define CMD25 (0x40|25) /* WRITE_MULTIPLE_BLOCK */
#define CMD32 (0x40|32) /* ERASE_BLOCK_START_ADDR */
#define CMD33 (0x40|33) /* ERASE_BLOCK_END_ADDR */
#define CMD38 (0x40|38) /* ERASE_SELECTED_BLOCKS */
#define CMD55 (0x40|55) /* APP_CMD */
#define CMD58 (0x40|58) /* READ_OCR */
#define CS_High() (*P_IOB_Data|=0x0800)
#define CS_Low() (*P_IOB_Data&=0xf7ff)
#define CLK_High() (*P_IOB_Data|=0x0100)
#define CLK_Low() (*P_IOB_Data&=0xfeff)
#define DO_High() (*P_IOB_Data|=0x4000)
#define DO_Low() (*P_IOB_Data&=0xbfff)
#define DI_High() (*P_IOB_Data|=0x0200)
#define DI_Low() (*P_IOB_Data&=0xfdff)
void SD_IOInit(void)
{
*P_IOB_Attrib=0xfd00;
*P_IOB_Dir=0xff00;
*P_IOB_Data=0xff00;
}
void Delayus(unsigned int n)
{
while(n--)
{}
}
void SPI_Send(uchar d)
{
uchar i;
for(i=0;i<8;i++)
{
if(d&0x0080)
DO_High();
else
DO_Low();
CLK_Low();
Delayus(200);
CLK_High();
Delayus(200);
d<<=1; //先传高位
}
DO_High();//不使用时将输出线置1
}
uchar SPI_Receive(void)
{
uchar d,i;
for(i=0;i<8;i++)
{
CLK_Low();
Delayus(200);
CLK_High();
Delayus(200);
d<<=1; //先接高位
if(*P_IOB_Data&0x0200)
d++;
}
return (d&0x00ff);
}
uchar SD_CMDWrite(uchar CMDx,unsigned long CMDArg)
{
uchar res=0xff; uchar retry=0; uchar CRC=0xff;
if(CMDx==0x40) CRC=0x95;
CS_High();
SPI_Send(0xff);//8个时钟脉冲
CS_Low();
SPI_Send(CMDx);//发送命令索引,前两位是01
SPI_Send(CMDArg>>24);
SPI_Send(CMDArg>>16);
SPI_Send(CMDArg>>8);
SPI_Send(CMDArg);
SPI_Send(CRC);
SPI_Send(CMDx);
SPI_Send(0xff); //8个附加时钟
do{
SPI_Receive(); //读前8位
res=SPI_Receive(); //读取SD回应(后8位)
retry++;
*P_Watchdog_Clear=0x0001;
if(retry>100)
break; // 超时
} while((res&0x00ff)==0x00ff);
CS_High();
SPI_Send(0xff); //附加8个额外时钟
return (res&0x00ff);
}
uchar SD_Init(void)
{
uchar res=0xff; uchar i,retry=0;
SD_IOInit(); //管脚初始化
CS_High();
Delayus(500);
for(i=0;i<0x0f;i++) //发送多于74个时钟
SPI_Send(0xff);
do{
res=SD_CMDWrite(CMD0,0);//复位
retry++;
*P_Watchdog_Clear=0x0001;
if(retry>0x100)
break;
}while((res&0x00ff)!=0x01);
retry=0;
do{
res=SD_CMDWrite(CMD1,0);//激活SD卡
retry++;
*P_Watchdog_Clear=0x0001;
if(retry>0x100)
break;
}while((res&0x00ff)!=0);
return (res&0x00ff);
}
int main(void)
{
char resp=0xff;
*P_SystemClock=0x0080;
do{
resp=SD_Init();
*P_Watchdog_Clear=0x0001;
}while((resp&0x00ff)!=0);
while(1){}
return 0;
} |
阿莫论坛20周年了!感谢大家的支持与爱护!!
一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。
|