|||
在读写SD的时候都需要等待SD卡是否ready, 使用查询的方式完全占用了CPU 的时间,对于开发应用软件效率很低,特别是裸奔的程序,于是本人开发了分时处理(状态机)SD卡读写的程序,大大提高了效率。
其中的读例程示例如下:希望对你有用,本人的学习板提供完整的例程。
void SD_ReadProcess(void)
{
static volatile BYTE n;
BYTE *buff;
BYTE res;
WORD wc;
switch(ReadId)
{
case 0: //idle
break;
case 1:
//1,send_cmd(CMD17, sector)
DESELECT();
SELECT();
ReadId ++;
Delay = 500;
rcv_spi();
case 2:
//if (wait_ready() != 0xFF) return 0xFF;
//500ms 超时等待
res = rcv_spi();
if(res == 0xFF)
{ //reveive ready flag
ReadId ++; //next,go on
}
else
{
if(Delay == 0)
{ //time out -- error
Status = FALSE;
ReadId = 5; // skip following 2 steps
}
break;
}
case 3: //SD_Cmd
/* Send command packet */
mit_spi(CMD17); /* Start + Command index */
mit_spi((BYTE)(Sector >> 24)); /* Argument[31..24] */
mit_spi((BYTE)(Sector >> 16)); /* Argument[23..16] */
mit_spi((BYTE)(Sector >> 8)); /* Argument[15..8] */
mit_spi((BYTE)Sector); /* Argument[7..0] */
n = 0x01; /* Dummy CRC + Stop */
//if (CMD17 == CMD0) n = 0x95; /* Valid CRC for CMD0(0) */
//if (CMD17 == CMD8) n = 0x87; /* Valid CRC for CMD8(0x1AA) */
mit_spi(n);
/* Receive command response */
//if (CMD17 == CMD12) rcv_spi(); /* Skip a stuff byte when stop reading */
n = 10;
ReadId ++; /* Wait for a valid response in timeout of 10 attempts */
case 4:
res = rcv_spi();
if((res & 0x80) && --n)
{ // waiting
break;
}
else
{
ReadId ++;
}
// receive data .......................................
case 5: //2,rcvr_datablock(buff, 512)
Delay = 100+1;
ReadId ++;
case 6:
/* Wait for data packet in timeout of 100ms */
res = rcv_spi();
if((res == 0xFF) && Delay)break;
if(res != 0xFE)
{
ReadId = 7;
Status = FALSE;
break; //goto :
}
buff = pSDBuffer;
for(wc=0;wc<512;wc++)
{
res = stm32_spi_w(0xff);
*buff = res;
buff ++;
}
rcv_spi(); /* Discard CRC */
rcv_spi();
ReadId ++;
Status = TRUE;
case 7:
release_spi_sd(); // release spi
ReadId = 0;
SD_Busy = 0; //enable
break;
default:
ReadId = 0;
SD_Busy = 0;
break;
}
}