一、编程要点
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)
{
}
}