初级会员

- 积分
- 122
- 金钱
- 122
- 注册时间
- 2022-1-1
- 在线时间
- 35 小时
|
2金钱
现在做一个小项目,主控芯片为STM32F3系列,存储方式采用SD卡存储,通信方式SPI(F3系列没有SDIO),由于板子空间有限,采用TF卡的卡槽,用的卡是立创买的4GB TF卡,现在初始化可以通过,但是我的数据量级别大概是2GB,用正点原子MINI开发板的SPI驱动SD卡程序,用u8 sd_write_disk(u8 *pbuf, u32 saddr, u32 cnt)函数多扇区写,但是一直会卡在 if ( (t & 0x1F) != 0x05) { return SD_ERROR; }这里面导致多扇区写不能成功,所以打算固定cnt = 1,每次调用这个函数,让其一个扇区一个扇区的写,但是测试过程中,每写一个扇区还得加几ms的延时才能勉强算成功写入,而且再同样方式调用读函数u8 sd_read_disk(u8 *pbuf, u32 saddr, u32 cnt),也读不出来,请问大神们这大概是哪方面的问题啊,卡还是程序呢?
下面附官方程序:
u8 sd_write_disk(u8 *pbuf, u32 saddr, u32 cnt)
{
u8 retry = 20; /* 发送ACMD经常失败, 多尝试几次 */
u8 res;
long long lsaddr = saddr;
if (sd_type != SD_TYPE_V2HC)
{
lsaddr <<= 9; /* 转换为字节地址 */
}
if (cnt == 1)
{
res = sd_send_cmd(CMD24, lsaddr); /* 读命令 */
if (res == 0) /* 指令发送成功 */
{
res = sd_send_block(pbuf, 0xFE);/* 写512个字节 */
}
}
else
{
if (sd_type != SD_TYPE_MMC)
{
do
{
sd_send_cmd(ACMD23, cnt); /* 发送 ACMD23 指令 */
}while(res && retry--);
}
res = sd_send_cmd(CMD25, lsaddr); /* 连续读命令 */
if (res == 0)
{
do
{
res = sd_send_block(pbuf, 0xFC); /* 写入一个block, 512个字节 */
pbuf += 512;
} while (--cnt && res == 0);
res = sd_send_block(0, 0xFD); /* 写入一个block, 512个字节 */
}
}
sd_deselect();/* 取消片选 */
return res;
}
u8 sd_send_block(u8 *buf, u8 cmd)
{
u16 t;
if (sd_wait_ready()) /* 等待ready */
{
return SD_ERROR;
}
sd_spi_read_write_byte(cmd); /* 发送 CMD */
if (cmd != 0XFD) /* 不是结束指令 */
{
for (t = 0; t < 512; t++)
{
sd_spi_read_write_byte(buf[t]); /* 发送数据 */
}
sd_spi_read_write_byte(0xFF); /* 忽略crc */
sd_spi_read_write_byte(0xFF);
t = sd_spi_read_write_byte(0xFF); /* 接收响应 */
if ((t & 0x1F) != 0x05) /* 数据包没有被接收 */
{
return SD_ERROR;
}
}
return SD_OK; /* 写入成功 */
}
u8 sd_read_disk(u8 *pbuf, u32 saddr, u32 cnt)
{
u8 res;
long long lsaddr = saddr;
if (sd_type != SD_TYPE_V2HC)
{
lsaddr <<= 9; /* 转换为字节地址 */
}
if (cnt == 1)
{
res = sd_send_cmd(CMD17, lsaddr); /* 读命令 */
if (res == 0) /* 指令发送成功 */
{
res = sd_receive_data(pbuf, 512); /* 接收512个字节 */
}
}
else
{
res = sd_send_cmd(CMD18, lsaddr); /* 连续读命令 */
do
{
res = sd_receive_data(pbuf, 512); /* 接收512个字节 */
pbuf += 512;
} while (--cnt && res == 0);
sd_send_cmd(CMD12, 0); /* 发送停止命令 */
}
sd_deselect(); /* 取消片选 */
return res;
}
u8 sd_receive_data(u8 *buf, u16 len)
{
if (sd_get_response(0xFE)) /* 等待SD卡发回数据起始令牌0xFE */
{
return SD_ERROR;
}
while (len--) /* 开始接收数据 */
{
*buf = sd_spi_read_write_byte(0xFF);
buf++;
}
/* 下面是2个伪CRC(dummy CRC) */
sd_spi_read_write_byte(0xFF);
sd_spi_read_write_byte(0xFF);
return SD_OK; /* 读取成功 */
}
下面是我的测试代码:
while(1)
{
if(USART1_RX_STA&0x8000)
{
if(USART1_RX_BUF[0]==0xAA&&USART1_RX_BUF[1]==0x01)
{
LED1_ON;
//写入0xFF
for(a=0; a<512; a++)
{
writeBuffer[a] = 0xFF;
}
for(b=0;b<1000;b++)
{
if(sd_write_disk(writeBuffer,b,1) == 0)//如果等于0,证明写完
{
LED3_ON;
RS485_TX_HI;
USART_SendData(USART1,0xFF);
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
RS485_TX_LO;
}
delay_ms(10);
}
//写入数据
for(a=0; a<512; a++)
{
writeBuffer[a] = a;
}
for(b=0;b<1000;b++)
{
if(sd_write_disk(writeBuffer,b,1) == 0)//如果等于0,证明写完
{
LED3_ON;
RS485_TX_HI;
USART_SendData(USART1,0x22);
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
RS485_TX_LO;
}
delay_ms(10);
}
LED1_OFF;
LED3_OFF;
}
if(USART1_RX_BUF[0]==0xAA&&USART1_RX_BUF[1]==0x02)
{
LED2_ON;
for(a=0;a<1000;a++)
{
if(sd_read_disk(readBuffer, a, 1) == 0)
{
RS485_TX_HI;
for(b=0;b<512;b++)
{
USART_SendData(USART1,readBuffer[b]);
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
}
RS485_TX_LO;
}
delay_ms(10);
}
LED2_OFF;
}
USART1_RX_STA=0;
}
}
|
|