2014-11-28 5 views
-1

SPI 모드를 통해 마이크로 컨트롤러에 SD 카드 (또는 SDHC 카드)를 연결했습니다. Chan의 FAT 라이브러리를 사용하고 있습니다. 이 문서에서 CodevisionAVR v2.05.3 예제 코드를 사용했습니다. 이것을 사용하여 텍스트 문서를 읽고 기존 파일을 사용하여 파일을 열었습니다.Embedded - SD 카드 - SPI - C - Codevision AVR - SD 카드에 파일 작성 및 쓰기

그러나 새 파일을 만들거나 쓰려고 할 때 파일을 열 수 없습니다 (do f_open). 오류 부여 : FR_INVALID_OBJECT.

이 문제를 어떻게 해결할 수 있습니까?

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.

파일 포인터가 아마 널 :

그리고 내 코드는 문서에서

/* 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 : 마운트 됨 \ r \ n"); else 오류 (res); if ((res = f_open (& file, path, FA_READ)) == FR_OK) printf ("1_File % s 열린 파일 \ r \ n", 경로); else 오류 (res); if ((res = f_read (& file, buffer, sizeof (buffer) -1, & nbytes)) == FR_OK) { printf ("% u 바이트 읽기 \ r \ n", nbytes); 버퍼 [nbytes + 1] = NULL; printf ("텍스트 읽기 : \"% s \ "\ r \ n", 버퍼); } else 오류 (res); if ((res = f_close (& file)) == FR_OK) printf ("1_File % s 닫기 OK \ r \ n \ n \ n", 경로); else 오류 (res); – sasi

답변

0

입니까?

또한 실제로 쓰기 조작을 지원하도록 라이브러리를 구성했다고 생각하십시오. ffconf.h에서 다음을 가져야합니다.

#define _FS_READONLY 0 
+0

하지만 기존 파일을 읽고 열 때 동일한 파일이 작동합니다. – sasi

+0

ELM FatF를 읽기 전용으로 구성 할 수 있습니다 (쓰기가 필요하지 않으면 크기 줄이기 위해). 쓰기 용으로 구성 했습니까? – Clifford

+0

예 쓰기 용으로 구성되었습니다. Dharmanitech atmel 스튜디오 코드 작업을하는 하드웨어 설치.링크는 http://www.dharmanitech.com/2009/01/sd-card-interfacing-with-atmega8-fat32.html입니다. – sasi