Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
STM32F407
USB
STM32F407 SDIO挂载SD卡并使用USB模拟U盘拷贝文件
发布于 2024-07-04 14:30:10 浏览:622
订阅该版
[tocm] ## 一.rtthread studio生成基础代码 ## 二.配置setting 1.总览 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20240807/c3c5f6bb932aa063ee43edd09dd190c1.png.webp) 2.配置内核 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20240807/dcbaf65333b5efd0696771245d7aedaf.png.webp) 3.配置文件系统 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20240807/bc5f6e49be63be34dfbc24c4efd1cee4.png) ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20240807/d4a2e784bf25ac6ca89ce879c4bf1d41.png.webp) 4.配置USB接口 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20240807/373c885cecfc5f9a7a021f911aadc4f4.png) ## 三、复制STM32cubemx生成的的xxx_hal_msp.c文件中的io初始化代码到board.c中 包括SD卡的SDIO,USB初始化,还有时钟初始化 ```c /** * @brief SD MSP Initialization * This function configures the hardware resources used in this example * @param hsd: SD handle pointer * @retval None */ void HAL_SD_MspInit(SD_HandleTypeDef* hsd) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(hsd->Instance==SDIO) { /* USER CODE BEGIN SDIO_MspInit 0 */ /* USER CODE END SDIO_MspInit 0 */ /* Peripheral clock enable */ __HAL_RCC_SDIO_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); /**SDIO GPIO Configuration PC8 ------> SDIO_D0 PC9 ------> SDIO_D1 PC10 ------> SDIO_D2 PC11 ------> SDIO_D3 PC12 ------> SDIO_CK PD2 ------> SDIO_CMD */ GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11 |GPIO_PIN_12; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF12_SDIO; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_2; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF12_SDIO; HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); /* USER CODE BEGIN SDIO_MspInit 1 */ /* USER CODE END SDIO_MspInit 1 */ } } /** * @brief SD MSP De-Initialization * This function freeze the hardware resources used in this example * @param hsd: SD handle pointer * @retval None */ void HAL_SD_MspDeInit(SD_HandleTypeDef* hsd) { if(hsd->Instance==SDIO) { /* USER CODE BEGIN SDIO_MspDeInit 0 */ /* USER CODE END SDIO_MspDeInit 0 */ /* Peripheral clock disable */ __HAL_RCC_SDIO_CLK_DISABLE(); /**SDIO GPIO Configuration PC8 ------> SDIO_D0 PC9 ------> SDIO_D1 PC10 ------> SDIO_D2 PC11 ------> SDIO_D3 PC12 ------> SDIO_CK PD2 ------> SDIO_CMD */ HAL_GPIO_DeInit(GPIOC, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11 |GPIO_PIN_12); HAL_GPIO_DeInit(GPIOD, GPIO_PIN_2); /* USER CODE BEGIN SDIO_MspDeInit 1 */ /* USER CODE END SDIO_MspDeInit 1 */ } } void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOA_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_RESET); /*Configure GPIO pin : PA12 */ GPIO_InitStruct.Pin = GPIO_PIN_12; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLDOWN; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12,GPIO_PIN_RESET); HAL_Delay(65); //先把PA12拉低再拉高,利用D+模拟USB的拔插动作 HAL_GPIO_WritePin(GPIOA,GPIO_PIN_12,GPIO_PIN_SET); HAL_Delay(65); } void HAL_PCD_MspInit(PCD_HandleTypeDef* pcdHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; MX_GPIO_Init(); if(pcdHandle->Instance==USB_OTG_FS) { /* USER CODE BEGIN USB_OTG_FS_MspInit 0 */ /* USER CODE END USB_OTG_FS_MspInit 0 */ __HAL_RCC_GPIOA_CLK_ENABLE(); /**USB_OTG_FS GPIO Configuration PA11 ------> USB_OTG_FS_DM PA12 ------> USB_OTG_FS_DP */ GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* Peripheral clock enable */ __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); /* Peripheral interrupt init */ HAL_NVIC_SetPriority(OTG_FS_IRQn, 0, 0); HAL_NVIC_EnableIRQ(OTG_FS_IRQn); /* USER CODE BEGIN USB_OTG_FS_MspInit 1 */ /* USER CODE END USB_OTG_FS_MspInit 1 */ } } void HAL_PCD_MspDeInit(PCD_HandleTypeDef* pcdHandle) { if(pcdHandle->Instance==USB_OTG_FS) { /* USER CODE BEGIN USB_OTG_FS_MspDeInit 0 */ /* USER CODE END USB_OTG_FS_MspDeInit 0 */ /* Peripheral clock disable */ __HAL_RCC_USB_OTG_FS_CLK_DISABLE(); /**USB_OTG_FS GPIO Configuration PA11 ------> USB_OTG_FS_DM PA12 ------> USB_OTG_FS_DP */ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12); /* Peripheral interrupt Deinit*/ HAL_NVIC_DisableIRQ(OTG_FS_IRQn); /* USER CODE BEGIN USB_OTG_FS_MspDeInit 1 */ /* USER CODE END USB_OTG_FS_MspDeInit 1 */ } } ``` 三、配置board.h ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20240807/adb5e66bf566ea405039c348ab207c58.png) ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20240807/bd8f20341b37380b07c4ed20256608cf.png) 增加这几个端点宏 ```c #define EP_MPS_64 0U #define EP_MPS_32 1U #define EP_MPS_16 2U #define EP_MPS_8 3U ``` 否则会编译报错 ## 四、挂载SD卡 ```c void mnt_init(void) { rt_thread_mdelay(500);//Wait for the SD card to stabilize if(dfs_mount("sd0","/","elm",0,0)==0) { rt_kprintf("dfs mount success\r\n"); } else { rt_kprintf("dfs mount failed\r\n"); dfs_mkfs("elm","sd0"); if(dfs_mount("sd0","/","elm",0,0)!=0) { rt_kprintf("dfs mount failed again\r\n"); RT_ASSERT(RT_NULL); } } } ``` 放到主函数或自动初始化 注意:到这一步是可以直接在串口终端下ls查看到文件目录的 ## 五、SD卡挂载到USB总线上 # 注意:SD卡不能同时挂载到文件系统和USB总线上,因此当插入USB时,应该先umount文件系统,然后等待USB MSC自动挂载到SD卡上 在这个文件中插入一段代码,让USB插入时,先卸载文件系统,然后进行USB的枚举 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20240807/6df04c210c287c9c7aaaa0be86e539ca.png.webp) ```c static int sdcard_umount(const char *path) { int dfs_unmount(const char *specialfile); rt_kprintf("unmount %s ... ", path); if (dfs_unmount(path) < 0) { rt_kprintf("failed!\n"); if (dfs_unmount(path) < 0) { rt_kprintf("failed again!\n"); return -1; } rt_kprintf("final succeed!\n"); return 0; } else { rt_kprintf("succeed!\n"); return 0; } } ``` 在下面的函数中调用这句话 ```c static void rt_usbd_thread_entry(void* parameter) { while(1) { struct udev_msg msg; udevice_t device; /* receive message */ if(rt_mq_recv(&usb_mq, &msg, sizeof(struct udev_msg), RT_WAITING_FOREVER) != RT_EOK ) continue; device = rt_usbd_find_device(msg.dcd); if(device == RT_NULL) { rt_kprintf("invalid usb device\n"); continue; } RT_DEBUG_LOG(RT_DEBUG_USB, ("message type %d\n", msg.type)); switch (msg.type) { case USB_MSG_SOF: _sof_notify(device); break; case USB_MSG_DATA_NOTIFY: /* some buggy drivers will have USB_MSG_DATA_NOTIFY before the core * got configured. */ _data_notify(device, &msg.content.ep_msg); break; case USB_MSG_SETUP_NOTIFY: _setup_request(device, &msg.content.setup); break; case USB_MSG_EP0_OUT: _ep0_out_notify(device, &msg.content.ep_msg); break; case USB_MSG_RESET: sdcard_umount("/"); RT_DEBUG_LOG(RT_DEBUG_USB, ("reset %d\n", device->state)); if (device->state == USB_STATE_ADDRESS || device->state == USB_STATE_CONFIGURED) _stop_notify(device); device->state = USB_STATE_NOTATTACHED; break; case USB_MSG_PLUG_IN: device->state = USB_STATE_ATTACHED; break; case USB_MSG_PLUG_OUT: device->state = USB_STATE_NOTATTACHED; _stop_notify(device); break; default: rt_kprintf("unknown msg type %d\n", msg.type); break; } } } ``` ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20240807/1c8baf9ed8ac851d41dc13a604dd9918.png) ## 至此大功告成了
0
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
NHMF_4386
这家伙很懒,什么也没写!
文章
3
回答
4
被采纳
1
关注TA
发私信
相关文章
1
请教USB Host
2
STM32F4调试USB 读卡器(Slave)提示格式化
3
急求 STM32F4 USB Device MSC+SD 的相关问题
4
USB 框架问题
5
USB键盘
6
LPC17xx 如何添加USB HOST设备
7
RT-Thread目前支持USB HOST了吗?
8
USB HOST的支持问题
9
RTT 2.0.1 USB存储设备问题,枚举到USBREQ_GET_MAX_LUN后复位
10
USB库已经很久没更新了
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
I2C_IIC
ESP8266
UART
WIZnet_W5500
ota在线升级
cubemx
PWM
flash
freemodbus
BSP
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
编译报错
中断
Debug
rt_mq_消息队列_msg_queue
SFUD
msh
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
出出啊
1518
个答案
343
次被采纳
小小李sunny
1444
个答案
290
次被采纳
张世争
813
个答案
177
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
149
次被采纳
本月文章贡献
出出啊
1
篇文章
1
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
3
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
2
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部