目录
Cubemx部分
一.SDIO外设的配置
1.SDIO外设的开启
2. 启用SDIO的中断
3.使用SDIO的DMA(方便FATFS 文件系统时调用)
二.USB外设设置
1.USB外设的开启
2.USB中断开启
三.Fatfs文件系统的配置
1.选择SD卡外设
USE_LFN:我这里选择的是动态工作在栈区,所以在cubemx分配堆栈的时候要给大点。
2.使能DMA方式
3.检查SD卡是否插入
我这边配置的是PD13,你们根据直接的电路图来配置。
四.USB_Device的设置
其他的就选默认的就行
Keil软件修改部分
到此我们的Cubemx的设置就完成了,下面我们开始软件的修改:
sdio.c目录下修改为
/* USER CODE END SDIO_Init 1 */
hsd.Instance = SDIO;
hsd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
hsd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
hsd.Init.BusWide = SDIO_BUS_WIDE_1B;
hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
hsd.Init.ClockDiv = 2;
/* USER CODE BEGIN SDIO_Init 2 */
把cubemx生成的SDIO_BUS_WIDE_4B修改为SDIO_BUS_WIDE_1B.就可以正常的访问SD卡了。
如果你们在使用Fatfs时初始化不通过你看看你们的Application/User/FATFS/Target文件目录下的fatfs_platform.c有没有加入你们的SD卡检测函数
uint8_t BSP_PlatformIsDetected(void) {
uint8_t status = SD_PRESENT;
/* Check SD card detect pin */
if(HAL_GPIO_ReadPin(SD_DETECT_GPIO_PORT, SD_DETECT_PIN) != GPIO_PIN_RESET)
{
status = SD_NOT_PRESENT;
}
/* USER CODE BEGIN 1 */
/* user code can be inserted here */
/* USER CODE END 1 */
return status;
}
解决完以上问题就可以测试SD卡是不是可以使用fatfs文件系统了Demo:
rt_kprintf("\r\n ****** FatFs Example ******\r\n\r\n");
/*##-1- Register the file system object to the FatFs module ##############*/
retSD = f_mount(&SDFatFS,SDPath, 1);
//f_mkdir("0:dxc");
if(retSD)
{
rt_kprintf(" mount error : %d \r\n",retSD);
Error_Handler();
}
else
rt_kprintf(" mount sucess!!! \r\n");
/*##-2- Create and Open new text file objects with write access ######*/
retSD=exf_getfree("0:",&total,&mfree);
if(retSD==0)
rt_kprintf(" total : %d MB,free : %d MB \r\n",total>>10,mfree>>10);
else
rt_kprintf(" getfree error!!! \r\n");
f_mkdir("0:20230331");
retSD = f_open(&SDFile, filename, FA_CREATE_ALWAYS | FA_WRITE);
if(retSD)
rt_kprintf(" open file error : %d\r\n",retSD);
else
rt_kprintf(" open file sucess!!! \r\n");
/*##-3- Write data to the text files ###############################*/
retSD = f_write(&SDFile, wtext, sizeof(wtext), (void *)&byteswritten);
if(retSD)
rt_kprintf(" write file error : %d\r\n",retSD);
else
{
rt_kprintf(" write file sucess!!! \r\n");
rt_kprintf(" write Data : %s\r\n",wtext);
}
/*##-4- Close the open text files ################################*/
retSD = f_close(&SDFile);
if(retSD)
rt_kprintf(" close error : %d\r\n",retSD);
else
rt_kprintf(" close sucess!!! \r\n");
/*##-5- Open the text files object with read access ##############*/
retSD = f_open(&SDFile, filename, FA_READ);
if(retSD)
rt_kprintf(" open file error : %d\r\n",retSD);
else
rt_kprintf(" open file sucess!!! \r\n");
/*##-6- Read data from the text files ##########################*/
retSD = f_read(&SDFile, rtext, sizeof(rtext), (UINT*)&bytesread);
if(retSD)
rt_kprintf(" read error!!! %d\r\n",retSD);
else
{
rt_kprintf(" read sucess!!! \r\n");
rt_kprintf(" read Data : %s\r\n",rtext);
}
/*##-7- Close the open text files ############################*/
retSD = f_close(&SDFile);
if(retSD)
rt_kprintf(" close error!!! %d\r\n",retSD);
else
rt_kprintf(" close sucess!!! \r\n");
/*##-8- Compare read data with the expected data ############*/
if(bytesread == byteswritten)
{
rt_kprintf(" FatFs is working well!!!\r\n");
}
如果SD卡能够正常使用fatfs文件系统读写的话,下面就开始设置USB来把SD卡当作U盘来识别了
主要把usbd_storage_if.c文件来修改一下就行,直接替换成我的也可以
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : usbd_storage_if.c
* @version : v1.0_Cube
* @brief : Memory management layer.
******************************************************************************
* @attention
*
* <h2><center>© Copyright (c) 2022 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 "sdio.h"
#include "sd_diskio.h"
/* USER CODE END INCLUDE */
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
/* 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 */
/* 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 */
SD_Driver.disk_initialize(1); // 增加
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 */
//*block_num = STORAGE_BLK_NBR;
//*block_size = STORAGE_BLK_SIZ;
*block_num = hsd.SdCard.BlockNbr ;
*block_size = hsd.SdCard.BlockSize ;
return (USBD_OK);
/* 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 */
return (SD_Driver.disk_status(lun));
/* 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 */
return (SD_Driver.disk_read(lun, buf, blk_addr, blk_len));
/* 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 */
return (SD_Driver.disk_write(lun, buf, blk_addr, blk_len));
/* 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 */
/* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
如有问题欢迎一起探讨,一起解决