|
最近對(duì)FAT32文件系統(tǒng)的10來(lái)個(gè) 應(yīng)用函數(shù)“溫故”了一下,比以前的認(rèn)識(shí)提高了很多。FAT32文件系統(tǒng)作為一個(gè)大型軟件不比uc/os-ii操作系統(tǒng)簡(jiǎn)單。個(gè)人認(rèn)為,F(xiàn)AT32文件系統(tǒng)的難點(diǎn)就在于對(duì)存儲(chǔ)介質(zhì)的理解比較難,如什么是扇區(qū)?什么是簇?什么是FAT表?它們都與FAT32文件系統(tǒng)中的幾個(gè)重要結(jié)構(gòu)體和枚舉類型數(shù)據(jù)息息相關(guān);如FATFS,FIL,DIR,FRESULT等等成員的意義是什么?那些重要的應(yīng)用函數(shù)的形參的意義是什么?這些才是學(xué)習(xí)FAT32文件系統(tǒng)的重點(diǎn)和難點(diǎn)!看懂一兩個(gè)例程并不代表自己真正的學(xué)會(huì)了FAT32文件系統(tǒng)。
這幾天一直在做 FAT32文件系統(tǒng)應(yīng)用函數(shù)的實(shí)驗(yàn),現(xiàn)將其貼出來(lái)與同道中人分享。本程序?qū)⒃拥乃悸愤\(yùn)用在了野火的板子,將原子戰(zhàn)艦板的精華(如USMART串口助手移植到了野火的板子)完全與野火的板子和程序作了兼容處理,如原子的exfuns和fattest等文件都移植到了野火板。就是這么個(gè)簡(jiǎn)單的軟硬件兼容處理耗費(fèi)了本人不少的精力。常常夜不能寐。
主程序的功能:1,檢測(cè)SD卡的總?cè)萘亢涂臻e容量;2,實(shí)時(shí)時(shí)鐘功能;3,用到了f_gets(),f_typetell(),f_opendir()等等。
4,用按鈕控制,將實(shí)驗(yàn)結(jié)果通過(guò)串口助手打印出來(lái),同時(shí)顯示在LCD上。不足之處就是對(duì)文件索引號(hào)的處理不靠譜。即便如此,還是沒(méi)有實(shí)現(xiàn)將實(shí)時(shí)數(shù)據(jù)存儲(chǔ)到文本文件的功能,真他媽愚鈍。至此,已經(jīng)很憔悴了,苦逼的代碼難民!
FIL fnew; /* file objects */
//FATFS fs; /* Work area (file system object) for logical drives */
FRESULT res;
UINT br, bw; /* File R/W count */
BYTE buffer[4096]={0}; /* file copy buffer */
BYTE textFileBuffer[] = "Welcome to use Wildfire iso stm32 Development Board today is a good day";
//FILINFO fileinfo; //文件信息
//DIR dir; //目錄
TCHAR* buf;
//u8 *fatbuf; //SD卡數(shù)據(jù)緩存區(qū)
int main(void)
{
u32 i,total,free;
u8 t=0;
u8 m,n,j=0;
exfuns_init(); //
uart_init(9600);
delay_init();
mem_init(SRAMIN);
LCD_Init();
LCD_Clear(0, 0, 240, 320, WHITE);
Key_init();
LED_GPIO_Config();
NVIC_Configuration();
RTC_Init();
usmart_dev.init(SystemCoreClock/1000000);
LCD_DispEnCh(10, 20, "實(shí)時(shí)時(shí)鐘+FAT32文件系統(tǒng)實(shí)驗(yàn)", RED);
LCD_DispEnCh(100, 270, (uint8_t *)"2014-06-05", MAGENTA );
LCD_DispEnCh(30, 240, "沉著--厚積--低調(diào)", RED);
LCD_DispStrCH(20, 270, "王衍制作", RED);
while(RTC_Init())
{
LCD_DispStr(60,60,"RTC ERROR! ",RED);
delay_ms(200);
LCD_DispStr(60,60,"RTC Trying...",RED);
}
LCD_DispStr(30,120," - - ",RED); //顯示:年_月_日
LCD_DispStr(10,140," : : ",RED); //顯示格式時(shí)分秒
Sd_fs_init();
while(exf_getfree("0",&total,&free)) //得出SD卡的容量
{
LCD_DispStr(60,170,"Fatfs Error!",BLUE);
delay_ms(200);
LCD_DispStr(60,170,"Fatfs Error!",WHITE);
LED2_TOGGLE;
}
LCD_DispStr(60,170,"Fatfs OK!",BLUE);
LCD_DispStr(10,190,"SD Total Size: MB",BLUE);
LCD_DispStr(10,210,"SD Free Size: MB",BLUE);
LCD_DisNum(160,190,total>>10,RED); //
LCD_DisNum(160,210,free>>10,RED);
if(t!=calendar.sec)
{
t=calendar.sec;
LCD_DisNum(30, 120, calendar.w_year, BLUE);
LCD_DisNum(85, 120, calendar.w_month, BLUE);
LCD_DisNum(110, 120, calendar.w_date, BLUE);
switch(calendar.week)
{
case 0:
LCD_DispEnCh(150, 120, "星期天", BLUE);
break;
case 1:
LCD_DispEnCh(150, 120, "星期一", BLUE);
break;
case 2:
LCD_DispEnCh(150, 120, "星期二", BLUE);
break;
case 3:
LCD_DispEnCh(150, 120, "星期三", BLUE);
break;
case 4:
LCD_DispEnCh(150, 120, "星期四", BLUE);
break;
case 5:
LCD_DispEnCh(150, 120, "星期五", BLUE);
break;
case 6:
LCD_DispEnCh(150, 120,"星期六", BLUE);
break;
}
LCD_DisNum(50, 140, calendar.hour, BLUE);
LCD_DisNum(80, 140, calendar.min, BLUE);
LCD_DisNum(110, 140, calendar.sec, BLUE);
}
while(1)
{
if( Key_Scan(GPIOA,GPIO_Pin_0) == KEY_ON )
{
if(Key_Scan(GPIOA,GPIO_Pin_0) == KEY_ON)delay_ms(10);
{ j=dir.index;j++;delay_ms(10);
LCD_DisNum(50,40,j,BLUE);
f_open(&fnew, "0:newfile.txt", FA_OPEN_EXISTING | FA_READ);
buf=f_gets((TCHAR*)fatbuf,sizeof(buf),&fnew);
printf("文件字符 :%s\r\n",buf);
m= f_typetell("sub");//在這里sub是文件夾名而不是文件名,所以輸出0xff
printf("文件屬性 :%d\r\n",m);
n= f_typetell("wildfire.bmp"); printf("文件后綴名:%d\r\n",n);
/*打印出來(lái)的n(十進(jìn)制)等于80,將80轉(zhuǎn)換成16進(jìn)制就是0x50,正好是bmp文件,
由u8 *FILE_TYPE_TBL[6][13]可知 */
if(f_opendir(&dir, "sub") == FR_OK) //
{
while (f_readdir(&dir, &fileinfo) == FR_OK) //按順序讀取文件夾sub內(nèi)的文件名信息
{
if(!fileinfo.fname[0]) break; //文件名為0,說(shuō)明文件里已經(jīng)沒(méi)有文件了
{
f_open(&fnew, "0:newfile.txt", FA_OPEN_EXISTING | FA_READ);
buf=f_gets((TCHAR*)fatbuf,150,&fnew);
/* 在 "0:newfile.txt" 文本文件里讀出150個(gè)字符,注意函數(shù)的用法 */
printf("文件字符名字 :%s\r\n",buf);//注意:*buf 數(shù)據(jù)類型不能搞錯(cuò)
LCD_DispStr(50,60,"readdir ok!",BLUE);
if(fileinfo.fattrib == AM_ARC) //??????
printf("文件名:%s\r\n",fileinfo.fname);
}
printf("文件索引號(hào): %d\r\n",j);//注意:j是u8類型,所以printf里只能是“d”類型!
}
} f_close(&fnew);
}
}
if( Key_Scan(GPIOC,GPIO_Pin_13) == KEY_ON ) // KEY2=PC13
{
if(Key_Scan(GPIOC,GPIO_Pin_13)== KEY_ON) delay_ms(10);
res = f_open(&fnew, "0:newfile.txt", FA_CREATE_ALWAYS | FA_WRITE );
if ( res == FR_OK )
{
res = f_write(&fnew, textFileBuffer, sizeof(textFileBuffer), &bw);
f_close(&fnew);
}
res = f_open(&fnew, "0:newfile.txt", FA_OPEN_EXISTING | FA_READ);
res = f_read(&fnew, buffer, sizeof(buffer), &br);
printf("\r\n %s ", buffer);
f_close(&fnew);
LCD_DispStr(50,80,"hello world!",BLUE);
}
i++;
if((i%60)==0)
{
LED3_TOGGLE;
}
delay_ms(10);
}
}
|
|