本文总结如何使用CubeMx制作一个U盘。
由于本文将基于STM3240G-EVAL平台,主要用到USB外设和SDIO外设,所以我们主要是看这两部分外围电路。
USB外围电路:
SDIO外围电路:
另外,STM3240G-EVAL评估板使用的是25M外部晶振:
首先我们只做一个USB MSC工程,先不急着使用SDIO外设。
使用CubeMx创建一个STM32F407IHx工程:
Pinout:
RCC->Crystal/Ceramic Resonator
SYS->Serial Wire
USB_OTG_FS->Mode:Device_Only
USB_DEVICE->Class For FS IP:Mass Storage Class
Clock Configuration:
Project Settings:
堆栈设置:
我们回到CubeMx上,在pinout中为系统增加SDIO外设:
Pinout:
SDIO->Mode:SD 4bits Wide bus
并增加PH13管脚来检测SD卡是否存在,当然设置为输入模式:
就这样再次重新生成代码。
在正式对代码修改前,我们现将一个源码文件bsp_driver_sd.c及其头文件加入工程,此文件是之前一片文章(如何制作一个读取U盘文件系统的工程: http://blog.csdn.net/flydream0/article/details/53789548) ,也是由CubeMx自动生成的代码文件,可能是因为本工程并没有使用到文件系统,且CubeMx并不知道USB MSC与SDIO有明确关联,所以并没有生成SD卡对应的bsp驱动源码,因此,我们挪用下之前的源码。如下图:
int8_t STORAGE_Init_FS (uint8_t lun)
{
/* USER CODE BEGIN 2 */
BSP_SD_Init();
return (USBD_OK);
/* USER CODE END 2 */
}
接口初始化,主要是对SD卡的初始化,调用bsp_driver_sd.c的初始化函数BSP_SD_Init来实现。
读U盘 代码:
int8_t STORAGE_Read_FS (uint8_t lun,
uint8_t *buf,
uint32_t blk_addr,
uint16_t blk_len)
{
/* USER CODE BEGIN 6 */
int8_t ret = -1;
if(BSP_SD_IsDetected() != SD_NOT_PRESENT)
{
BSP_SD_ReadBlocks_DMA((uint32_t *)buf, blk_addr * STORAGE_BLK_SIZ, STORAGE_BLK_SIZ, blk_len);
ret = 0;
}
return ret;
/* USER CODE END 6 */
}
这里使用SD卡的DMA方式来读取SD内容。
写U盘:
int8_t STORAGE_Write_FS (uint8_t lun,
uint8_t *buf,
uint32_t blk_addr,
uint16_t blk_len)
{
/* USER CODE BEGIN 7 */
int8_t ret = -1;
if(BSP_SD_IsDetected() != SD_NOT_PRESENT)
{
BSP_SD_WriteBlocks_DMA((uint32_t *)buf, blk_addr * STORAGE_BLK_SIZ, STORAGE_BLK_SIZ, blk_len);
ret = 0;
}
return ret;
/* USER CODE END 7 */
}
同样,这里也是通过SD的DMA方式来写SD卡数据。
获取U盘容量信息:
int8_t STORAGE_GetCapacity_FS (uint8_t lun, uint32_t *block_num, uint16_t *block_size)
{
/* USER CODE BEGIN 3 */
HAL_SD_CardInfoTypedef info;
int8_t ret = -1;
if(BSP_SD_IsDetected() != SD_NOT_PRESENT)
{
BSP_SD_GetCardInfo(&info);
*block_num = (info.CardCapacity)/STORAGE_BLK_SIZ - 1;
*block_size = STORAGE_BLK_SIZ;
ret = 0;
}
return ret;
/* USER CODE END 3 */
}
如上代码,我们通过SD卡的BSP驱动接口函数BSP_SD_GetCardInfo来获取SD卡信息,并将数据返回。
获取U盘状态:
int8_t STORAGE_IsReady_FS (uint8_t lun)
{
/* USER CODE BEGIN 4 */
static int8_t prev_status = 0;
int8_t ret = -1;
if(BSP_SD_IsDetected() != SD_NOT_PRESENT)
{
if(prev_status < 0)
{
BSP_SD_Init();
prev_status = 0;
}
if(BSP_SD_GetStatus() == SD_TRANSFER_OK)
{
ret = 0;
}
}
else if(prev_status == 0)
{
prev_status = -1;
}
return ret;
/* USER CODE END 4 */
}
通过SD卡BSP驱动接口函数BSP_SD_GetStatus获取SD卡状态,并将结果返回。
到此,代码基本修改完成,接下来解释测试验证工作。
重新编译工程,并烧录到STM3240G-EVAL评估板,将通过micro-usb线连接到PC机后,多出一个移动U盘,双击打开,如下图所示:
这里的关键是SDIO global interrupt,DMA,就是USB中断优先级的顺序,必须SDIO>DMA>USB,不然会出错,其他的都好处理,使用CubeMx生成的默认配置即可。
另附上源码:http://download.csdn.net/detail/flydream0/9729021