STM32 HAL SD卡U盘
·
最近查了很多关于SDIO+USB MSG的文章。得到了比较浅显的配置手段,目前也是成功的单根USB线同时供电和传输数据。并简单进行了读写测试。
需要SD卡为SDHC(Secure Digital High Capacity)类型:容量范围为2GB到32GB。
下面开始一步步配置
1.开启外部高速时钟并开启SWD下载;
2.开启SDIO并启动DMA,配置默认

3.开始USB作为设备端,其他配置默认

4.启动FATFS,并设置中文和启动长文件名,开启DMA,配置SD卡插入检测引脚



5.启用USB MSG,配置默认

6.手动配置时钟

7.配置NVIC中断优先级

8.堆栈稍微拉大点,都设置成1000,然后生成代码
9.加入#include "ff_gen_drv.h"代码

10.修改usbd_storage_if.c文件(添加两个头文件,修改三个函数)

获取存储介质容量
int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num, uint16_t *block_size)
{
/* USER CODE BEGIN 3 */
HAL_SD_CardInfoTypeDef cardInfo;
//使用SDIO库函数
HAL_StatusTypeDef res = HAL_SD_GetCardInfo(&hsd, &cardInfo);
if(res == HAL_OK)
{
*block_num = cardInfo.BlockNbr; //块的个数
*block_size = cardInfo.BlockSize; //块大小=512字节
}
else
{
*block_num = STORAGE_BLK_NBR; //0x10000
*block_size = STORAGE_BLK_SIZ; //块大小=512字节
}
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 */
//读取超时时间10000ms
uint32_t Timeout = 10000;
HAL_StatusTypeDef res = HAL_OK;
res = HAL_SD_ReadBlocks(&hsd, buf, blk_addr, blk_len, Timeout);
HAL_SD_CardStateTypeDef status = HAL_SD_CARD_RECEIVING;
if(res == HAL_OK)
{
//等待传输完成
while(status != HAL_SD_CARD_TRANSFER)
status = HAL_SD_GetCardState(&hsd);
return (USBD_OK);
}
else
return (USBD_FAIL);
/* 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 */
//写入超时时间10000ms
uint32_t Timeout = 10000;
HAL_StatusTypeDef res = HAL_OK;
res = HAL_SD_WriteBlocks(&hsd, buf, blk_addr, blk_len, Timeout);
HAL_SD_CardStateTypeDef status = HAL_SD_CARD_SENDING;
if (res == HAL_OK)
{
//等待传输完成
while(status != HAL_SD_CARD_TRANSFER)
status = HAL_SD_GetCardState(&hsd);
return (USBD_OK);
}
else
return (USBD_FAIL);
/* USER CODE END 7 */
}
11.进行主函数读写测试
/* USER CODE BEGIN 0 */
uint8_t readBuf[512];
uint8_t writeBuf[512];
BYTE work[_MAX_SS];
char *fileName = "test.txt";
uint32_t writeLen;
uint32_t readLen;
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
// 挂载
retSD = f_mount(&SDFatFS, SDPath, 1);
switch(retSD)
{
case FR_NO_FILESYSTEM: // FM_FAT32
{
retSD = f_mkfs(SDPath,FM_FAT32,512,work, sizeof(work));
if(retSD!=FR_OK)
{
while(1);
}
}
break;
case FR_OK:break;
default:
while(1);
}
// 写
retSD = f_open(&SDFile,fileName, FA_CREATE_ALWAYS | FA_WRITE);
if(retSD!=FR_OK)
{
while(1);
}
sprintf((char *)writeBuf,"%s","abc123今天天气还可以\r\n");
retSD = f_write(&SDFile,writeBuf, strlen((const char *)writeBuf), &writeLen);
if(retSD!=FR_OK)
{
while(1);
}
f_close(&SDFile);
// 读
retSD = f_open(&SDFile,fileName, FA_OPEN_EXISTING | FA_READ);
if(retSD!=FR_OK)
{
while(1);
}
retSD = f_read(&SDFile,readBuf, 50, &readLen);
if(retSD!=FR_OK)
{
while(1);
}
f_close(&SDFile);
// 卸载
f_mount(NULL, SDPath, 1);
/* USER CODE END 2 */
12.现象
USB加载需要大概10s,很慢,
参考文献:【CubeMX+STM32】SD卡 U盘文件系统 USB+FATFS_stm32cubemx fatfs-CSDN博客
STM32CubeMX教程30 USB_DEVICE - MSC外设_读卡器_stm32cubemx配置usb读卡器-CSDN博客
更多推荐



所有评论(0)