2014-11-28 1 views
-1

У меня есть SD-карта (или SDHC-карта), подключенная к микроконтроллеру через SPI-режим. Я использую библиотеку FAT Chan. В этом я использовал код примера CodevisionAVR v2.05.3 из справки. С помощью этого я прочитал текстовый документ и открыл файл, используя открытый существующий.Embedded - SD-карта - SPI - C -Codevision AVR - Создание и запись файла на SD-карте

Однако, пока я создаю новый файл или пытаюсь писать, я не мог открыть файл (do f_open). Ошибка при передаче ERROR: FR_INVALID_OBJECT.

Как я могу устранить эту проблему?

И мой код

/* 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!"; 
 

 

 

 
/* 100Hz 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 occured, 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 occured, 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 occured, 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 occured, 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 occured, 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 occured, 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 occured, 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 occured, 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 occured, 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 occured, 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 occured, 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 occured, display it and stop */ 
 
     error(res); 
 

 
    printf("done\r\n"); 
 

 
    PORTB.4 = 1; 
 
/* stop here */ 
 
    while (1); 
 
}

+0

Почтовый пример кода. – Clifford

+0

Во-первых, смонтировал ли FS нормально? –

+0

if ((res = f_mount (0, & drive)) == FR_OK) printf («Логический диск 0: установлен OK \ r \ n»); else ошибка (res); if ((res = f_open (& file, path, FA_READ)) == FR_OK) printf ("1_File% s открыт OK \ r \ n", путь); else ошибка (res); if ((res = f_read (& file, buffer, sizeof (buffer) -1, & nbytes)) == FR_OK) { printf ("% u bytes read \ r \ n", nbytes); буфер [nbytes + 1] = NULL; printf ("Читать текст: \"% s \ "\ r \ n", buffer); } else error (res); if ((res = f_close (& file)) == FR_OK) printf ("1_File% s closed OK \ r \ n \ n \ n", path); else ошибка (res); – sasi

ответ

0

Из документации:

FR_INVALID_OBJECT

The file/directory object structure is invalid or a null pointer is given. All open objects of the logical drive are invalidated by the volume mount process.

Ваш указатель файла, возможно, пустой?

Также следует учитывать, что вы настроили библиотеку для фактической поддержки операций записи. В ffconf.h вы должны иметь:

#define _FS_READONLY 0 
+0

, но тот же файл работает для чтения и открытия существующих операций. – sasi

+0

Можно настроить ELM FatFs только для чтения (чтобы уменьшить размер, если запись не нужна) - вы настроили его для записи? – Clifford

+0

да, я настроен для записи. и аппаратная настройка, работающая с кодом Dharmanitech atmel.и ссылка http://www.dharmanitech.com/2009/01/sd-card-interfacing-with-atmega8-fat32.html – sasi

Смежные вопросы