一、介绍
本次采用STM32CubeIDE 平台 STM32L476RE 芯片 自带 usb接口和 Mirco卡槽,实现通过USB连接电脑能正确对SD卡中的文件进行读写操作,同时芯片内部程序也可以以FATFS方式对SD卡操作。
二、步骤
1、RCC SYS 配置比较简单,大家都知道
2、USB_OTG_FS配置
以从机的方式配置,Mode :Device_Only
Activate VBUS: VBUS sensing 这里我们检测vbus状态,避免 PC和芯片同时对一个文件访问产生冲突
其他默认
3、USB_DEVICE 配置
Mode:选择Mass Storage Class 即MSC 大容量存储设备类
4、FATFS 配置
使用SD Card 其他默认就好
5、 SDMMC 配置
总线4位宽 使能硬件流控制 时钟分频设置
开启DMA 中断
开启DMA
配置GPIO
6堆栈设置
7 main函数增加 fatfs 测试函数 测试正常读写文件功能
对于想具体了解 USB相关的库函数大家可以参考最后相关链接,我把有关USB所有文档打包上传了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | static void FS_FileOperations_LIUYAN(void) { FRESULT res; /* FatFs function common result code */ uint32_t byteswritten, bytesread; /* File write/read counts */ uint8_t wtext[] = "stm32l476g_eval : This is STM32 working with FatFs and uSD diskio driver"; /* File write buffer */ uint8_t rtext[100]; /* File read buffer */ /* Register the file system object to the FatFs module */ if(f_mount(&SDFatFs, (TCHAR const*)SDPath, 0) == FR_OK) { /* Create and Open a new text file object with write access */ if(f_open(&MyFile, "liuyan.TXT", FA_CREATE_ALWAYS | FA_WRITE) == FR_OK) { /* Write data to the text file */ res = f_write(&MyFile, wtext, sizeof(wtext), (void *)&byteswritten); if((byteswritten > 0) && (res == FR_OK)) { /* Close the open text file */ f_close(&MyFile); /* Open the text file object with read access */ //f_mount(NULL, (TCHAR const*)SDPath, 0); } } } /* Error */ Error_Handler(); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_DMA_Init(); MX_USB_DEVICE_Init(); MX_SDMMC1_SD_Init(); MX_FATFS_Init(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_9) == 0) { FS_FileOperations_LIUYAN(); } } /* USER CODE END 3 */ } |
8 修改USB 接口函数 就是 usbd_storage_if.c 文件
大家有想了解usb相关的文档,我已打包发布出来,有需要的可以下载
usbd_storage_if.c 代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 | /* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : usbd_storage_if.c * @version : v2.0_Cube * @brief : Memory management layer. ****************************************************************************** * @attention * * <h2><center>© Copyright (c) 2020 STMicroelectronics. * All rights reserved.</center></h2> * * This software component is licensed by ST under Ultimate Liberty license * SLA0044, the "License"; You may not use this file except in compliance with * the License. You may obtain a copy of the License at: * www.st.com/SLA0044 * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "usbd_storage_if.h" /* USER CODE BEGIN INCLUDE */ #include "bsp_driver_sd.h" /* USER CODE END INCLUDE */ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* Private variables ---------------------------------------------------------*/ __IO uint32_t writestatus, readstatus = 0; /* USER CODE END PV */ /** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY * @brief Usb device. * @{ */ /** @defgroup USBD_STORAGE * @brief Usb mass storage device module * @{ */ /** @defgroup USBD_STORAGE_Private_TypesDefinitions * @brief Private types. * @{ */ /* USER CODE BEGIN PRIVATE_TYPES */ /* USER CODE END PRIVATE_TYPES */ /** * @} */ /** @defgroup USBD_STORAGE_Private_Defines * @brief Private defines. * @{ */ #define STORAGE_LUN_NBR 1 #define STORAGE_BLK_NBR 0x10000 #define STORAGE_BLK_SIZ 0x200 /* USER CODE BEGIN PRIVATE_DEFINES */ /* USER CODE END PRIVATE_DEFINES */ /** * @} */ /** @defgroup USBD_STORAGE_Private_Macros * @brief Private macros. * @{ */ /* USER CODE BEGIN PRIVATE_MACRO */ /* USER CODE END PRIVATE_MACRO */ /** * @} */ /** @defgroup USBD_STORAGE_Private_Variables * @brief Private variables. * @{ */ /* USER CODE BEGIN INQUIRY_DATA_FS */ /** USB Mass storage Standard Inquiry Data. */ const int8_t STORAGE_Inquirydata_FS[] = {/* 36 */ /* LUN 0 */ 0x00, 0x80, 0x02, 0x02, (STANDARD_INQUIRY_DATA_LEN - 5), 0x00, 0x00, 0x00, 'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', /* Manufacturer : 8 bytes */ 'P', 'r', 'o', 'd', 'u', 'c', 't', ' ', /* Product : 16 Bytes */ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '0', '.', '0' ,'1' /* Version : 4 Bytes */ }; /* USER CODE END INQUIRY_DATA_FS */ /* USER CODE BEGIN PRIVATE_VARIABLES */ /* USER CODE END PRIVATE_VARIABLES */ /** * @} */ /** @defgroup USBD_STORAGE_Exported_Variables * @brief Public variables. * @{ */ extern USBD_HandleTypeDef hUsbDeviceFS; /* USER CODE BEGIN EXPORTED_VARIABLES */ extern SD_HandleTypeDef hsd1; /* USER CODE END EXPORTED_VARIABLES */ /** * @} */ /** @defgroup USBD_STORAGE_Private_FunctionPrototypes * @brief Private functions declaration. * @{ */ static int8_t STORAGE_Init_FS(uint8_t lun); static int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num, uint16_t *block_size); static int8_t STORAGE_IsReady_FS(uint8_t lun); static int8_t STORAGE_IsWriteProtected_FS(uint8_t lun); static int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len); static int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len); static int8_t STORAGE_GetMaxLun_FS(void); /* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION */ /* USER CODE END PRIVATE_FUNCTIONS_DECLARATION */ /** * @} */ USBD_StorageTypeDef USBD_Storage_Interface_fops_FS = { STORAGE_Init_FS, STORAGE_GetCapacity_FS, STORAGE_IsReady_FS, STORAGE_IsWriteProtected_FS, STORAGE_Read_FS, STORAGE_Write_FS, STORAGE_GetMaxLun_FS, (int8_t *)STORAGE_Inquirydata_FS }; /* Private functions ---------------------------------------------------------*/ /** * @brief Initializes over USB FS IP * @param lun: * @retval USBD_OK if all operations are OK else USBD_FAIL */ int8_t STORAGE_Init_FS(uint8_t lun) { /* USER CODE BEGIN 2 */ BSP_SD_Init(); return (USBD_OK); /* USER CODE END 2 */ } /** * @brief . * @param lun: . * @param block_num: . * @param block_size: . * @retval USBD_OK if all operations are OK else USBD_FAIL */ 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 */ } /** * @brief . * @param lun: . * @retval USBD_OK if all operations are OK else USBD_FAIL */ 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 */ } /** * @brief . * @param lun: . * @retval USBD_OK if all operations are OK else USBD_FAIL */ int8_t STORAGE_IsWriteProtected_FS(uint8_t lun) { /* USER CODE BEGIN 5 */ return (USBD_OK); /* USER CODE END 5 */ } /** * @brief . * @param lun: . * @retval USBD_OK if all operations are OK else USBD_FAIL */ 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; uint32_t timeout = 100000; BSP_SD_ReadBlocks((uint32_t *)buf, blk_addr, blk_len, SD_DATATIMEOUT); while(BSP_SD_GetCardState() != SD_TRANSFER_OK) { if (timeout-- == 0) { return ret; } } ret = 0; return ret; /* 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 */ int8_t ret = -1; uint32_t timeout = 100000; BSP_SD_WriteBlocks((uint32_t *)buf, blk_addr, blk_len, SD_DATATIMEOUT); while(BSP_SD_GetCardState() != SD_TRANSFER_OK) { if (timeout-- == 0) { return ret; } } ret = 0; return ret; /* USER CODE END 7 */ } /** * @brief . * @param None * @retval . */ int8_t STORAGE_GetMaxLun_FS(void) { /* USER CODE BEGIN 8 */ return (STORAGE_LUN_NBR - 1); /* USER CODE END 8 */ } /* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */ //void BSP_SD_WriteCpltCallback(void) //{ // writestatus = 1; //} // //void BSP_SD_ReadCpltCallback(void) //{ // readstatus = 1; //} /* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */ /** * @} */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
9 程序通过检测Vbus 电平状态来确认是否插入PC 机,正常在插入PC 时,程序不允许对SD卡操作
三、结果
最后文章参考博主 http://www.freesion.com/article/489386717/
本例程所有代码链接: https://download.csdn.net/download/weixin_39949884/12256206
USB 所有资源打包地址: https://download.csdn.net/download/weixin_39949884/12274629