STM32 USB 使用芯片内部flash模拟U盘

来源:互联网 发布:密码破译软件 编辑:程序博客网 时间:2024/06/05 19:03
这次是实现一个使用STM32内部的flash模拟一个U盘。我使用的STM32芯片是STM32F103ZE,该芯片有512K的内部flash,本次工程,我准备用最后的400K空间来模拟一个U盘。本次的工程在之前用NAND或SD卡模拟U盘的工程基础上进行修改。
首次要做的是在外设库组中添加stm32f10x_flash.c文件,因为涉及到内部flash,所以必须添加此文件。接下去,需要修改的文件只有mass_mal.c和memory.c两个了。

先来讲讲memory.c,这个文件修改量很小。在函数的前面,我们可以看到有个:uint32_t Data_Buffer[];数组的定义,该数组的数组元素个数,跟大家所使用的存储器的块大小有关。比如说,在NNAD工程里,带数组这样定义:uint32_t Data_Buffer[BULK_MAX_PACKET_SIZE *2];(BULK_MAX_PACKET_SIZE =64)可以看到总共有128个字,也就是512字节;在SD卡的程序中也是512字节;为这次我们使用内部的flash,需要定义成2K字节:uint32_t Data_Buffer[BULK_MAX_PACKET_SIZE *8]。还有需要注意下,在Write_Memory()和Read_Memory()中MAL层读写函数我们使用官方例程上的调用代码,而不是之前我们讲过的NAND无法格式化解决的那篇文章的调用代码。调用如下:
MAL_Read(lun ,Offset , Data_Buffer,Mass_Block_Size[lun]);
MAL_Write(lun ,W_Offset - Mass_Block_Size[lun],Data_Buffer,Mass_Block_Size[lun]);

接着是mass_mal.c这个文件修改量比较大。首先,得在该文件的最前面需要定义一些与flash相关的宏定义:

#define FLASH_START_ADDR 0x08016000 // Flash start address #define FLASH_SIZE 0x64000 // 400K 的U盘 #define FLASH_PAGE_SIZE 0x800 // 2k Bytes per page,只有2K才能格式化#define FLASH_WAIT_TIMEOUT 100000 //操等待时间

然后要编写MAL_Init()、MAL_Write()、MAL_Read()、MAL_GetStatus()这里不多做介绍,贴出代码:

#include "mass_mal.h"

#define FLASH_START_ADDR 0x08016000 // Flash start address #define FLASH_SIZE 0x64000 // 400K 的U盘 #define FLASH_PAGE_SIZE 0x800 // 2k Bytes per page,只有2K才能格式化#define FLASH_WAIT_TIMEOUT 100000/* Private typedef -----------------------------------------------------------*//* Private define ------------------------------------------------------------*//* Private macro -------------------------------------------------------------*//* Private variables ---------------------------------------------------------*/uint32_t Mass_Memory_Size[2];uint32_t Mass_Block_Size[2];uint32_t Mass_Block_Count[2];__IO uint32_t Status = 0;/* Private function prototypes -----------------------------------------------*//* Private functions ---------------------------------------------------------*//******************************************************************************** Function Name : MAL_Init* Description : 初始化STM32的媒体设备* Input : lun* Output : None* Return : None*******************************************************************************/uint16_t MAL_Init(uint8_t lun){ u16 status = MAL_OK; switch (lun) { case 0: FLASH_Unlock(); break; default: return MAL_FAIL; } return status;}/******************************************************************************** Function Name : MAL_Write* Description : 写扇区* Input : None* Output : None* Return : None*******************************************************************************/uint16_t MAL_Write(uint8_t lun, uint32_t Memory_Offset, uint32_t *Writebuff, uint16_t Transfer_Length){ uint16_t i; switch (lun) { case 0: for(i=0;i<Transfer_Length;i+=FLASH_PAGE_SIZE){if(FLASH_WaitForLastOperation(FLASH_WAIT_TIMEOUT)!=FLASH_TIMEOUT){FLASH_ClearFlag(FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);}FLASH_ErasePage(FLASH_START_ADDR + Memory_Offset + i); }for(i=0;i<Transfer_Length;i+=4){if(FLASH_WaitForLastOperation(FLASH_WAIT_TIMEOUT)!=FLASH_TIMEOUT){FLASH_ClearFlag(FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);}FLASH_ProgramWord(FLASH_START_ADDR + Memory_Offset + i , Writebuff[i>>2]);} break; default: return MAL_FAIL; } return MAL_OK;}/******************************************************************************** Function Name : MAL_Read* Description : 读取扇区* Input : None* Output : None* Return : Buffer pointer*******************************************************************************/uint16_t MAL_Read(uint8_t lun, uint32_t Memory_Offset, uint32_t *Readbuff, uint16_t Transfer_Length){ uint16_t i; switch (lun) { case 0: for(i=0;i<Transfer_Length;i+=4){Readbuff[i>>2] = ((vu32*)(FLASH_START_ADDR + Memory_Offset))[i>>2];} break; default: return MAL_FAIL; } return MAL_OK;}/******************************************************************************** Function Name : MAL_GetStatus* Description : 获取状态* Input : None* Output : None* Return : None*******************************************************************************/uint16_t MAL_GetStatus (uint8_t lun){ if (lun == 0) { Mass_Block_Count[0] = FLASH_SIZE/FLASH_PAGE_SIZE; Mass_Block_Size[0] = FLASH_PAGE_SIZE; Mass_Memory_Size[0] = FLASH_SIZE;LED2_ON();return MAL_OK;} LED2_OFF();

  return MAL_FAIL;}


虽然说,我们上面定义了400KB留作空间,但,我们在电脑上只看见375K左右的空间,这属于正常现象。还有,之前在调代码的时候,又出现了无法格式化的问题,经过一番推敲,才发现是定义flash也的大小出现了问题,之前定义成1K,发现不想,修改成2K才成功,就是我们上面的 :#define FLASH_PAGE_SIZE 0x800。
STM32 USB 使用芯片内部flash模拟U盘 - ziye334 - ziye334的博客
写速度如下,读速度无法测,因为空间太小,能存放的文件也太小,拷贝数据简直就是一瞬间的事:
STM32 USB 使用芯片内部flash模拟U盘 - ziye334 - ziye334的博客
0 0