很长一段时间我尝试实现FatFs模块,但每次SD卡格式化后它都会变得疯狂。 (每次都有不同的错误)。我决定降低速度并检查我的SDCard驱动程序,我注意到当我读到扇区字段的某些(但总是相同)时,我收到了垃圾,我无法解释它。
我的驱动程序测试如下所示:
.service_description {
display: none;
border: 1px solid black;
padding: 8px;
width: 20%;
margin-top: -16px;
}
我把断点放在CSD = 0;线。这是我写完和阅读相同地址后得到的结果:
缓冲区填充0到255之间的数字(两次,因为溢出)。 为了降低噪声,我将SPI频率降至最低。没有改变。但事实上,错误的数字总是出现在相同的表索引下并且具有相同的值表明噪声没有问题,但是有些错误。 它看起来像驱动程序正常工作,因为它们编写和读取大多数字段,但总是在相同的情况下回答垃圾。我找不到任何痕迹我能做错什么。我是否在一些允许的地址下写作?当我读取任何随机地址时,我收到相同的结果。
我包括函数:读取和写入(SD_Sector是全局缓冲区)
WRITE
#if 1 //SD Card Test
uint16_t i;
uint8_t CSD; //card capacity
uint8_t CID; //card id
uint8_t Buffer[512]; //this buffer is written to card
for(i=0; i<512;i++)
{
Buffer[i]=i;
}
SD_CardInit(); //card initialization
CSD = SD_Read_CSD(); //read capacity
CID = SD_Read_CSD(); //read ID
SD_WriteBlock(0x200, Buffer, 512); //write Buffer under 0x200 (512) address
SD_Read_Block(0x200); //read buffer from 0x200
CSD = 0;
#endif
READ
// Write block of data to the SD card
// input:
// addr - start address of the block (must be power of two)
// pBuf - pointer to the buffer with data
// len - buffer length
// return: SDR_xxx
SDResult_TypeDef SD_WriteBlock(uint32_t addr, uint8_t *pBuf, uint32_t len)
{
uint32_t wait;
uint16_t CRC_loc; // Calculated CRC16 of the block
uint16_t i;
uint8_t cmdres, response, temp;
SDCard_privChipSelect();
// Calculate 16-bit CRC
CRC_loc = CRC16_buf(pBuf,len);
// SDSC card uses byte unit address and
// SDHC/SDXC cards use block unit address (1 unit = 512 bytes)
// For SDHC/SDXC card addr must be converted to block address
#if 0 //TODO: reconsider PiechotM, do not work with that line
if (SD_CardType == SD_HIGH_CAPACITY_SD_CARD) addr >>= 9;
#endif
response = SD_SendCmd(SD_CMD_WRITE_SINGLE_BLOCK,addr); // CMD24
if (response != 0x00)
{
// Something wrong happened, do nothing
return response; // SD_CMD_READ_SINGLE_BLOCK command returns bad response
}
else
{
wait = 0; response = 0;
while (++wait <= 512/*0x1ff*/ && response == 0xff)
{
temp = 0xFF;
SD_Send( temp );
response = SD_Recv();
}
if (wait >= 0x1ff) return 0xff;
// Send start block token
SD_Send(SD_TOKEN_START_BLOCK);
// Send data block
for (i = 0; i < len; i++)
{
uint8_t temp;
SD_Send( *pBuf++ );
}
// Send CRC
SD_Send(CRC_loc >> 8);
SD_Send((uint8_t)CRC_loc);
}
// Get response from the SD card
cmdres = SD_Recv();
cmdres &= 0x1f;
if (cmdres != SD_TOKEN_DATA_ACCEPTED)
{
// Data block rejected by SD card for some reason
// Release SD card
SD_Send(0xff);
SDCard_privChipDeSelect();
if (cmdres & SD_TOKEN_WRITE_CRC_ERROR) return SDR_WriteCRCError;
if (cmdres & SD_TOKEN_WRITE_ERROR) return SDR_WriteErrorInternal;
return SDR_WriteError;
}
// Wait while the SD card is busy by data programming
wait = 0x7fff; // Recommended timeout is 250ms (500ms for SDXC)
do
{
cmdres = SD_Recv();
} while (cmdres == 0 && --wait);
// Provide extra 8 clocks for the card (from SanDisk specification)
SD_Send(0xff);
// Release SD card
SDCard_privChipDeSelect();
// Must send at least 74 clock ticks to SD Card
for (wait = 0; wait < 10; wait++) SD_Send(0xff);
return SDR_Success;
}
我将非常感谢你的帮助!
致以最诚挚的问候,
Maks Piechota