尝试EFM32下的fatfs的使用
生活随笔
收集整理的這篇文章主要介紹了
尝试EFM32下的fatfs的使用
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
主芯片為EFM32WG360F256,使用的SPIflash為W25Q256。
關于SPIflash的驅動部分不再說明。
移植的fatfs為官方的最新版本:http://elm-chan.org/fsw/ff/00index_e.html,Download: FatFs R0.12a | Updates | Latest Patch July 23, 2016
用不到長文件名,直接刪掉源碼的option文件夾下所有文件,接下來開始配置ffconf.h,配置如下:
配置為TINY精簡模式。之后開始完善diskio.c的底層接口函數,代碼如下:
/*-----------------------------------------------------------------------*/ /* Low level disk I/O module skeleton for FatFs (C)ChaN, 2016 */ /*-----------------------------------------------------------------------*/ /* If a working storage control module is available, it should be */ /* attached to the FatFs via a glue function rather than modifying it. */ /* This is an example of glue functions to attach various exsisting */ /* storage control modules to the FatFs module with a defined API. */ /*-----------------------------------------------------------------------*/#include "diskio.h" /* FatFs lower layer API */ #include "bsp_gps.h"/* Definitions of physical drive number for each drive */ #define EX_FLASH 0 //外部flash,卷標為0#define FLASH_SECTOR_SIZE 4096 #define FLASH_BLOCK_SIZE 16 //每個BLOCK有16個扇區 #define FLASH_SECTOR_NUM (32*1024*1024)//flash的總容量/*-----------------------------------------------------------------------*/ /* Get Drive Status */ /*-----------------------------------------------------------------------*/ //獲得磁盤狀態 DSTATUS disk_status (BYTE pdrv /* Physical drive nmuber (0..) */ ) {return 0; }/*-----------------------------------------------------------------------*/ /* Inidialize a Drive */ /*-----------------------------------------------------------------------*/ //初始化磁盤 DSTATUS disk_initialize (BYTE pdrv /* Physical drive nmuber (0..) */ ) {BYTE res=0;switch(pdrv){case EX_FLASH://外部flashW25QXX_Init();break;default:res=1;}if(res)return STA_NOINIT;else return 0; //初始化成功 }/*-----------------------------------------------------------------------*/ /* Read Sector(s) */ /*-----------------------------------------------------------------------*/ //讀扇區 //drv:磁盤編號0~9 //*buff:數據接收緩沖首地址 //sector:扇區地址 //count:需要讀取的扇區數 DRESULT disk_read (BYTE pdrv, /* Physical drive nmuber (0..) */BYTE *buff, /* Data buffer to store read data */DWORD sector, /* Sector address (LBA) */UINT count /* Number of sectors to read (1..128) */ ) {BYTE res=0;if (!count)return RES_PARERR;//count不能等于0,否則返回參數錯誤switch(pdrv){case EX_FLASH://外部flashfor(;count>0;count--){W25QXX_Read(buff,sector*FLASH_SECTOR_SIZE,FLASH_SECTOR_SIZE);sector++;buff+=FLASH_SECTOR_SIZE;}res=0;break;default:res=1;}//處理返回值,將SPI_SD_driver.c的返回值轉成ff.c的返回值if(res==0x00)return RES_OK;else return RES_ERROR; }/*-----------------------------------------------------------------------*/ /* Write Sector(s) */ /*-----------------------------------------------------------------------*/ //寫扇區 //drv:磁盤編號0~9 //*buff:發送數據首地址 //sector:扇區地址 //count:需要寫入的扇區數 DRESULT disk_write (BYTE pdrv, /* Physical drive nmuber (0..) */const BYTE *buff, /* Data to be written */DWORD sector, /* Sector address (LBA) */UINT count /* Number of sectors to write (1..128) */ ) {BYTE res=0;if (!count)return RES_PARERR;//count不能等于0,否則返回參數錯誤switch(pdrv){case EX_FLASH://外部flashfor(;count>0;count--){W25QXX_Write((BYTE*)buff,sector*FLASH_SECTOR_SIZE,FLASH_SECTOR_SIZE);sector++;buff+=FLASH_SECTOR_SIZE;}res=0;break;default:res=1;}//處理返回值,將SPI_SD_driver.c的返回值轉成ff.c的返回值if(res == 0x00)return RES_OK;else return RES_ERROR; }/*-----------------------------------------------------------------------*/ /* Miscellaneous Functions */ /*-----------------------------------------------------------------------*/ //其他表參數的獲得//drv:磁盤編號0~9//ctrl:控制代碼//*buff:發送/接收緩沖區指針 DRESULT disk_ioctl (BYTE pdrv, /* Physical drive nmuber (0..) */BYTE cmd, /* Control code */void *buff /* Buffer to send/receive control data */ ) {DRESULT res;if(pdrv==EX_FLASH) //外部FLASH{switch(cmd){case CTRL_SYNC:res = RES_OK;break;case GET_SECTOR_SIZE:*(WORD*)buff = FLASH_SECTOR_SIZE;res = RES_OK;break;case GET_BLOCK_SIZE:*(WORD*)buff = FLASH_BLOCK_SIZE;res = RES_OK;break;case GET_SECTOR_COUNT:*(DWORD*)buff = FLASH_SECTOR_NUM;res = RES_OK;break;default:res = RES_PARERR;break;}}else res=RES_ERROR;//其他的不支持return res; }//獲得時間 //User defined function to give a current time to fatfs module */ //31-25: Year(0-127 org.1980), 24-21: Month(1-12), 20-16: Day(1-31) */ //15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2) */ DWORD get_fattime (void) {u32 time=0;if((pGPS_Data.Year+2000)<1980)return 0;time=(pGPS_Data.Year+2000-1980)<<25;//年份time|=(pGPS_Data.Mouth)<<21; //月份time|=(pGPS_Data.Day)<<16; //日期time|=(pGPS_Data.Hour)<<11; //時time|=(pGPS_Data.Min)<<5; //分time|=(pGPS_Data.Sec/2); //秒return time; }將spiflash的讀寫函數嵌入fatfs的讀寫函數中,用GPS的全局時間結構體作為fatfs的時間,之后編寫一個fatfs的初始化函數:
//fatfs初始化函數,檢測無文件系統的時候會自動格式化 //成功返回剩余容量(一個0~1之間的小數),失敗返回0 FATFS FatFs; float fatfs_init(void) {FRESULT res; /* FatFs return code */DWORD fre_clust, fre_sect, tot_sect;BYTE line[512];//檢查SPI FLASH的文件系統f_mount(&FatFs, "0:", 0); //掛載FLASH.//W25Q256檢測,如果不存在文件系統,則先創建.res=f_getfree("0:", &fre_clust, &FatFs);//得到FLASH剩余容量和總容量/* Get total sectors and free sectors */tot_sect = (FatFs.n_fatent - 2) * FatFs.csize;fre_sect = fre_clust * FatFs.csize;if(res == FR_NO_FILESYSTEM)//文件系統不存在{res=f_mkfs("0:", FM_FAT32, 0, line, sizeof line);//格式化FLASHif(res==FR_OK){res=f_getfree("0:", &fre_clust, &FatFs);//重新獲取容量/* Get total sectors and free sectors */tot_sect = (FatFs.n_fatent - 2) * FatFs.csize;fre_sect = fre_clust * FatFs.csize;}}if(res==FR_OK)//得到FLASH卡剩余容量和總容量return ((float)fre_sect/(float)tot_sect);elsereturn 0; }編寫一個fatfs 的測試函數:
void fatfs_text (void) {printf("Flash text begin...\r\n");FIL fil; /* File object */UINT bw;UINT br;BYTE buff[64];FRESULT fr; /* FatFs return code */float fre_sect;f_mount(&FatFs, "0:", 0); //掛載FLASH./* Open a text file */fr = f_open(&fil, "0:text.txt", FA_OPEN_ALWAYS|FA_READ|FA_WRITE);printf ("open fill is %d\r\n",fr);/* write str in to the file */sprintf (buff,"%2d%2d%2d %2d%2d%2d %2d %2d\r\n",pGPS_Data.Year,pGPS_Data.Mouth,pGPS_Data.Day,pGPS_Data.Hour,pGPS_Data.Min,pGPS_Data.Sec,pGPS_Data.sum_satellite,pGPS_Data.PUBX_data.num);fr = f_write(&fil,buff,64,&bw);printf ("write fill is %d\r\n",fr);/* Pointer to */fr = f_lseek(&fil,0);printf (buff,"lseek fill is %d\r\n",fr);/* read str from the file */BYTE data[64] = "no data!\r\n";fr = f_read(&fil,data,64,&br);printf (data);printf ("read fill is %d\r\n",fr);/* Close the file */f_close(&fil);fre_sect = fatfs_init();printf ("free sectors is %d.0\r\n",(WORD)(fre_sect*100));printf ("Finish.\r\n"); }測試函數將一個動態的GPS數據打印出來,每次調用這個測試函數應該會提示不一樣的數據,測試打印結果如下所示:
open fill is 0
write fill is 0
lseek fill is 0
16 8 8 11211 0 12
read fill is 0
free sectors is 99.0
Finish.
0代表運行成功,創建text.txt,將GPS的數據寫入文件,并讀取從串口打印出來。至此fatfs的移植測試成功完成。
總結
以上是生活随笔為你收集整理的尝试EFM32下的fatfs的使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据库概念结构设计阶段的4个工作步骤-
- 下一篇: liferay 7.0开发到部署