使用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 */
}
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
人性化!