STM32 USB 使用芯片內部flash模擬U盤

此次是實現一個使用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();ui

  return MAL_FAIL; } spa


雖說,咱們上面定義了400KB留做空間,但,咱們在電腦上只看見375K左右的空間,這屬於正常現象。還有,以前在調代碼的時候,又出現了沒法格式化的問題,通過一番推敲,才發現是定義flash也的大小出現了問題,以前定義成1K,發現不想,修改爲2K才成功,就是咱們上面的 :# define FLASH_PAGE_SIZE 0x800。
STM32 USB 使用芯片內部flash模擬U盤 - ziye334 - ziye334的博客
寫速度以下,讀速度沒法測,由於空間過小,能存放的文件也過小,拷貝數據簡直就是一瞬間的事:
STM32 USB 使用芯片內部flash模擬U盤 - ziye334 - ziye334的博客