HAL库USB+SD卡,读卡器设置
主控:STM32L476VE
STM32CUBE设置如下
开启SDMMC的DMA,RX和TX都设置为轮询模式
开启FATFS修改红框中内容
开启USB,设置device_only
host:主机
device:从机
OTG:既可以是主机也可以是从机,双功能设备
speed:传输速度,全速USB最高12M
low power: 低功耗模式
link power management :电源管理
VBUS sensing :USB 检测
signal start of frame:帧开始信号
开启USB_DEVICE中间件,选择mass storage class
mass storage class :大容量存储
audio storage class :音频协议
Communication Device Class:USB通信设备
download firmware updata : 固件更新
human interface device class :HID设备
中断优先级设置,SDMMC的DMA中断要低于SDMMC中断,USB中断要低于SDMMC的DMA中断
修改sdmmc.C和bsp_driver_sd.c见上一篇
修改usbd_storage_if.c
int8_t STORAGE_Init_FS(uint8_t lun)
{
/* USER CODE BEGIN 2 */
//MX_SDMMC1_SD_Init();
BSP_SD_Init();
return (USBD_OK);
/* USER CODE END 2 */
}
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.LogBlockNbr - 1;
*block_size = info.LogBlockSize;
ret = 0;
}
return ret;
/* USER CODE END 3 */
}
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_GetCardState() == SD_TRANSFER_OK)
{
ret = 0;
}
}
else if(prev_status == 0)
{
prev_status = -1;
}
return ret;
/* USER CODE END 4 */
}
int8_t STORAGE_IsWriteProtected_FS(uint8_t lun)
{
/* USER CODE BEGIN 5 */
return (USBD_OK);
/* USER CODE END 5 */
}
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, blk_len);
/* Wait for Rx Transfer completion */
// while (ReadStatus == 0){}
// ReadStatus = 0;
/* Wait until SD card is ready to use for new operation */
while (BSP_SD_GetCardState() != SD_TRANSFER_OK){}
ret = 0;
}
return ret;
/* 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 */
int8_t ret = -1;
if(BSP_SD_IsDetected() != SD_NOT_PRESENT)
{
BSP_SD_WriteBlocks_DMA((uint32_t *)buf, blk_addr, blk_len);
/* Wait for Tx Transfer completion */
// while (WriteStatus == 0){}
// WriteStatus = 0;
/* Wait until SD card is ready to use for new operation */
while (BSP_SD_GetCardState() != SD_TRANSFER_OK){}
ret = 0;
}
return ret;
/* USER CODE END 7 */
}
int8_t STORAGE_GetMaxLun_FS(void)
{
/* USER CODE BEGIN 8 */
return (STORAGE_LUN_NBR - 1);
/* USER CODE END 8 */
}
插入usb,电脑文件管理中就会显示有u盘了。
其中写函数中的
while (WriteStatus == 0){}
WriteStatus = 0;
和读函数中的
while (ReadStatus == 0){}
ReadStatus = 0;
这四句语句为官方例程中带的,注释掉后也可正常使用
但不注释掉会有问题
上面两个等待的变量应该在下面这两个回调函数中置1
void BSP_SD_WriteCpltCallback(void)
{
WriteStatus = 1;
}
void BSP_SD_ReadCpltCallback(void)
{
ReadStatus = 1;
}
需要修改sd_diskio.c文件中static volatile UINT WriteStatus = 0, ReadStatus = 0;
改为uint8_t WriteStatus = 0, ReadStatus = 0;(定义为全局变量)
在sd_diskio.h文件中声明extern uint8_t WriteStatus , ReadStatus ;
(同时加上#include “ff_gen_drv.h”,否则Diskio_drvTypeDef 报错)
在usbd_storage_if.c文件中加上#include “sd_diskio.h”
然后编译即可