今天给大家分享一下如何使用HAL库配置STM32外挂FLASH当U盘使用的案例。
我用的STM32是F103RCT6,FLASH外设是W25Q256型号,如果你是其他型号也没关系下面的代码和操作也都是通用的,大差不差。
W25Q256的数据地址是四个字节,而其他型号的比如W25Q16 32 64 128都是三个字节,这里大家需要注意。
W25Q256有512块,一块有16个扇区,一个扇区16页,一页是256字节,所以该FLASH容量大小为(512x16x16x256)/1024/1024=32MB。大小就是32M。
下面我来介绍一下配置FLASH当U盘的操作:
1、我们打开STM32CubeMX,首先配置一下FLASH的SPI引脚,然后在工程文件里导入我们从网上拷贝来的FLASH驱动文件编译测试即可。FLASH的驱动文件W25XX.c和W25XX.h网上挺多的,大家可以自行搜索下载,如果找不见或者不放心可以后台私聊我。
2、USB通信——大容量存储设备类型
回到CubeMX,在配置SPI的栏目最下面点开USB,然后点勾选。这里的参数设置我们都是默认的就行。
在下面侧边栏最后一个Middleware,点开USB_DEVICE,在菜单栏里下拉选中最后一个Mass Storage Class,参数设置里面最后一个数字我们改为4096,因为我们的FLASH一个扇区16页,一页256字节,所以一个扇区大小就是16x256=4096字节。
3、然后我们打开KEIL工程,发现侧边栏里面添加了几个文件夹,发现全是USB的,不要害怕,需要改动的地方只有一个.c文件。打开USB_DEVICE下的usbd_storage_if.c文件,只有这个文件需要编辑。
这里需要把FLASH驱动文件的.h文件添加进来。
#define STORAGE_LUN_NBR 1 /* 逻辑单元号,只有一个外部flash,设置为1 */
#define STORAGE_BLK_NBR 8192 /* 扇区的数量,外部flash的大小是32Mbyte,有512块,每块16个扇区,故512*16=8192个扇区 */
#define STORAGE_BLK_SIZ 4096 /* 每个扇区的大小,外部flash扇区的大小为4096byte */
然后改动三个宏定义变量,分别代表的意思就是FLASH设备数目、扇区数目和扇区大小。我用的是W25Q256,所以521块x16扇区=8192个扇区,如果是W25Q128那就是减半,64是128的一半,以此类推。
接着我们一次在以下四个函数里添加相应的代码(也是从网上搜的抄的)。
int8_t STORAGE_Init_FS(uint8_t lun)
{
/* USER CODE BEGIN 2 */
W25QXX_Init();
return (USBD_OK);
/* USER CODE END 2 */
}
int8_t STORAGE_IsReady_FS(uint8_t lun)
{
/* USER CODE BEGIN 4 */
W25QXX_ReadSR(1);
return (USBD_OK);
/* USER CODE END 4 */
}
int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
/* USER CODE BEGIN 6 */
/* 因为传进来的参数是扇区的地址和扇区的大小,在进行读的时候要转换成字节地址和字节大小 */
W25QXX_Read(buf,blk_addr*W25Q64_SECTOR_SIZE,blk_len*W25Q64_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 */
/* 因为传进来的参数是扇区的地址和扇区的大小,在进行写的时候要转换成字节地址和字节大小,flash写之前要擦除 */
W25QXX_Write(buf,blk_addr*W25Q64_SECTOR_SIZE,blk_len*W25Q64_SECTOR_SIZE);
return (USBD_OK);
/* USER CODE END 7 */
}
编译下载程序即可,然后用可以通信的Typec数据线连上板子接到电脑上,此时会比较卡,电脑在识别这个U盘设备,等亿会后他会说磁盘需要格式化,那就格式化,格式化之后就会出现这个U盘设备。
为了测试我们FLASH是否可以做到掉电也可存储信息,我们就可以打开U盘在里面添加个记事本写上几个字,拔掉Type-C再插上看看就可以。我测试是可行的。
有想法的小伙伴也可以试一试。