当我从SPI总线上的PIC-18F4520向卡片发出地址为(0x00000000)的cmd17命令时,我会从命令发出处得到一个正确的R1标记。然后,在几次循环检查后,我会从我的发行SPI_Put_Char(0xFF)中获得一个0xFE标记。接下来应该是数据,所以我将512字节读入我的IO_Buffer数组。当我扫描返回时,我得到许多0x00字节。奇怪的是,在第0个扇区的位置448左右,一些数据会被传输过来 - 有一些字节 - 然后最后的32个字节(我只能在我的LCD屏幕上一次查看32个字节)都是零,后面是期望在引导扇区结尾的0x55AA标记。
奇怪的是,使用磁盘调查程序可以发现SD卡具有正确的零扇区信息 - MSDOS消息,EB跳转代码等等。但我的读取命令将所有这些都返回为零。我真的不知道发生了什么。
其他信息:我使用cmd0,cmd8,cmd58和OCR启动读取正常。然后是acmd41(循环cmd55后跟APP_SEND_OP_COND)。所有似乎都有响应并给出预期的标记。最后,我甚至使用SEND_CID获取卡片信息。返回MID = 3 OID = SD和版本SD017,后跟其他信息 - 所有似乎都是正确的。
我尝试在来自卡的DOUT上添加上拉和下拉电阻,但没有影响任何结果。
我渴望尝试一些想法来使这张卡正确读取。顺便说一句,我已经尝试了另外两张卡。它们给出不同的具体结果,但定性相同 - 初始化,OCR和CID读取都可以正常工作。数据读取大部分为零,然后是一些可重现但稀疏的字节,以及一个0xAA55标记!?
我的SanDisk 1GB SD卡正在以3.296伏特运行,在读卡过程中似乎很稳定。
以下是一些代码:
奇怪的是,使用磁盘调查程序可以发现SD卡具有正确的零扇区信息 - MSDOS消息,EB跳转代码等等。但我的读取命令将所有这些都返回为零。我真的不知道发生了什么。
其他信息:我使用cmd0,cmd8,cmd58和OCR启动读取正常。然后是acmd41(循环cmd55后跟APP_SEND_OP_COND)。所有似乎都有响应并给出预期的标记。最后,我甚至使用SEND_CID获取卡片信息。返回MID = 3 OID = SD和版本SD017,后跟其他信息 - 所有似乎都是正确的。
我尝试在来自卡的DOUT上添加上拉和下拉电阻,但没有影响任何结果。
我渴望尝试一些想法来使这张卡正确读取。顺便说一句,我已经尝试了另外两张卡。它们给出不同的具体结果,但定性相同 - 初始化,OCR和CID读取都可以正常工作。数据读取大部分为零,然后是一些可重现但稀疏的字节,以及一个0xAA55标记!?
我的SanDisk 1GB SD卡正在以3.296伏特运行,在读卡过程中似乎很稳定。
以下是一些代码:
bit MMC_Command(unsigned char cmd, unsigned short AdrH, unsigned short AdrL, unsigned char *response)
{
unsigned char response_length;
unsigned char MMC_Counter_Byte = 255;
unsigned char current_response;
switch (cmd)
{
case MMC_SEND_IF_COND:
case MMC_READ_OCR:
response_length = 5;
break;
case MMC_SEND_STATUS:
response_length = 2;
break;
default:
response_length = 1;
};
DEV_xSELECT = DEV_MMC;
SPI_Put_Char(cmd);
SPI_Put_Char(AdrH >> 8);
SPI_Put_Char(AdrH & 0x00FFU);
SPI_Put_Char(AdrL >> 8);
SPI_Put_Char(AdrL & 0x00FFU);
SPI_Put_Char(0x95U); //CRC = 0x95 to get to SPI, then value not important, so always use this for convenience
do
{
response[0] = SPI_Put_Char(0xFF);
} while ((response[0] & 0x80) && --MMC_Counter_Byte);
if (!MMC_Counter_Byte)
{
//SPI_Put_Char(0xFF); //some say is necessary
DEV_xSELECT = DEV_NONE;
return FALSE;
};
for (current_response = 1; current_response < response_length; current_response++)
{
response[current_response] = SPI_Put_Char(0xFF);
};
SPI_Put_Char(0xFF); //some say is necessary
DEV_xSELECT = DEV_NONE;
return TRUE;
};
unsigned char MMC_Init_SD(void)
{
unsigned long MMC_Counter_Word;
unsigned char response[5];
DEV_xSELECT = DEV_MMC;
for (MMC_Counter_Word = 0; MMC_Counter_Word < 20; MMC_Counter_Word++)
{
SPI_Put_Char(0xFFU);
};
DEV_xSELECT = DEV_NONE;
for (MMC_Counter_Word = 0; MMC_Counter_Word < 10; MMC_Counter_Word++)
{
SPI_Put_Char(0xFFU);
};
MMC_Counter_Word = 255;
do
{
MMC_Command(MMC_GO_IDLE_STATE, 0x0000, 0x0000, response); //cmd0
} while (--MMC_Counter_Word && (response[0] != 0x01));
if (!MMC_Counter_Word) //if counter timed out, error
{
return FALSE;
};
MMC_Command(MMC_SEND_IF_COND, 0x0000, 0x01AA, response); //cmd8
if (response[0] != 0x05)
{
return FALSE; //other card type
};
MMC_Command(MMC_READ_OCR, 0x0000, 0x0000, response); //cmd58
MMC_Counter_Word = 0xFFFFU;
do
{
if (MMC_Command(MMC_APP_CMD, 0x0000, 0x0000, response)) //cmd55
{
MMC_Command(MMC_APP_SEND_OP_COND, 0x4001, 0x0000, response); //acmd41
SPI_Put_Char(0xFF);
}
else
{
return FALSE;
};
} while (--MMC_Counter_Word && ((response[0] & 1) == 1));
if (!MMC_Counter_Word)
{
return FALSE;
};
if (MMC_Command(MMC_SEND_CID, 0x0000, 0x0000, response)) //cmd10
{
DEV_xSELECT = DEV_MMC;
MMC_Counter_Word = 255;
while (--MMC_Counter_Word && (SPI_Put_Char(0xFF) != 0xFE));
if (!MMC_Counter_Word)
{
DEV_xSELECT = DEV_NONE;
return FALSE;
};
//code for reading 16 byte OCR goes here
SPI_Put_Char(0xFFU);
SPI_Put_Char(0xFFU); //cycle through 16-bit CRC
SPI_Put_Char(0xFFU); //1GB Sandisk SD seems to require another dummy
DEV_xSELECT = DEV_NONE;
Delay_Sec(2);
LCD_CLS();
}
else
{
return FALSE;
};
return TRUE;
};
bit MMC_Fill_IO_Buffer(unsigned long sector)
{
unsigned short MMC_Fill_Index_Byte;
unsigned char MMC_Counter_Byte = 255;
unsigned char response[1];
if (MMC_Command(MMC_READ_SINGLE_BLOCK, 0x0000, 0x0000, response)) //cmd10
{
DEV_xSELECT = DEV_MMC;
MMC_Counter_Byte = 255;
while (--MMC_Counter_Byte && (SPI_Put_Char(0xFF) != 0xFE));
if (!MMC_Counter_Byte)
{
DEV_xSELECT = DEV_NONE;
return FALSE;
};
}
else
{
return FALSE;
};
for (MMC_Fill_Index_Byte = 0; MMC_Fill_Index_Byte < 512 ; MMC_Fill_Index_Byte++)
{
IO_Buffer[MMC_Fill_Index_Byte] = SPI_Put_Char(0xFF);
};
SPI_Put_Char(0xFFU);
SPI_Put_Char(0xFFU); //cycle through 16-bit CRC
SPI_Put_Char(0xFFU); //1GB Sandisk SD seems to require another dummy
DEV_xSELECT = DEV_NONE;
//following is IO_Buffer displaying code.
//LCD_CLS();
//for (MMC_Counter_Byte = 0; MMC_Counter_Byte < 42; MMC_Counter_Byte++)
//{
// LCD_Draw_Byte_Hex(IO_Buffer[MMC_Counter_Byte + 448]);
//};
//while (1);
return TRUE;
};
提前感谢你!
(这是需要翻译的内容)