简介
使用STM32USB功能配置成Mass Storage Class 存储介质使用w25qxx做U盘时,发现一个比较好玩的事情。
当换不同容量的存储介质时需要改下程序,显示不同的大小。
更改usbd_storage_if.c文件下的
/* USER CODE BEGIN PRIVATE_DEFINES */#define USER_STORAGE_LUN_NBR 1#define USER_STORAGE_BLK_NBR 512#define USER_STORAGE_BLK_SIZ 4096/* USER CODE END PRIVATE_DEFINES */
本文介绍一种更换不同容量的w25qxx时,USB设备自动判别容量大小的做法
原理
在USB初始化时,通过读取w25qxx的ID函数,得到存储介质的信息,
之后判别信息,改写为对应的容量大小。
开头:
#define STORAGE_LUN_NBR 1#define STORAGE_BLK_NBR 0x10000#define STORAGE_BLK_SIZ 0x200/* USER CODE BEGIN PRIVATE_DEFINES */#define USER_STORAGE_BLK_SIZ 4096/* USER CODE END PRIVATE_DEFINES */
初始化
/* USER CODE BEGIN PRIVATE_VARIABLES */uint32_t w25qxx_storage;/* USER CODE END PRIVATE_VARIABLES */int8_t STORAGE_Init_FS(uint8_t lun){/* USER CODE BEGIN 2 */W25QXX_Init();switch(W25QXX_TYPE){case W25Q32:w25qxx_storage = 32;break;case W25Q64:w25qxx_storage = 64;break;case W25Q128:w25qxx_storage = 128;break;case W25Q256:w25qxx_storage = 256;break;default :w25qxx_storage = 8;}w25qxx_storage = w25qxx_storage/8*1024*1024; // w25qxx_storage is xxMB, but USER_STORAGE_BLK_SIZ is xxByte. Be care of the unit!w25qxx_storage = w25qxx_storage/USER_STORAGE_BLK_SIZ;return (USBD_OK);/* USER CODE END 2 */}
USB 读取容量初始化
int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num, uint16_t *block_size){/* USER CODE BEGIN 3 */*block_num = w25qxx_storage;*block_size = USER_STORAGE_BLK_SIZ;return (USBD_OK);/* USER CODE END 3 */}
读写:
int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len){/* USER CODE BEGIN 6 */uint16_t i = 0;for(i = 0;i < blk_len;i++){W25QXX_Read(buf + i * USER_STORAGE_BLK_SIZ,blk_addr * USER_STORAGE_BLK_SIZ + i * USER_STORAGE_BLK_SIZ,USER_STORAGE_BLK_SIZ );}return (USBD_OK);/* USER CODE END 6 */}/*** @brief .* @param lun: .* @retval USBD_OK if all operations are OK else USBD_FAIL*/int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len){/* USER CODE BEGIN 7 */uint16_t i = 0;for(i = 0;i < blk_len;i++){W25QXX_Write((uint8_t *)(buf + i * USER_STORAGE_BLK_SIZ),blk_addr * USER_STORAGE_BLK_SIZ + i * USER_STORAGE_BLK_SIZ,USER_STORAGE_BLK_SIZ );}return (USBD_OK);/* USER CODE END 7 */}
*注意bug
w25qxx的驱动一般都使用正点原子的驱动
“巴特”(but),
驱动程序有问题,这个也我在测试时发现的:
w25qxx.c文件中 读取ID函数:
uint16_t W25QXX_ReadID(void){uint16_t Temp = 0;uint8_t byte = 0;W25QXX_CS(0);SPIx_ReadWriteByte(0x90); //发送读取ID命令SPIx_ReadWriteByte(0x00);SPIx_ReadWriteByte(0x00);SPIx_ReadWriteByte(0x00);SPIx_ReadByte(&byte, 1);Temp |= byte;SPIx_ReadByte(&byte, 1);Temp |= byte;W25QXX_CS(1);return Temp;}
看出问题了吗?
给你三分钟。
1min.
2min.
3min.
来揭晓答案:
.....SPIx_ReadByte(&byte, 1);Temp |= byte;Temp<<=8; //Be care of this!SPIx_ReadByte(&byte, 1);Temp |= byte;.....
正确的应该为:
uint16_t W25QXX_ReadID(void){uint16_t Temp = 0;uint8_t byte = 0;W25QXX_CS(0);SPIx_ReadWriteByte(0x90); //发送读取ID命令SPIx_ReadWriteByte(0x00);SPIx_ReadWriteByte(0x00);SPIx_ReadWriteByte(0x00);SPIx_ReadByte(&byte, 1);Temp |= byte;Temp<<=8; //Be care of this!SPIx_ReadByte(&byte, 1);Temp |= byte;W25QXX_CS(1);return Temp;}
现在就可以顺利读取芯片的ID了,之后通过读取的ID判断容量大小。
效果展示
插上w25q64
换上w25q128
人性化!