FATFS_FLASH文件系统

一、编程要点

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)
  {      
  }
}

猜你喜欢

转载自blog.csdn.net/qq_41985317/article/details/80807940