FATFS 成功应用于STM32F4的SPI FLASH!

继上一篇博客https://www.cnblogs.com/showtime20190824/p/11523402.html

这一次我们我们再深入探讨了解一下FATFS的移植过程,并尝试在其他内存上进行拓展物理磁盘,博主成功移植于SPI FLASH,硬件为W25Q256,32MB。

关于外部FLASH,具体的细节就不说了,如果对其不是很了解,建议先去学习一下。这里主要提几点需要注意的:

首先,与上一篇博客的SD卡不同的是,该FLASH的扇区sector大小不是512字节,而是4096字节,每个block块有16个扇区,每个block大小为65536,因此在CUBEMX中需要调节一个参数(最大扇区大小)

  其次,需要选一下FATFS下拉列表中的user-defined,接着生成工程文件

  自己拓展用户自定义磁盘需要在user-diskio.c中添加API接口函数,这点与SD卡不同,因为SD卡自动帮你添加了这些接口,非常方便。

下一步,打开user-diskio.c,添加接口函数,具体有USER_read,USER_write,USER_ioctl三个部分

首先根据我们选择的硬件,添加几个宏定义:

#include "STW_w25qxx.h"
#define FLASH_SECTOR_SIZE     4096    
#define FLASH_SECTOR_COUNT     256*25    //W25Q256,Ç°25M×Ö½Ú¸øFATFSÕ¼ÓÃ    
#define FLASH_BLOCK_SIZE       65536             //ÿ¸öBLOCKÓÐ8¸öÉÈÇø    

接下来修改三个部分的API函数(函数原型框架已经搭好了,只需添加有色字体的代码):

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 */
}
#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((u8*)buff,sector*FLASH_SECTOR_SIZE,FLASH_SECTOR_SIZE);
        sector++;
        buff+=FLASH_SECTOR_SIZE;
    }
    return RES_OK;
  /* USER CODE END WRITE */
}
#endif /* _USE_WRITE == 1 */
#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 */

OK,以上,我们完成了对外部FLASH的FATFS框架搭建,现在让我们编写相关代码实验一下:

void FATFS_MOUNT(void){
    POINT_COLOR = DARKBLUE;
    LCD_ShowString(400,400,500,24,24,"****** FATFS START ******");
    retSD = f_mount(&SDFatFS, "", 0) && f_mount(&USERFatFS, "", 0);
    if(retSD){
        LCD_ShowString(400,440,500,24,24,"****** mount error ******");
        LCD_ShowNum(800,440,retSD,2,24);
        Error_Handler();
    }
    else
        LCD_ShowString(400,440,500,24,24,"****** mount successfully!!! ******");
}
void FATFS_WRITE_TEST(void){
    POINT_COLOR = DARKBLUE;
    retSD = f_open(&SDFile, filename, FA_CREATE_ALWAYS | FA_WRITE) && f_open(&USERFile, filename, FA_CREATE_ALWAYS | FA_WRITE);;
    if(retSD){
        LCD_ShowString(400,480,500,24,24,"****** open file error ******");
        LCD_ShowNum(800,480,retSD,2,24);
        Error_Handler();
    }
    else
        LCD_ShowString(400,480,500,24,24,"****** open file successfully!!! ******");
    
    retSD = f_write(&SDFile, wtext, sizeof(wtext), (void *)&byteswritten) && f_write(&USERFile, wtext, sizeof(wtext), (void *)&byteswritten);
    if(retSD){
        LCD_ShowString(400,520,500,24,24,"****** write file error ******");
        LCD_ShowNum(800,520,retSD,2,24);
        Error_Handler();
    }
    else
        LCD_ShowString(400,520,500,24,24,"****** write file successfully!!! ******");
    
    retSD = f_close(&SDFile) && f_close(&USERFile);
    if(retSD){
        LCD_ShowString(400,560,500,24,24,"****** close file error ******");
        LCD_ShowNum(800,560,retSD,2,24);
        Error_Handler();
    }
    else
        LCD_ShowString(400,560,500,24,24,"****** close file successfully!!! ******");
}
void FAFTF_READ_FILE_TEST(void){
    POINT_COLOR = DARKBLUE;
    retSD = f_open(&USERFile, filename, FA_READ);;
    if(retSD){
        LCD_ShowString(400,480,500,24,24,"****** open file error ******");
        LCD_ShowNum(800,480,retSD,2,24);
        Error_Handler();
    }
    else
        LCD_ShowString(400,480,500,24,24,"****** open file successfully!!! ******");
    
    retSD = f_read(&USERFile, rtext, sizeof(rtext), (void *)&bytesread);
    if(retSD){
        LCD_ShowString(400,520,500,24,24,"****** read file error ******");
        LCD_ShowNum(800,560,retSD,2,24);
        Error_Handler();
    }
    else
        LCD_ShowString(400,520,500,24,24,"****** read file successfully!!! ******");
    
    retSD = f_close(&USERFile);
    if(retSD){
        LCD_ShowString(400,560,500,24,24,"****** close file error ******");
        LCD_ShowNum(800,560,retSD,2,24);
        Error_Handler();
    }
    else
        LCD_ShowString(400,560,500,24,24,"****** close file successfully!!! ******");
    
    POINT_COLOR = RED;
    LCD_ShowString(300,640,260,24,24,"The File Content is:");
    LCD_ShowString(560,640,500,24,24,(char*)rtext);
}

博主写了以上三个测试函数,在初始化之后while(1)之前加入下面代码:

    FATFS_MOUNT();
   FATFS_WRITE_TEST(); FAFTF_READ_FILE_TEST();

测试结果如下:

最后,提供工程文件下载链接。觉得有帮助的朋友可以关注一下博主。

链接:https://pan.baidu.com/s/1en7C-aezeWjK2dtSN20pnw
提取码:ibga

猜你喜欢

转载自www.cnblogs.com/showtime20190824/p/11526882.html