一、編程要點
1、將FATFS文件系統添加到工程中
2、修改diskio.c 文件接口以及ffconf.h相關宏
3、編寫測試函數
二、修改diskio.c 文件
1、disk_status()函數
功能:獲取磁盤當前(物理)狀態
DSTATUS disk_status (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
DSTATUS stat;
switch (pdrv) {
case ATA_SD :
break;
case SPI_FLASH :
if(Read_FlashID() == sFLASH_ID)
{
stat=0;
}
else
{
stat=STA_NOINIT;
}
return stat;
}
return stat;
}
2、disk_initialize ()
功能:文件系統初始化
DSTATUS disk_initialize (
BYTE pdrv /* 磁盤號 */
)
{
u32 i=500;
switch (pdrv) {
case ATA_SD :
break;
case SPI_FLASH :
SPI_FLASH_config(); //FLASH初始化
SPI_Flash_WAKEUP(); //喚醒FLASH
while(i--);
return disk_status(SPI_FLASH); //獲取磁盤狀態
}
return STA_NOINIT;
}
3、disk_read (),disk_write ()
功能:讀寫FLASH接口函數
DRESULT disk_read (
BYTE pdrv, /*磁盤號*/
BYTE *buff, /*讀緩存指針 */
DWORD sector, /* 讀地址 */
UINT count /* 讀數量 */
)
{
DRESULT res;
switch (pdrv) {
case ATA_SD :
break;
case SPI_FLASH :
sector+=512; //偏移2M字節
FLASH_Read(sector<<12,buff, count<<12); //讀數據 地址 緩存指針 長度(<<12->*4096)
res=RES_OK;
return res;
default :
res=RES_PARERR;
return res;
}
return res;
}
/*-----------------------------------------------------------------------*/
/* Write Sector(s) */
/*-----------------------------------------------------------------------*/
#if _USE_WRITE
DRESULT disk_write (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
const BYTE *buff, /* Data to be written */
DWORD sector, /* Sector address in LBA */
UINT count /* Number of sectors to write */
)
{
DRESULT res;
switch (pdrv) {
case ATA_SD :
break;
case SPI_FLASH :
sector+=512;
FLASH_SectorErase(sector<<12); //擦除要寫的塊
SPI_FLASH_BufferWrite((u8*)buff, sector<<12,count<<12);
res=RES_OK;
return res;
}
return res;
}
三、測試程序
1、判斷並寫入(格式化)文件系統
if(res_flash == FR_NO_FILESYSTEM) //FR_NO_FILESYSTEM
{
printf("未發現文件系統,進行格式化\n");
res_flash=f_mkfs ("1:",0,0 ); //格式化
printf("格式化結果 res =%d\n",res_flash);
if(res_flash==FR_OK)
{
printf("格式化化成功\n");
res_flash=f_mount (NULL,"1:",1); //取消掛載
printf("掛載結果1 res =%d",res_flash);
res_flash=f_mount (&fs,"1:",1); //重新掛載
printf("掛載結果2 res =%d\n",res_flash);
}
}
2、讀寫函數
res_flash=f_write (&fnew, textFileBuffer, sizeof(textFileBuffer), &bw);/
//文件矩柄 寫緩存指針 寫長度 已寫長度
res_flash=f_read (&fnew, buffer, f_size(&fnew), &br);
//文件矩柄 讀緩存指針 讀長度 已讀取長度
四、程序源碼
1、diskio.c
#include "diskio.h" /* FatFs lower layer API */
#include "bsp_flash.h"
#define ATA_SD 0
#define SPI_FLASH 1
#define SD_CARD 2
#define sFLASH_ID 0XEF4017
DSTATUS disk_status (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
DSTATUS stat;
switch (pdrv) {
case ATA_SD :
break;
case SPI_FLASH :
if(Read_FlashID() == sFLASH_ID)
{
stat=0;
}
else
{
stat=STA_NOINIT;
}
return stat;
}
return stat;
}
/*-----------------------------------------------------------------------*/
/* Inidialize a Drive */
/*-----------------------------------------------------------------------*/
DSTATUS disk_initialize (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
u32 i=500;
// DSTATUS stat;
// int result;
switch (pdrv) {
case ATA_SD :
break;
case SPI_FLASH :
SPI_FLASH_config();
SPI_Flash_WAKEUP();
while(i--);
return disk_status(SPI_FLASH);
}
return STA_NOINIT;
}
/*-----------------------------------------------------------------------*/
/* Read Sector(s) */
/*-----------------------------------------------------------------------*/
DRESULT disk_read (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
BYTE *buff, /* Data buffer to store read data */
DWORD sector, /* Sector address in LBA */
UINT count /* Number of sectors to read */
)
{
DRESULT res;
switch (pdrv) {
case ATA_SD :
break;
case SPI_FLASH :
sector+=512;
FLASH_Read(sector<<12,buff, count<<12); //讀數據 地址 緩存指針 長度
res=RES_OK;
return res;
default :
res=RES_PARERR;
return res;
}
return res;
}
/*-----------------------------------------------------------------------*/
/* Write Sector(s) */
/*-----------------------------------------------------------------------*/
#if _USE_WRITE
DRESULT disk_write (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
const BYTE *buff, /* Data to be written */
DWORD sector, /* Sector address in LBA */
UINT count /* Number of sectors to write */
)
{
DRESULT res;
// int result;
switch (pdrv) {
case ATA_SD :
break;
case SPI_FLASH :
sector+=512;
FLASH_SectorErase(sector<<12);
SPI_FLASH_BufferWrite((u8*)buff, sector<<12,count<<12);
//SPI_FLASH_Write((u8*)buff,sector<<12,count<<12);
res=RES_OK;
return res;
}
return res;
}
#endif
/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions */
/*-----------------------------------------------------------------------*/
#if _USE_IOCTL
DRESULT disk_ioctl (
BYTE pdrv, /* Physical drive nmuber (0..) */
BYTE cmd, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
DRESULT res;
// int result;
switch (pdrv) {
case ATA_SD :
break;
case SPI_FLASH :
switch (cmd)
{ //扇區數量
case GET_SECTOR_COUNT :
*(DWORD*)buff=1536;
break;
//扇區大小
case GET_SECTOR_SIZE :
*(WORD*)buff=4096;
break;
case GET_BLOCK_SIZE :
*(DWORD*)buff=1;
break;
}
res = RES_OK;
return res;
}
return res;
}
#endif
//返回時間
DWORD get_fattime (void)
{
return 0;
}
2、main.c文件
#include "stm32f10x.h" // 相當於51單片機中的 #include <reg51.h>
#include "bsp_led.h"
#include "usart.h"
#include "bsp_flash.h"
#include "diskio.h"
#include "ff.h"
#define GPIOB_ODR_Addr (GPIOB_BASE+0X0C)
#define PBout(n) *(unsigned int *)((GPIOB_ODR_Addr & 0xF0000000)+0x02000000+((GPIOB_ODR_Addr&0x00FFFFFF)<<5)+(n<<2))
FATFS fs; /* FatFs 文件系統對象 */
FIL fnew; /* 文件對象 */
FRESULT res_flash; /* 文件操作結果 */
UINT fnum; /* 文件成功讀寫數量 */
BYTE buffer[1024]= {0}; /* 讀緩衝區 */
BYTE textFileBuffer[] = /* 寫緩衝區*/
"歡迎使用野火 STM32 開發板 今天是個好日子,新建文件系統測試文件\r\n";
UINT bw;
UINT br;
int main(void)
{
LED_GPIO_Config();
PBout(0)=1;
USART_config();
printf("\n串口初始化成功\n");
res_flash=f_mount (&fs,"1:",1);
//掛載文件系統
printf("res=%d\n",res_flash);
if(res_flash == FR_NO_FILESYSTEM) //FR_NO_FILESYSTEM
{
printf("未發現文件系統,進行格式化\n");
res_flash=f_mkfs ("1:",0,0 ); //格式化
printf("格式化結果 res =%d\n",res_flash);
if(res_flash==FR_OK)
{
printf("格式化化成功\n");
res_flash=f_mount (NULL,"1:",1); //取消掛載
printf("掛載結果1 res =%d",res_flash);
res_flash=f_mount (&fs,"1:",1); //重新掛載
printf("掛載結果2 res =%d\n",res_flash);
}
}
res_flash=f_open (&fnew, "1:abc.txt", FA_OPEN_ALWAYS|FA_READ|FA_WRITE);
printf("open=%d\n",res_flash);
if(res_flash==FR_OK)
{
printf("創建/打開文件成功\n");
res_flash=f_write (&fnew, textFileBuffer, sizeof(textFileBuffer), &bw);
if(res_flash==FR_OK)
{
printf("寫入數量爲 bw=%d\n",bw);
// 不再讀寫,關閉文件
//f_close(&fnew);
f_lseek(&fnew,0);
res_flash=f_read (&fnew, buffer, f_size(&fnew), &br);
printf("讀取結果 read=%d br=%d\n",res_flash,br);
if(res_flash==FR_OK)
{
printf(" 讀取內容爲:%s\n",buffer);
}
}
else
{
printf("寫入失敗\n");
}
}
while (1)
{
}
}