问题描述
我尝试使用SPI和FatFS从SD卡读取文件,而ACMD41出现问题。 以前,CMD0和CMD8给我正确的响应,并且我假设我有一个新的v2类型。 第一次发送ACMD41时,CMD55和CMD41都收到0x01响应,因此下次发送时,在16个CLK周期中,除了0xff之外,我都没有收到CMD55响应,因此初始化最终返回了错误。我试图编写自己的文件来初始化卡,并使用了我在Internet上找到的就绪库。我也认为SD卡没有问题,因为我已经尝试了其中四个。
下面是代码,也许某人将能够找到解决方案,或者给我一些建议或链接到可靠的来源。
/*
* sd_spi.c
*
* Created on: 26.11.2017
* Author: jaras
*/
#include "sd_spi.h"
#include <string.h>
uint8_t SDSPI_SendCMD(SPI_HandleTypeDef *phandle,uint8_t cmd,uint32_t arg,uint8_t crc) {
uint8_t buf[6];
buf[0] = cmd | 0x40;
buf[1] = (arg >> 24) & 0xff;
buf[2] = (arg >> 16) & 0xff;
buf[3] = (arg >> 8) & 0xff;
buf[4] = arg & 0xff;
buf[5] = crc;
if(HAL_SPI_Transmit(phandle,buf,6,1000) != HAL_OK) {
return 1;
}
return 0;
}
uint8_t SDSPI_Response(SPI_HandleTypeDef *phandle,uint8_t *buf,uint16_t size) {
uint8_t tx = 0xff;
uint8_t rx = 0xff;
uint8_t i = 0;
while(rx == 0xff) {
if(HAL_SPI_TransmitReceive(phandle,&tx,&rx,1,1000) != HAL_OK) {
return 1;
}
i++;
if(i > 8) {
return 2;
}
}
*buf = rx;
for(uint16_t k = 1; k < size; k++) {
if(HAL_SPI_TransmitReceive(phandle,1000) != HAL_OK) {
return 1;
}
*(buf + k) = rx;
}
return 0;
}
uint8_t SDSPI_CMD(SPI_HandleTypeDef *phandle,uint8_t crc,uint8_t *response,uint8_t size) {
HAL_GPIO_WritePin(SDSPI_CSPORT,SDSPI_CSPIN,GPIO_PIN_RESET);
uint8_t res = SDSPI_SendCMD(phandle,cmd,arg,crc);
if(res > 0) {
HAL_GPIO_WritePin(SDSPI_CSPORT,GPIO_PIN_SET);
return 1;
}
res = SDSPI_Response(phandle,response,size);
if(res > 0) {
HAL_GPIO_WritePin(SDSPI_CSPORT,GPIO_PIN_SET);
return 2;
}
HAL_GPIO_WritePin(SDSPI_CSPORT,GPIO_PIN_SET);
uint8_t tx = 0xff;
if(HAL_SPI_Transmit(phandle,1000) != HAL_OK) {
HAL_GPIO_WritePin(SDSPI_CSPORT,GPIO_PIN_SET);
return 3;
}
return 0;
}
uint8_t SDSPI_ACMD(SPI_HandleTypeDef *phandle,uint8_t size) {
uint8_t value0;
uint8_t rx = 0;
uint8_t res = SDSPI_CMD(phandle,55,0x65,1);
value0=rx;
if(res > 0) {
return 1;
}
if((rx & 0xf4) > 0) {
return 2;
}
res = SDSPI_CMD(phandle,crc,size);
if(res > 0) {
return 3;
}
return 0;
}
uint8_t SDSPI_Init(SPI_HandleTypeDef *phandle) {
uint8_t value0;
uint8_t value1;
uint8_t value2;
uint8_t value3;
uint8_t value4;
HAL_GPIO_WritePin(SDSPI_CSPORT,GPIO_PIN_SET);
HAL_Delay(10);
uint8_t buf[] = {0xff,0xff,0xff};
if(HAL_SPI_Transmit(phandle,10,1000) != HAL_OK) {
return 1; //spi error
}
uint8_t res = SDSPI_CMD(phandle,0x95,1);
value0 = buf[0];
if(res > 0) {
return 1; //command error
}
if(buf[0] != 1) {
return 2; //not initialized
}
uint8_t type = 0;
uint8_t block = 0;
res = SDSPI_CMD(phandle,8,0x01aa,0x87,5);
value0 = buf[0];
value1 = buf[1];
value2 = buf[2];
value3 = buf[3];
value4 = buf[4];
if(res > 0) {
type = 1;
}
if(buf[0] != 1) {
type = 1;
}
if((buf[3] & 0x0f) != 1 || buf[4] != 0xaa) {
return 3; //initialization error
}
uint8_t stat = 0;
uint32_t tickstart = 0;
if(type == 0) {
stat = 1;
tickstart = HAL_GetTick();
while(stat > 0) {
if((HAL_GetTick()-tickstart) >= 1000) {
HAL_GPIO_WritePin(SDSPI_CSPORT,GPIO_PIN_SET);
return 4; //timeout
}
res = SDSPI_ACMD(phandle,41,0x40000000,0x77,&stat,1);
if(res > 0) {
return 5; //not supported
}
}
res = SDSPI_CMD(phandle,58,0x75,5);
if(res > 0) {
return 6; //not supported
}
if(buf[0] > 0) {
return 7;
}
if((buf[1] & 0x04) > 0) {
block = 1;
}
}
if(type == 1) {
stat = 1;
tickstart = HAL_GetTick();
while(stat > 0) {
if((HAL_GetTick()-tickstart) >= 1000) {
HAL_GPIO_WritePin(SDSPI_CSPORT,GPIO_PIN_SET);
stat = 0;
type = 2;
}
res = SDSPI_ACMD(phandle,1);
if(res > 0) {
stat = 0;
type = 2;
}
}
}
if(type == 2) {
stat = 1;
tickstart = HAL_GetTick();
while(stat > 0) {
if((HAL_GetTick()-tickstart) >= 1000) {
HAL_GPIO_WritePin(SDSPI_CSPORT,GPIO_PIN_SET);
return 8; //timeout
}
res = SDSPI_CMD(phandle,1);
if(res > 0) {
return 9; //error
}
}
}
if(block == 0) {
res = SDSPI_CMD(phandle,16,512,1);
if(res > 0) {
return 10; //not supported
}
if(buf[0] > 0) {
return 11; //error
}
}
return 0;
}
/*
* sd_spi.h
*
* Created on: 26.11.2017
* Author: jaras
*/
#ifndef SD_SPI_H_
#define SD_SPI_H_
#include "stm32f3xx_hal.h"
#include "gpio.h"
#define SDSPI_CSPORT CS_PIN_GPIO_Port
#define SDSPI_CSPIN CS_PIN_Pin
uint8_t SDSPI_Init(SPI_HandleTypeDef *phandle);
uint8_t SDSPI_ReadInfo(SPI_HandleTypeDef *phandle,uint16_t *sector,uint32_t *capacity);
uint8_t SDSPI_ReadBlock(SPI_HandleTypeDef *phandle,uint32_t lba,uint16_t size);
uint8_t SDSPI_WriteBlock(SPI_HandleTypeDef *phandle,uint16_t size);
#endif /* SD_SPI_H_ */
解决方法
问题出在SD卡上,尚未在SPI和SDIO上同时初始化由Fatube库生成的FAT和CubeMX生成的SDIO文件。我已经购买了一张新卡,现在在SDIO上可以正常使用。在SPI上检查了它,但是我怀疑格式化有问题