• 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

  • 相关阅读:
    常用Linux命令
    KDevolop使用小技巧
    微软在5/10/2006发布新版的LINQ Preview (May 2006).msi 无为而为
    盼望已久的Office Live Beta 已经发布,大家可以去尝尝鲜 无为而为
    需求工程:TFS MSF模版中UI Flow model的应用 无为而为
    Visual Studio 2005 Team Foundation Server 试用版及中文说明文件下载,中文版可能在2006年5月15日发布 无为而为
    让我们努力从“不可救药的乐观主义者”华尔街知名投资人约翰。多尔那里学点东西(永远放弃尝试改变这个世界) 无为而为
    Visual Studio 2005 开发Office(Word/Excel)项目的若干资源和示例 无为而为
    IT人看《国富论》系列:第一篇之第十章:论工资与利润随劳动与资本用途的不同而不同,分析分析IT界薪水起伏的原因 无为而为
    非正常状态,彻底删除Exchange服务器 无为而为
  • 原文地址:https://www.cnblogs.com/showtime20190824/p/11526882.html
Copyright © 2020-2023  润新知