我正在使用带有STM32F407芯片的STM32F4开发板。为了与SD卡通信,我使用SPI1,并使用由Chan创建的FatFs库。
问题的关键在于我已成功设法在SD卡上创建文件,我能够从中读取。但是当我尝试写入文件时,它会破坏文件或打印像这样的垃圾数据" {46040EDD-C"。如果我看看memmory,我可以看到我写的东西,但不知怎的,它被写入错误的memmory地址。
我遇到的另一个问题是,第一次创建文件并尝试使用f_write写入文件时,我得到了回复FR_DISK_ERR。这个错误来自于尝试创建一个集群链,当我通过代码它运行正常时。所以可能会有一些延迟缺失。下次运行程序时,它可以工作,f_write返回FR_OK。
我不确定这些问题是否相关。我一直试图让它工作大约两个星期,并且会喜欢我能得到的任何帮助。谢谢。
代码:
的main.c
=Switch(Fields!Date.Value >= CDate("01/05/" & Str(Year(Parameters!StartDate.Value))) and Fields!Date.Value <= CDate("01/10/" & Str(Year(Parameters!EndDate.Value))) and
count(lookup(Fields!Assessors_Staff_ID.Value,Fields!EMPNO.Value, Fields!SINFO.Value, "FullTime"))>= "8"
and lookup(Fields!Assessors_Staff_ID.Value,Fields!EMPNO.Value, Fields!SINFO.Value, "FullTime") = "100%",
"Green",
Fields!Date.Value >= CDate("01/11/" & Str(Year(Parameters!StartDate.Value))) and Fields!Date.Value <= CDate("30/04/" & Str(Year(Parameters!EndDate.Value))) and
count(lookup(Fields!Assessors_Staff_ID.Value,Fields!EMPNO.Value, Fields!SINFO.Value, "FullTime"))>= "4"
and lookup(Fields!Assessors_Staff_ID.Value,Fields!EMPNO.Value, Fields!SINFO.Value, "FullTime") = "100%",
"Green",
Fields!Date.Value >= CDate("01/05/" & Str(Year(Parameters!StartDate.Value))) and Fields!Date.Value <= CDate("01/10/" & Str(Year(Parameters!EndDate.Value))) and
count(lookup(Fields!Assessors_Staff_ID.Value,Fields!EMPNO.Value,Fields!SINFO.Value, "FullTime"))>= "6"
and lookup(Fields!Assessors_Staff_ID.Value,Fields!EMPNO.Value, Fields!SINFO.Value, "FullTime") = "75%",
"Green",
Fields!Date.Value >= CDate("01/11/" & Str(Year(Parameters!StartDate.Value))) and Fields!Date.Value <= CDate("30/04/" & Str(Year(Parameters!EndDate.Value))) and
count(lookup(Fields!Assessors_Staff_ID.Value,Fields!EMPNO.Value, Fields!SINFO.Value, "FullTime"))>= "3"
and lookup(Fields!Assessors_Staff_ID.Value,Fields!EMPNO.Value, Fields!SINFO.Value, "FullTime") = "75%",
"Green",
Fields!Date.Value >= CDate("01/05/" & Str(Year(Parameters!StartDate.Value))) and Fields!Date.Value <= CDate("01/10/" & Str(Year(Parameters!EndDate.Value))) and
count(lookup(Fields!Assessors_Staff_ID.Value,Fields!EMPNO.Value, Fields!SINFO.Value, "FullTime"))>= "4"
and lookup(Fields!Assessors_Staff_ID.Value,Fields!EMPNO.Value, Fields!SINFO.Value, "FullTime") = "50%" ,
"Green",
Fields!Date.Value >= CDate("01/11/" & Str(Year(Parameters!StartDate.Value))) and Fields!Date.Value <= CDate("30/04/" & Str(Year(Parameters!EndDate.Value))) and
count(lookup(Fields!Assessors_Staff_ID.Value,Fields!EMPNO.Value, Fields!SINFO.Value, "FullTime"))>= "2"
and lookup(Fields!Assessors_Staff_ID.Value,Fields!EMPNO.Value, Fields!SINFO.Value, "FullTime") = "50%",
"Green",
true,"Red"
)
我编辑的Chans diskio.c文件。
int main(void)
{
int i;
//SD CARD INIT
//Fatfs object
FATFS FatFs;
//File object
FIL fil;
UINT fa;
FRESULT res_mount, res_open, res_seek, res_write;
delay(10ms);
res_mount = f_mount(&FatFs, "", 1);
if (res_mount == FR_OK) {
GPIO_ToggleBits(GPIOD, GPIO_Pin_12);
delay(10ms);
res_open = f_open(&fil, "test.txt", FA_OPEN_ALWAYS | FA_READ | FA_WRITE);
if (res_open == FR_OK) {
GPIO_ToggleBits(GPIOD, GPIO_Pin_13);
delay(10ms);
res_seek = f_lseek(&fil, f_size(&fil));
if(res_seek == FR_OK)
{
delay(10ms);
GPIO_ToggleBits(GPIOD, GPIO_Pin_14);
res_write = f_write(&fil, "Alpha Beta\n", 11, &fa);
if (fa > 0 && res_write == FR_OK) {
GPIO_ToggleBits(GPIOD, GPIO_Pin_15);
f_sync(&fil);
}
}
f_close(&fil);
}
f_mount(0, "", 1);
}
while(1);
//SD CARD INIT END
}
SD_CARD.c:
#include "diskio.h" /* FatFs lower layer API */
/* Definitions of physical drive number for each drive */
#define DEV_RAM 0 /* Example: Map Ramdisk to physical drive 0 */
#define DEV_MMC 1 /* Example: Map MMC/SD card to physical drive 1 */
#define DEV_USB 2 /* Example: Map USB MSD to physical drive 2 */
static volatile DSTATUS Stat = STA_NOINIT; /* Disk status */
static BYTE CardType; /* Card type flags (b0:MMC, b1:SDv1, b2:SDv2, b3:Block addressing) */
/*-----------------------------------------------------------------------*/
/* Get Drive Status */
/*-----------------------------------------------------------------------*/
DSTATUS disk_status (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
if(pdrv)
return STA_NOINIT; // Supports only drive 0
return Stat;
}
/*-----------------------------------------------------------------------*/
/* Inidialize a Drive */
/*-----------------------------------------------------------------------*/
DSTATUS disk_initialize (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
if (Stat & STA_NODISK)
return Stat; /* No card in the socket? */
//SLOW
uint8_t ty = 0;
ty = SD_CARD_InitialiseCard();
CardType = ty;
if(ty)
Stat &= ~STA_NOINIT;
return Stat;
}
/*-----------------------------------------------------------------------*/
/* Read Sector(s) */
/*-----------------------------------------------------------------------*/
DRESULT disk_read (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
BYTE *buff, /* Data buffer to store read data */
DWORD sector, /* Start sector in LBA */
UINT count /* Number of sectors to read */
)
{
//DRESULT res;
//int result;
if(pdrv || !count)
return RES_PARERR;
if (Stat & STA_NOINIT)
return RES_NOTRDY;
if(!(CardType & SDCARD_BLOCK))
sector *= 512;
if(count == 1)
{
if((SD_CARD_Cmd(READ_SINGLE_BLOCK, sector) == 0x00) && SD_CARD_Read(buff, 512))
count = 0;
}
else
{
if(SD_CARD_Cmd(READ_MULTIPLE_BLOCKS, sector) == 0)
{
do
{
if(!SD_CARD_Read(buff, 512))
break;
buff += 512;
}
while(--count);
SD_CARD_Cmd(STOP_TRANSMISSION, 0);
}
}
return count ? RES_ERROR : RES_OK;
}
/*-----------------------------------------------------------------------*/
/* Write Sector(s) */
/*-----------------------------------------------------------------------*/
DRESULT disk_write (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
const BYTE *buff, /* Data to be written */
DWORD sector, /* Start sector in LBA */
UINT count /* Number of sectors to write */
)
{
//DRESULT res;
//int result;
if (pdrv || !count)
return RES_PARERR;
if (Stat & STA_NOINIT)
return RES_NOTRDY;
if (Stat & STA_PROTECT)
return RES_WRPRT;
if(!(CardType & SDCARD_BLOCK))
sector *= 512;
if(count == 1)
{
if((SD_CARD_Cmd(WRITE_SINGLE_BLOCK, sector) == 0x00) && SD_CARD_Write(buff, 0xFE))
count = 0;
}
else
{
if (CardType & SDCARD_SDC)
SD_CARD_Cmd(SET_WR_BLOCK_ERASE_COUNT, count);
if(SD_CARD_Cmd(WRITE_MULTIPLE_BLOCKS, sector) == 0)
{
do
{
if(!SD_CARD_Write(buff, 0xFC))
break;
buff += 512;
}
while(--count);
if (!SD_CARD_Write(0, 0xFD)) /* STOP_TRAN token */
count = 1;
}
}
return count ? RES_ERROR : RES_OK;
}
/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions */
/*-----------------------------------------------------------------------*/
DRESULT disk_ioctl (
BYTE pdrv, /* Physical drive nmuber (0..) */
BYTE cmd, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
//DRESULT res;
//int result;
//NOT NEEDED AT THE MOMENT
return RES_PARERR;
}
DWORD get_fattime (void)
{
/* Pack date and time into a DWORD variable */
return ((DWORD)(2017 - 1980) << 25)
| ((DWORD)1 << 21)
| ((DWORD)1 << 16)
| ((DWORD)0 << 11)
| ((DWORD)0 << 5)
| ((DWORD)0 >> 1);
}
SPI.c:
#include "SD_CARD.h"
/*
SPI1(GPIOA): - Type: - SD CARD:
Pin4 - CS - Pin2
Pin5 - SCLK - Pin5
Pin6 - MISO - Pin7
Pin7 - MOSI - Pin3
*/
uint8_t SD_CARD_InitialiseCard()
{
INT i = 0;
SPI1ENABLE();
ChipSelect(SPI1, HIGH);
for(i = 0;i < 16;i++)
SPI_Send(SPI1, 0xFF);
for(i = 0;i < 0xFFFF;i++);
while(SD_CARD_Cmd(GO_IDLE_STATE, 0) != R1_IDLE_STATE); //CMD0
uint32_t r = SD_CARD_Cmd(SEND_IF_COND, 0x1AA); //CMD8
if(r == 0x1AA)
return SD_CARD_InitialiseCardV2();
else if(r == (R1_IDLE_STATE | R1_ILLEGAL_COMMAND))
return SD_CARD_InitialiseCardV1();
else
return SDCARD_FAIL;
}
uint8_t SD_CARD_WriteRead(INT arg)
{
SPI_Send(SPI1, arg);
uint8_t test = SPI_Read(SPI1);
return test;
}
uint8_t SD_CARD_InitialiseCardV1()
{
uint8_t cmd;
INT i = 0;
if(SD_CARD_Cmd(SD_SEND_OP_COND, 0x40040000) <= 1) //ACMD41 - set to 3V, use 0x40200000 for 3V3
cmd = SD_SEND_OP_COND;
else
cmd = SEND_OP_COND;
for(i = 0; i < SD_COMMAND_TIMEOUT;i++)
{
if(SD_CARD_Cmd(cmd, 0) == 0) //CMD1 or ACMD41
{
// Set block length to 512 (CMD16)
if(SD_CARD_Cmd(SET_BLOCKLEN, 512) != 0) //CMD16
return SDCARD_FAIL;
//Init: SEDCARD_V1
if(cmd == SD_SEND_OP_COND)
return SDCARD_V1;
else
return SDCARD_MMCV3;
}
}
//Timeout waiting for v1.x card
return SDCARD_FAIL;
}
uint8_t SD_CARD_InitialiseCardV2()
{
INT i = 0;
INT j = 0;
for(i = 0;i < SD_COMMAND_TIMEOUT;i++)
{
for(j = 0;j < 0xFF;j++);
if(SD_CARD_Cmd(SD_SEND_OP_COND, 0x40040000) == 0) //ACMD41 - set to 3V, use 0x40200000 for 3V3
{
uint32_t ocr = SD_CARD_Cmd(READ_OCR, 0); //CMD58
return (ocr & 0x40000000) ? SDCARD_V2 | SDCARD_BLOCK : SDCARD_V2;
}
}
//Timed out waiting for v2.x card
return SDCARD_FAIL;
}
uint32_t SD_CARD_Cmd(INT cmd, INT arg)
{
struct command_fields com;
com.start_bit = 0;
com.transmitter_bit = 1;
com.index = cmd;
com.argument = arg;
if(cmd == GO_IDLE_STATE)
com.crc = 0x4A;
else if(cmd == SEND_IF_COND)
com.crc = 0x43;
else
com.crc = 0x7F;
com.end_bit = 1;
if(cmd == SD_STATUS | cmd == SET_WR_BLOCK_ERASE_COUNT | cmd == SD_SEND_OP_COND) //ACMDx
SD_CARD_Cmd(APP_CMD, 0); //CMD55
SD_CARD_WriteCom(&com);
if(cmd == SEND_IF_COND)
return SD_CARD_RecieveR7();
else if(cmd == READ_OCR)
return SD_CARD_RecieveR3();
else
return SD_CARD_RecieveR1();
}
void SD_CARD_WriteCom(struct command_fields *com)
{
ChipSelect(SPI1, LOW);
SPI_Send(SPI1, 0xFF);
SPI_Send(SPI1, (0xFF & ((com->start_bit << 7) | (com->transmitter_bit << 6) | com->index)));
SPI_Send(SPI1, (0xFF & (com->argument >> 24)));
SPI_Send(SPI1, (0xFF & (com->argument >> 16)));
SPI_Send(SPI1, (0xFF & (com->argument >> 8)));
SPI_Send(SPI1, (0xFF & com->argument));
SPI_Send(SPI1, (0xFF & ((com->crc << 1) | com->end_bit)));
}
INT SD_CARD_Write(const BYTE *buffer, BYTE token)
{
INT i = 0;
ChipSelect(SPI1, LOW);
while(SD_CARD_WriteRead(0xFF) != 0xFF);
// indicate start of block
SPI_Send(SPI1, token);
if(token != 0xFD)
{
// write the data
for(i = 0;i < 512;i++)
{
SPI_Send(SPI1, *buffer);
buffer++;
}
// write the checksum
SPI_Send(SPI1, 0xFF);
SPI_Send(SPI1, 0xFF);
// check the repsonse token
if(((SD_CARD_WriteRead(0xFF)) & 0x1F) != 0x05)
{
ChipSelect(SPI1, HIGH);
SPI_Send(SPI1, 0xFF);
return SUCCESS;
}
}
// wait for write to finish
while(SD_CARD_WriteRead(0xFF) != 0xFF);
ChipSelect(SPI1, HIGH);
SPI_Send(SPI1, 0xFF);
return ERROR;
}
INT SD_CARD_Read(BYTE *buffer, INT length)
{
INT i = 0;
ChipSelect(SPI1, LOW);
for(i = 0; i < SD_COMMAND_TIMEOUT;i++)
{
// read until start byte (0xFF)
if(SD_CARD_WriteRead(0xFF) == 0xFE)
{
// read data
for(i = 0;i < length;i++)
buffer[i] = SD_CARD_WriteRead(0xFF);
SPI_Send(SPI1, 0xFF); // checksum
SPI_Send(SPI1, 0xFF);
ChipSelect(SPI1, HIGH);
SPI_Send(SPI1, 0xFF);
return SUCCESS;
}
}
return ERROR;
}
uint8_t SD_CARD_RecieveR1()
{
INT i;
uint8_t response = 0xFF;
for(i = 0;i < SD_COMMAND_TIMEOUT;i++)
{
response = SD_CARD_WriteRead(0xFF);
if((response == 0x00) || (response == 0x01))
{
ChipSelect(SPI1, HIGH);
SPI_Send(SPI1, 0xFF);
return response;
}
}
ChipSelect(SPI1, HIGH);
SPI_Send(SPI1, 0xFF);
return 0xFF;
}
uint32_t SD_CARD_RecieveR7()
{
INT i = 0, j = 0;
for(i = 0;i < (SD_COMMAND_TIMEOUT * 1000);i++)
{
uint8_t response[5];
response[0] = SD_CARD_WriteRead(0xFF);
if(!(response[0] & 0x80))
{
for(j = 1;j < 5;j++)
{
response[j] = SD_CARD_WriteRead(0xFF);
}
ChipSelect(SPI1, HIGH);
SPI_Send(SPI1, 0xFF);
return ((response[1] << 24) | (response[2] << 16) | (response[3] << 8) | response[4]);
}
}
ChipSelect(SPI1, HIGH);
SPI_Send(SPI1, 0xFF);
return 0xFFFFFFFF; // timeout
}
uint32_t SD_CARD_RecieveR3()
{
uint32_t ocr = 0;
INT response;
for(int i=0; i < SD_COMMAND_TIMEOUT; i++)
{
response = SD_CARD_WriteRead(0xFF);
if(!(response & 0x80))
{
ocr = SD_CARD_WriteRead(0xFF) << 24;
ocr |= SD_CARD_WriteRead(0xFF) << 16;
ocr |= SD_CARD_WriteRead(0xFF) << 8;
ocr |= SD_CARD_WriteRead(0xFF);
ChipSelect(SPI1, HIGH);
SPI_Send(SPI1, 0xFF);
return ocr;
}
}
ChipSelect(SPI1, HIGH);
SPI_Send(SPI1, 0xFF);
return 0xFFFFFFFF; // timeout
}
INT SD_CARD_InitialiseDisk()
{
if(SD_CARD_InitialiseCard() == SDCARD_FAIL)
return SDCARD_FAIL;
SPI_SetSpeed(SPI1, SPI_SPEED_1300KHz);
return SUCCESS;
}
答案 0 :(得分:0)
所以我发现了我的问题。像我一样愚蠢,在我的写函数中,我忘记在发送STOP_TRANs令牌时返回成功。以下是编辑后编写函数的样子。
INT SD_CARD_Write(const BYTE *buffer, BYTE token)
{
INT i = 0;
ChipSelect(SPI1, LOW);
while(SD_CARD_WriteRead(0xFF) != 0xFF);
// indicate start of block
SPI_Send(SPI1, token);
if(token != 0xFD)
{
// write the data
for(i = 0;i < 512;i++)
{
SPI_Send(SPI1, *buffer);
buffer++;
}
// write the checksum
SPI_Send(SPI1, 0xFF);
SPI_Send(SPI1, 0xFF);
// check the repsonse token
uint8_t resp = 0x00;
do
{
resp = SD_CARD_WriteRead(0xFF);
}
while(resp == 0x00);
if((resp & 0x1F) != 0x05)
{
// wait for write to finish
while(SD_CARD_WriteRead(0xFF) != 0xFF);
SPI_Send(SPI1, 0xFF);
ChipSelect(SPI1, HIGH);
SPI_Send(SPI1, 0xFF);
return SUCCESS;
}
}
// wait for write to finish
while(SD_CARD_WriteRead(0xFF) != 0xFF);
SPI_Send(SPI1, 0xFF);
ChipSelect(SPI1, HIGH);
SPI_Send(SPI1, 0xFF);
if(token == 0xFD)
return SUCCESS;
return ERROR;
}