SD卡电路,请用过的看看我的电路是否正确

做一个码农都是奢望 2012-07-18 05:36:48

以下是我的sd卡电路图,一直未成功实现cmd0应答。请看是否电路有问题。

电路如下: 供电都是3.3v。
...全文
250 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
1. cmd0指令


//--------- send CMD0 ---------
U08 CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};//cmd0
while((r1=SD_write_command (CMD)) !=0x01)
{
Uart_SendB(r1);//将应答发送出来。
if (Timeout++ > 200)
{ Uart_SendB(0xcc);return(1); }//测试是否未响应// CMD0 Error! 1
}


2.被调用的发送命令函数


//Send a Command to MMC/SD-Card
//Return: the second byte of response register of MMC/SD-Card
//---------------------------------------------------------------------
U08 SD_write_command (U08 *cmd)
{
U08 tmp = 0xff;
U16 Timeout = 0;

SD_Disable(); //SD_CS = HIGH
SD_write_byte(0xFF); //send 8 Clock Impulse
SD_Enable(); //SD_CS = LOW

//send 6 Byte Command
U08 a;
for (a = 0;a<0x06;a++)
{
SD_write_byte(*cmd++);
}

//get 16 bit response
while (tmp == 0xff)
{
tmp = SD_read_byte(); //Only last 8 bit is used here.Read it out.
if (Timeout++ > 500){break;}
}
return(tmp);
}


3.SPI读写


//---------------------------------------------------------------------
//Routine for reading a byte from MMC/SD-Card
//---------------------------------------------------------------------
inline U08 SD_read_byte (void)
{
U08 Byte = 0,a=0;

#if SPI_Mode
SPDR = 0xff;
while(!(SPSR & (1<<SPIF))){};
Byte = SPDR;
#else //Software SPI

for ( a=8; a>0; a--) //1 Byte ( MSB First)
{
SD_Write &=~(1<<SPI_Clock); //SD_SCK (Low)
delay();//启动延时
if (bit_is_set(SD_Read,SPI_DI) > 0)
{
Byte |= (1<<(a-1));
}
else
{
Byte &=~(1<<(a-1));
}
delay();//启动延时
SD_Write |=(1<<SPI_Clock); //SD_SCK (High)
delay();//启动延时
}
#endif
return (Byte);
}

//---------------------------------------------------------------------
//Routine for sending a byte to MMC/SD-Card
//---------------------------------------------------------------------
inline void SD_write_byte (U08 Byte)
{
U08 a;
#if SPI_Mode
SPDR = Byte;
while(!(SPSR & (1<<SPIF))) {}
#else
for (a=8; a>0; a--) // 1 Byte ( MSB First)
{
if (bit_is_set(Byte,(a-1))>0) {SD_Write |= (1<<SPI_DO); }//MMC.DO High
else {SD_Write &= ~(1<<SPI_DO);}//MMC.DO Low
delay();
SD_Write &= ~(1<<SPI_Clock); //MMC.SCK (LOW)
delay();
SD_Write |= (1<<SPI_Clock); //MMC.SCK (High)
delay();
}
SD_Write |= (1<<SPI_DO); //MMC.DO High
#endif
}

  • 打赏
  • 举报
回复
1.发送cmd0指令。

for (a = 0;a<0x0f;a++){SD_write_byte(0xff);}//wait >74 Clk

//--------- send CMD0 ---------
U08 CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};//cmd0
while((r1=SD_write_command (CMD)) !=0x01)
{
Uart_SendB(r1);//将应答发送出来。
if (Timeout++ > 200)
{ Uart_SendB(0xcc);return(1); }//测试是否未响应// CMD0 Error! 1
}


2.被调用的函数 SD_write_command

//---------------------------------------------------------------------
//Send a Command to MMC/SD-Card
//Return: the second byte of response register of MMC/SD-Card
//---------------------------------------------------------------------
U08 SD_write_command (U08 *cmd)
{
U08 tmp = 0xff;
U16 Timeout = 0;

SD_Disable(); //SD_CS = HIGH
SD_write_byte(0xFF); //send 8 Clock Impulse
SD_Enable(); //SD_CS = LOW

//send 6 Byte Command
U08 a;
for (a = 0;a<0x06;a++)
{
SD_write_byte(*cmd++);
}

//get 16 bit response
while (tmp == 0xff)
{
tmp = SD_read_byte(); //Only last 8 bit is used here.Read it out.
if (Timeout++ > 500){break;}
}
return(tmp);
}

3. SPI 发送和读取字节的命令。考虑模拟时序的问题。所用的avr单片机具备spi接口。

//---------------------------------------------------------------------
//Routine for reading a byte from MMC/SD-Card
//---------------------------------------------------------------------
inline U08 SD_read_byte (void)
{
U08 Byte = 0,a=0;

#if SPI_Mode
SPDR = 0xff;
while(!(SPSR & (1<<SPIF))){};
Byte = SPDR;
#else //Software SPI

for ( a=8; a>0; a--) //1 Byte ( MSB First)
{
SD_Write &=~(1<<SPI_Clock); //SD_SCK (Low)
delay();//启动延时
if (bit_is_set(SD_Read,SPI_DI) > 0)
{
Byte |= (1<<(a-1));
}
else
{
Byte &=~(1<<(a-1));
}
delay();//启动延时
SD_Write |=(1<<SPI_Clock); //SD_SCK (High)
delay();//启动延时
}
#endif
return (Byte);
}

//---------------------------------------------------------------------
//Routine for sending a byte to MMC/SD-Card
//---------------------------------------------------------------------
inline void SD_write_byte (U08 Byte)
{
U08 a;
#if SPI_Mode
SPDR = Byte;
while(!(SPSR & (1<<SPIF))) {}
#else
for (a=8; a>0; a--) // 1 Byte ( MSB First)
{
if (bit_is_set(Byte,(a-1))>0) {SD_Write |= (1<<SPI_DO); }//MMC.DO High
else {SD_Write &= ~(1<<SPI_DO);}//MMC.DO Low
delay();
SD_Write &= ~(1<<SPI_Clock); //MMC.SCK (LOW)
delay();
SD_Write |= (1<<SPI_Clock); //MMC.SCK (High)
delay();
}
SD_Write |= (1<<SPI_DO); //MMC.DO High
#endif
}

  • 打赏
  • 举报
回复
通过测试,现在明确了,发送cmd0,应答是0xff。
说明:根本没有收到sd卡的应答;因为SPI读数据之前是发送了一个ff的。
aydf1 2012-07-19
  • 打赏
  • 举报
回复
硬件没错,应该是时序的问题吧
Donbor 2012-07-18
  • 打赏
  • 举报
回复
VCC是3.3V你拉它干啥呀?
应该是限流电阻吧!
  • 打赏
  • 举报
回复
请问 片选和 时钟clk需要上拉吗?

27,374

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧