我是靠谱客的博主 傲娇小霸王,最近开发中收集的这篇文章主要介绍FATFS文件系统管理W25Q128,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1首先用STM32CUBEMX配置

如下图:
在这里插入图片描述

2重点修改user_diskio.c

/* USER CODE BEGIN Header */
/**
 ******************************************************************************
  * @file    user_diskio.c
  * @brief   This file includes a diskio driver skeleton to be completed by the user.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
 /* USER CODE END Header */

#ifdef USE_OBSOLETE_USER_CODE_SECTION_0
/*
 * Warning: the user section 0 is no more in use (starting from CubeMx version 4.16.0)
 * To be suppressed in the future.
 * Kept to ensure backward compatibility with previous CubeMx versions when
 * migrating projects.
 * User code previously added there should be copied in the new user sections before
 * the section contents can be deleted.
 */
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
#endif

/* USER CODE BEGIN DECL */

/* Includes ------------------------------------------------------------------*/
#include <string.h>
#include "ff_gen_drv.h"

/* Private typedef -----------------------------------------------------------*/
#include "w25qxx.h"
#define FLASH_SECTOR_SIZE     4096   //每个扇区4K
#define FLASH_SECTOR_COUNT   256*16  //W25Q128有256block,每个block16扇区
#define FLASH_BLOCK_SIZE       65536    //16*4096    

/* Private define ------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/
/* Disk status */
static volatile DSTATUS Stat = STA_NOINIT;

/* USER CODE END DECL */

/* Private function prototypes -----------------------------------------------*/
DSTATUS USER_initialize (BYTE pdrv);
DSTATUS USER_status (BYTE pdrv);
DRESULT USER_read (BYTE pdrv, BYTE *buff, DWORD sector, UINT count);
#if _USE_WRITE == 1
  DRESULT USER_write (BYTE pdrv, const BYTE *buff, DWORD sector, UINT count);
#endif /* _USE_WRITE == 1 */
#if _USE_IOCTL == 1
  DRESULT USER_ioctl (BYTE pdrv, BYTE cmd, void *buff);
#endif /* _USE_IOCTL == 1 */

Diskio_drvTypeDef  USER_Driver =
{
  USER_initialize,
  USER_status,
  USER_read,
#if  _USE_WRITE
  USER_write,
#endif  /* _USE_WRITE == 1 */
#if  _USE_IOCTL == 1
  USER_ioctl,
#endif /* _USE_IOCTL == 1 */
};

/* Private functions ---------------------------------------------------------*/

/**
  * @brief  Initializes a Drive
  * @param  pdrv: Physical drive number (0..)
  * @retval DSTATUS: Operation status
  */
DSTATUS USER_initialize (
	BYTE pdrv           /* Physical drive nmuber to identify the drive */
)
{
  /* USER CODE BEGIN INIT */
    Stat = STA_NOINIT;
    return RES_OK;
  /* USER CODE END INIT */
}

/**
  * @brief  Gets Disk Status
  * @param  pdrv: Physical drive number (0..)
  * @retval DSTATUS: Operation status
  */
DSTATUS USER_status (
	BYTE pdrv       /* Physical drive number to identify the drive */
)
{
  /* USER CODE BEGIN STATUS */
    Stat = STA_NOINIT;
    return RES_OK;
  /* USER CODE END STATUS */
}

/**
  * @brief  Reads Sector(s)
  * @param  pdrv: Physical drive number (0..)
  * @param  *buff: Data buffer to store read data
  * @param  sector: Sector address (LBA)
  * @param  count: Number of sectors to read (1..128)
  * @retval DRESULT: Operation result
  */
DRESULT USER_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 */
)
{
  /* USER CODE BEGIN READ */
		for(;count>0;count--){
        W25QXX_Read(buff,sector*FLASH_SECTOR_SIZE,FLASH_SECTOR_SIZE);
        sector++;
        buff+=FLASH_SECTOR_SIZE;
    }
    return RES_OK;
  /* USER CODE END READ */
}

/**
  * @brief  Writes Sector(s)
  * @param  pdrv: Physical drive number (0..)
  * @param  *buff: Data to be written
  * @param  sector: Sector address (LBA)
  * @param  count: Number of sectors to write (1..128)
  * @retval DRESULT: Operation result
  */
#if _USE_WRITE == 1
DRESULT USER_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 */
)
{
  /* USER CODE BEGIN WRITE */
  /* USER CODE HERE */
for(;count>0;count--){                                            
        W25QXX_Write((uint8_t *)buff,sector*FLASH_SECTOR_SIZE,FLASH_SECTOR_SIZE);
        sector++;
        buff+=FLASH_SECTOR_SIZE;
    }
	
	
    return RES_OK;
  /* USER CODE END WRITE */
}
#endif /* _USE_WRITE == 1 */

/**
  * @brief  I/O control operation
  * @param  pdrv: Physical drive number (0..)
  * @param  cmd: Control code
  * @param  *buff: Buffer to send/receive control data
  * @retval DRESULT: Operation result
  */
#if _USE_IOCTL == 1
DRESULT USER_ioctl (
	BYTE pdrv,      /* Physical drive nmuber (0..) */
	BYTE cmd,       /* Control code */
	void *buff      /* Buffer to send/receive control data */
)
{
  /* USER CODE BEGIN IOCTL */
    DRESULT res = RES_ERROR;
	
	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 = (WORD)FLASH_BLOCK_SIZE;
                res = RES_OK;
                break;     
        case GET_SECTOR_COUNT:
                *(DWORD*)buff = FLASH_SECTOR_COUNT;
                res = RES_OK;
                break;
        default:
                res = RES_PARERR;
                break;
    }
    return res;
  /* USER CODE END IOCTL */
}
#endif /* _USE_IOCTL == 1 */

3在main函数添加代码并测试

BYTE work[4096];
BYTE WriteBuffer[]=  "hello world123";
BYTE ReadBuffer[1024] = {0}; 

void FATFS_MOUNT(void){
   printf("FATFS START");
	retUSER  = f_mount(&USERFatFS, USERPath, 1);

    if(retUSER ==FR_NO_FILESYSTEM)
	{
       printf("fmkfs");
        /* 格式化 */
		retUSER  = f_mkfs(USERPath, 1, 0, work, sizeof(work));
		if(retUSER  == FR_OK)
			{
					 printf("fmkfs success");
					/* 格式化后,先取消挂载 */
					retUSER  = f_mount(NULL, USERPath, 1);
					/* 重新挂载 */
					retUSER  = f_mount(&USERFatFS,USERPath, 1);
			}
		else
		{
				printf("fmkfs error");
					while(1);
		}       
    }
    else if(retUSER  != FR_OK)
    {
      printf("mount error");
        while(1);
    }
    else
    {
        printf("mount succes");
    }
}

void FATFS_WRITE_TEST(void){
   
	retUSER =  f_open(&USERFile, "1:/data.txt", FA_OPEN_ALWAYS | FA_WRITE);
    if(retUSER){
			printf("open error");
			 while(1);
    }
    else
			printf("open success");
 		
    retUSER = f_write(&USERFile, WriteBuffer, sizeof(WriteBuffer),  &fnum);
    if(retUSER){
			printf("write error");
			 while(1);
    }
    else
        printf("write success");
		
    retUSER = f_close(&USERFile);
    
//读
	void FAFTF_READ_FILE_TEST(void){
  
    retUSER = f_open(&USERFile, "1:/data.txt", FA_READ);
    if(retUSER){
       	printf("open error");
			 while(1);
    }
    else
       printf("open success");
    
    retUSER = f_read(&USERFile, ReadBuffer, 100, &fnum);
    if(retUSER){
        	printf("read error");
			 while(1);
    }
    else
       printf("read success");
    
    retUSER = f_close(&USERFile);
  		
}

int main(void)
{
  MX_SPI1_Init();
  W25QXX_Init();
  MX_FATFS_Init();

  FATFS_MOUNT();
  HAL_Delay(1000);
  FATFS_WRITE_TEST();
  HAL_Delay(1000);

FAFTF_READ_FILE_TEST();
f_mount(NULL, USERPath, 1);
while(1);
}

用LCD显示过程。

在这里插入图片描述
经过测试能用,但是不推荐用FATFS管理spi flash。
因为使用FATFS管理上没有擦写均衡功能。spi flash寿命有限。
推荐使用LittleFS文件管理系统。
FATFS的优势在于能用电脑查看,适用于TF卡等能插在电脑上看的存储器。

最后

以上就是傲娇小霸王为你收集整理的FATFS文件系统管理W25Q128的全部内容,希望文章能够帮你解决FATFS文件系统管理W25Q128所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(79)

评论列表共有 0 条评论

立即
投稿
返回
顶部