这次的项目使用STM32的大容量设备进行文件传输,通过STM32的USB大容量设备将电脑中的文件放到外部FALSH中,然后在程序运行时通过FATFS文件系统读取数据访问文件。
完整工程在文末提供CSDN下载和Github下载

内容提要:USB大容量设备的移植、FATFS文件系统移植、W25Q64驱动。


建立STM32Cube工程

该工程使用STM32F103ZET6,在cube中选择对应的芯片,创建工程。启用USART1作为调试信息输出。

  1. 首先配置外部晶振,修改时钟为72MHZ。
    在这里插入图片描述
  2. 开启SPI外设
    我的FLASH芯片引脚接到SPI2,配置并修改通信波特率。
    数据长度,时钟极性,时钟相位全部默认值。
    波特率设置分频系数,在72M时钟时选择8分频,波特率为4.5MBit/s
    在这里插入图片描述
  3. 使能USB外设,启用USB大容量设备库,注意配置输入输出缓冲大小为4096,对应Flash一个扇区大小
    在这里插入图片描述
    在这里插入图片描述
  4. 启用FATFS,注意修改最大扇区大小,其他参数默认
    在这里插入图片描述
  5. 由于USB使用了堆,所以将堆栈设置大一点
    在这里插入图片描述

FLASH芯片驱动

本次使用FLASH芯片问W25Q16,芯片驱动参考使用微雪电子的相关教程,本次主要使用到这几个函数

void BSP_W25Qx_Read_ID(uint8_t *ID);		//读取芯片ID
uint8_t BSP_W25Qx_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size);		//读取指定长度数据
uint8_t BSP_W25Qx_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size);		//写入指定长度数据
uint8_t BSP_W25Qx_Erase_Block(uint32_t Address);   //扇区擦除

FATFS移植

FATFS移植核心在于user_diskio.c文件的几个函数,核心在于读写两个函数,其他部分参考文末附带的工程。
这几个宏定义了FATFS使用的扇区数和扇区大小

#define SPI_FLASH_REBUILD           1    // 1:使能格式化串行Flash,0:禁用格式化串行Flash
#define SPI_FLASH_SECTOR_SIZE    4096    // 串行Flash扇区大小
#define SPI_FLASH_START_SECTOR   256    // 串行Flash文件系统FatFS偏移量
#define SPI_FLASH_SECTOR_COUNT   256    // 串行Flash文件系统FatFS占用扇区个数    

FATFS的写函数,向FLASH芯片写入数据

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 */
	uint32_t write_addr; 
	/* 扇区偏移7MB,外部Flash文件系统空间放在SPI Flash后面9MB空间 */
	sector+=SPI_FLASH_START_SECTOR;
	write_addr = sector*SPI_FLASH_SECTOR_SIZE;    
	BSP_W25Qx_Erase_Block(write_addr);
	BSP_W25Qx_Write((uint8_t *)buff,write_addr,count*SPI_FLASH_SECTOR_SIZE);
    return RES_OK;
  /* USER CODE END WRITE */
}

FATFS的读函数,向FLASH芯片读取数据

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 */
  	/*spi flash 文件系统从第256扇区开始,共使用256个扇区,大小为1MB*/
	sector+=SPI_FLASH_START_SECTOR;   	
	BSP_W25Qx_Read(buff, sector*SPI_FLASH_SECTOR_SIZE, count*SPI_FLASH_SECTOR_SIZE);
    return RES_OK;
  /* USER CODE END READ */
}

对FATFS的驱动层移植完成后,可使用f_open等函数,对文件系统进行操作。

void fatfs_tset(void)
{
    uint8_t wtext[] = "This is STM32 working with FatFs"; /* File write buffer */
    uint8_t rtext[100];                     /* File read buffers */
	char filename[] = "STM32cube.txt";
	FATFS fs;		/*Fs文件系统对象 */
    uint8_t res;    /* Return value for SD */
    FIL fil;      // file objects

  res = f_mount(&fs, "", 0);
#if 1	//第一次格式化后将该代码段注释
    /*格式化文件系统*/
    res=f_mkfs("",0,0);
#endif
	
	res = f_open(&fil, filename, FA_CREATE_ALWAYS | FA_WRITE);
	res = f_write(&fil, wtext, sizeof(wtext), (void *)&byteswritten);
	res = f_close(&fil);

	res = f_open(&fil, filename, FA_READ);
	res = f_read(&fil, rtext, sizeof(rtext), (UINT*)&bytesread);
	printf(" Write Data : %s\r\n",rtext);
	res = f_close(&fil);
}

USB大容量设备移植

USB大容量设备移植,主要在usbd_storage_if.c文件中,同样核心部分在于读写函数

#define STORAGE_LUN_NBR                  1
#define STORAGE_BLK_NBR                  256  //使用扇区数量
#define STORAGE_BLK_SIZ                  4096    //扇区大小

//读取数据
int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
  /* USER CODE BEGIN 6 */
  blk_addr+=SPI_FLASH_START_SECTOR;   	
	BSP_W25Qx_Read(buf, blk_addr*SPI_FLASH_SECTOR_SIZE, blk_len*SPI_FLASH_SECTOR_SIZE);

  return (USBD_OK);
  /* USER CODE END 6 */
}
//写入数据
int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
  /* USER CODE BEGIN 7 */
  uint32_t write_addr; 
	blk_addr+=SPI_FLASH_START_SECTOR;
	write_addr = blk_addr*SPI_FLASH_SECTOR_SIZE;    
	BSP_W25Qx_Erase_Block(write_addr);
	BSP_W25Qx_Write((uint8_t *)buf,write_addr,blk_len*SPI_FLASH_SECTOR_SIZE);
  return (USBD_OK);
  /* USER CODE END 7 */
}

完成后将USB接入电脑即可查看U盘。并且放入文件后可使用FATFS进行读写 。

附件

如果感觉写的还不错的话,给我点个赞或者github来一个star吧!😊
github下载
CSDN下载

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐