I have an SD card (or SDHC card) connected to a microcontroller via SPI mode. I am using Chan’s FAT library. In this I used CodevisionAVR v2.05.3 example code from help. By using this I read a text document and opened the file using open existing.
However, when I created a new file or tried to write, I couldn't open the file (do f_open). Giving error ERROR: FR_INVALID_OBJECT.
How can I clear this issue?
And my code is:
/* ATmega128 I/O register definitions */
#include <io.h>
#if defined(_CHIP_ATMEGA32_)
#warning using ATMEGA32
#define TIMSK1 TIMSK
#define UCSR0A UCSRA
#define UCSR0B UCSRB
//#define UCSR0C UCSRC //this is commented out
#define UBRR0H UBRRH
#define UBRR0L UBRRL
#define TXEN0 TXEN
#endif
/* FAT on MMC/SD/SD HC card support */
#include <ff.h>
/* printf */
#include <stdio.h>
/* String functions */
#include <string.h>
#include <delay.h>
/* Timer1 overflow interrupt frequency [Hz] */
#define T1_OVF_FREQ 100
/* Timer1 clock prescaler value */
#define T1_PRESC 1024L
/* Timer1 initialization value after overflow */
#define T1_INIT (0x10000L-(_MCU_CLOCK_FREQUENCY_/(T1_PRESC*T1_OVF_FREQ)))
/* USART Baud rate */
#define BAUD_RATE 9600
#define BAUD_INIT (_MCU_CLOCK_FREQUENCY_/(BAUD_RATE*16L)-1)
/* Root directory path */
char path[] = "0:/fil.txt";
/* Text to be written to the file */
char text[]="I like CodeVisionAVR!";
/* 100 Hz timer interrupt generated by ATmega128 Timer1 overflow */
interrupt [TIM1_OVF] void timer_comp_isr(void)
{
/* Re-initialize Timer1 */
TCNT1H = T1_INIT >> 8;
TCNT1L = T1_INIT & 0xFF;
/* MMC/SD/SD HC card access low level timing function */
disk_timerproc();
}
/* Error message list */
flash char *flash error_msg[] = {
"", /* Not used */
"FR_DISK_ERR",
"FR_INT_ERR",
"FR_INT_ERR",
"FR_NOT_READY",
"FR_NO_FILE",
"FR_NO_PATH",
"FR_INVALID_NAME",
"FR_DENIED",
"FR_EXIST",
"FR_INVALID_OBJECT",
"FR_WRITE_PROTECTED",
"FR_INVALID_DRIVE",
"FR_NOT_ENABLED",
"FR_NO_FILESYSTEM",
"FR_MKFS_ABORTED",
"FR_TIMEOUT"
};
/* Display error message and stop */
void error(FRESULT res)
{
if ((res >= FR_DISK_ERR) && (res <= FR_TIMEOUT))
printf("ERROR: %p\r\n", error_msg[res]);
/* Stop here */
while (1);
}
void main(void)
{
/* FAT function result */
FRESULT res;
/* Will hold the information for logical drive 0: */
FATFS drive;
/* Will hold the file information */
FIL file;
/* Number of bytes written/read to the file */
unsigned int nbytes;
/* File read buffer */
char buffer[256];
/* Initialize Timer1 overflow interrupts in Mode 0 (Normal) */
TCCR1A = 0x00;
/* clkio/1024 */
TCCR1B = (1<<CS12)|(1<<CS10);
/* Timer overflow interrupts will occur with 100Hz frequency */
TCNT1H = T1_INIT >> 8;
TCNT1L = T1_INIT & 0xFF;
/* Enable Timer1 overflow interrupt */
TIMSK1 = 1 << TOIE1;
/* Initialize the USART0 TX, 8N1, Baud rate: 19200 */
UCSR0A = 0;
UCSR0B = 1 << TXEN0;
//UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
UBRR0H = BAUD_INIT >> 8;
UBRR0L = BAUD_INIT & 0xFF;
/* Globally enable interrupts */
#asm("sei")
PORTB.4 = 0;
delay_ms(1000);
printf("\n\nDirectory listing for root of logical drive 0:\r\n");
/* Mount logical drive 0: */
if ((res = f_mount(0, &drive)) == FR_OK)
printf("Logical drive 0: mounted OK\r\n");
else
/* An error occurred, display it and stop */
error(res);
printf("%s \r\n", path);
/* Open the file in read mode */
if ((res = f_open(&file, path, FA_READ)) == FR_OK)
printf("1_File %s opened OK\r\n", path);
else
/* An error occurred, display it and stop */
error(res);
/* Read and display the file's content.
make sure to leave space for a NULL terminator
in the buffer, so maximum sizeof(buffer)-1 bytes can be read */
if ((res=f_read(&file,buffer,sizeof(buffer)-1,&nbytes))==FR_OK)
{
printf("%u bytes read\r\n", nbytes);
/* NULL terminate the char string in the buffer */
buffer[nbytes+1]=NULL;
/* Display the buffer contents */
printf("Read text: \"%s\"\r\n", buffer);
}
else
/* An error occurred, display it and stop */
error(res);
/* Close the file */
if ((res = f_close(&file)) == FR_OK)
printf("1_File %s closed OK\r\n\n\n", path);
else
/* An error occurred, display it and stop */
error(res);
/* Create a new file in the root of drive 0:
and set write access mode */
if ((res = f_open(&file,path, FA_OPEN_EXISTING)) == FR_OK)
printf("File %s opened OK\r\n", path);
else
/* An error occurred, display it and stop */
error(res);
/* Close the file */
if ((res = f_close(&file)) == FR_OK)
printf("2_File %s closed OK\r\n\n\n", path);
else
/* An error occurred, display it and stop */
error(res);
if ((res = f_open(&file,path, FA_WRITE | FA_CREATE_ALWAYS)) == FR_OK)
printf("File %s created OK\r\n", path);
else
/* An error occurred, display it and stop */
error(res);
/* Write some text to the file,
without the NULL string terminator sizeof(data)-1 */
if ((res = f_write(&file, text, sizeof(text)-1,&nbytes)) == FR_OK)
printf("%u bytes written of %u\r\n", nbytes, sizeof(text)-1);
else
/* An error occurred, display it and stop */
error(res);
/* Close the file */
if ((res = f_close(&file)) == FR_OK)
printf("3_File %s closed OK\r\n\n\n", path);
else
/* An error occurred, display it and stop */
error(res);
/* Open the file in read mode */
if ((res = f_open(&file,path,FA_READ)) == FR_OK)
printf("1_File %s opened OK\r\n", path);
else
/* An error occurred, display it and stop */
error(res);
/* Read and display the file's content.
make sure to leave space for a NULL terminator
in the buffer, so maximum sizeof(buffer)-1 bytes can be read */
if ((res = f_read(&file, buffer, sizeof(buffer)-1, &nbytes)) == FR_OK)
{
printf("%u bytes read\r\n", nbytes);
/* NULL terminate the char string in the buffer */
buffer[nbytes+1] = NULL;
/* Display the buffer contents */
printf("Read text: \"%s\"\r\n", buffer);
}
else
/* An error occurred, display it and stop */
error(res);
/* Close the file */
if ((res = f_close(&file)) == FR_OK)
printf("4_File %s closed OK\r\n", path);
else
/* An error occurred, display it and stop */
error(res);
printf("done\r\n");
PORTB.4 = 1;
/* Stop here */
while (1);
}
From the documentation:
Your file pointer is perhaps null?
Also to consider is that you have configured the library to actually support write operations. In ffconf.h you should have: