USB HOST MSC using STM32
In this article we will implement usb host mass storage class using stm32 microcontroller.The advantage is that without using a computer we can write or read data to & from a file present in a usb flash drive. Here we have implemented the write operation.
The respective c files are given below.
1. main.c content :-
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2024 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "fatfs.h"
#include "usb_host.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart6;
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART6_UART_Init(void);
void MX_USB_HOST_Process(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
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_USART6_UART_Init();
MX_FATFS_Init();
MX_USB_HOST_Init();
/* USER CODE BEGIN 2 */
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
MX_USB_HOST_Process();
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 4;
RCC_OscInitStruct.PLL.PLLN = 168;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
RCC_OscInitStruct.PLL.PLLQ = 7;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief USART6 Initialization Function
* @param None
* @retval None
*/
static void MX_USART6_UART_Init(void)
{
/* USER CODE BEGIN USART6_Init 0 */
/* USER CODE END USART6_Init 0 */
/* USER CODE BEGIN USART6_Init 1 */
/* USER CODE END USART6_Init 1 */
huart6.Instance = USART6;
huart6.Init.BaudRate = 9600;
huart6.Init.WordLength = UART_WORDLENGTH_8B;
huart6.Init.StopBits = UART_STOPBITS_1;
huart6.Init.Parity = UART_PARITY_NONE;
huart6.Init.Mode = UART_MODE_TX;
huart6.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart6.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart6) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART6_Init 2 */
/* USER CODE END USART6_Init 2 */
}
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET);
/*Configure GPIO pin : PC0 */
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
2. usb_host.c content :-
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : usb_host.c
* @version : v1.0_Cube
* @brief : This file implements the USB Host
******************************************************************************
* @attention
*
* Copyright (c) 2024 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "usb_host.h"
#include "usbh_core.h"
#include "usbh_msc.h"
/* USER CODE BEGIN Includes */
#include "File_Handling.h"
/* USER CODE END Includes */
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
/* USER CODE END PV */
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE END PFP */
/* USB Host core handle declaration */
USBH_HandleTypeDef hUsbHostFS;
ApplicationTypeDef Appli_state = APPLICATION_IDLE;
/*
* -- Insert your variables declaration here --
*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/*
* user callback declaration
*/
static void USBH_UserProcess(USBH_HandleTypeDef *phost, uint8_t id);
/*
* -- Insert your external function declaration here --
*/
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/**
* Init USB host library, add supported class and start the library
* @retval None
*/
void MX_USB_HOST_Init(void)
{
/* USER CODE BEGIN USB_HOST_Init_PreTreatment */
/* USER CODE END USB_HOST_Init_PreTreatment */
/* Init host Library, add supported class and start the library. */
if (USBH_Init(&hUsbHostFS, USBH_UserProcess, HOST_FS) != USBH_OK)
{
Error_Handler();
}
if (USBH_RegisterClass(&hUsbHostFS, USBH_MSC_CLASS) != USBH_OK)
{
Error_Handler();
}
if (USBH_Start(&hUsbHostFS) != USBH_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USB_HOST_Init_PostTreatment */
/* USER CODE END USB_HOST_Init_PostTreatment */
}
/*
* Background task
*/
void MX_USB_HOST_Process(void)
{
/* USB Host Background task */
USBH_Process(&hUsbHostFS);
}
/*
* user callback definition
*/
static void USBH_UserProcess (USBH_HandleTypeDef *phost, uint8_t id)
{
/* USER CODE BEGIN CALL_BACK_1 */
switch(id)
{
case HOST_USER_SELECT_CONFIGURATION:
break;
case HOST_USER_DISCONNECTION:
Appli_state = APPLICATION_DISCONNECT;
Unmount_USB();
break;
case HOST_USER_CLASS_ACTIVE:
Appli_state = APPLICATION_READY;
Mount_USB();
Check_USB_Details ();//check space details
Scan_USB ("/");//scan for files & directories
Create_File ("ROOTFILE.txt");
Write_File ("ROOTFILE.txt","Kuna is a firmware engineer\n");
break;
case HOST_USER_CONNECTION:
Appli_state = APPLICATION_START;
break;
default:
break;
}
/* USER CODE END CALL_BACK_1 */
}
/**
* @}
*/
/**
* @}
*/
3. File_Handling.c content :-
/*
* File_Handling_RTOS.c
*
* Created on: 26-June-2020
* Author: Controllerstech.com
*/
#include "File_Handling.h"
#include "stm32f4xx_hal.h"
extern UART_HandleTypeDef huart6;
#define UART &huart6
/* =============================>>>>>>>> NO CHANGES AFTER THIS LINE =====================================>>>>>>> */
extern char USBHPath[4]; /* USBH logical drive path */
extern FATFS USBHFatFS; /* File system object for USBH logical drive */
extern FIL USBHFile; /* File object for USBH */
FILINFO USBHfno;
FRESULT fresult; // result
UINT br, bw; // File read/write count
/**** capacity related *****/
FATFS *pUSBHFatFS;
DWORD fre_clust;
uint32_t total, free_space;
void Send_Uart (char *string)
{
HAL_UART_Transmit(UART, (uint8_t *)string, strlen (string), HAL_MAX_DELAY);
}
void Mount_USB (void)
{
fresult = f_mount(&USBHFatFS, USBHPath, 1);
if (fresult != FR_OK) Send_Uart ("ERROR!!! in mounting USB ...\n\n");
else Send_Uart("USB mounted successfully...\n");
}
void Unmount_USB (void)
{
fresult = f_mount(NULL, USBHPath, 1);
if (fresult == FR_OK) Send_Uart ("USB UNMOUNTED successfully...\n\n\n");
else Send_Uart("ERROR!!! in UNMOUNTING USB \n\n\n");
}
/* Start node to be scanned (***also used as work area***) */
FRESULT Scan_USB (char* pat)
{
DIR dir;
UINT i;
领英推荐
char path = malloc(20sizeof (char));
sprintf (path, "%s",pat);
fresult = f_opendir(&dir, path); /* Open the directory */
if (fresult == FR_OK)
{
for (;;)
{
fresult = f_readdir(&dir, &USBHfno); /* Read a directory item */
if (fresult != FR_OK || USBHfno.fname[0] == 0) break; /* Break on error or end of dir */
if (USBHfno.fattrib & AM_DIR) /* It is a directory */
{
if (!(strcmp ("SYSTEM~1", USBHfno.fname))) continue;
if (!(strcmp("System Volume Information", USBHfno.fname))) continue;
char buf = malloc(30sizeof(char));
sprintf (buf, "Dir: %s\r\n", USBHfno.fname);
Send_Uart(buf);
free(buf);
i = strlen(path);
sprintf(&path[i], "/%s", USBHfno.fname);
fresult = Scan_USB(path); /* Enter the directory */
if (fresult != FR_OK) break;
path[i] = 0;
}
else
{ /* It is a file. */
char buf = malloc(30sizeof(char));
sprintf(buf,"File: %s/%s\n", path, USBHfno.fname);
Send_Uart(buf);
free(buf);
}
}
f_closedir(&dir);
}
free(path);
return fresult;
}
/* Only supports removing files from home directory */
FRESULT Format_USB (void)
{
DIR dir;
char path = malloc(20sizeof (char));
sprintf (path, "%s","/");
fresult = f_opendir(&dir, path); /* Open the directory */
if (fresult == FR_OK)
{
for (;;)
{
fresult = f_readdir(&dir, &USBHfno); /* Read a directory item */
if (fresult != FR_OK || USBHfno.fname[0] == 0) break; /* Break on error or end of dir */
if (USBHfno.fattrib & AM_DIR) /* It is a directory */
{
if (!(strcmp ("SYSTEM~1", USBHfno.fname))) continue;
if (!(strcmp("System Volume Information", USBHfno.fname))) continue;
fresult = f_unlink(USBHfno.fname);
if (fresult == FR_DENIED) continue;
}
else
{ /* It is a file. */
fresult = f_unlink(USBHfno.fname);
}
}
f_closedir(&dir);
}
free(path);
return fresult;
}
FRESULT Write_File (char name, char data)
{
/**** check whether the file exists or not ****/
fresult = f_stat (name, &USBHfno);
if (fresult != FR_OK)
{
char buf = malloc(100sizeof(char));
sprintf (buf, "ERROR!!! %s does not exists\n\n", name);
Send_Uart (buf);
free(buf);
return fresult;
}
else
{
/* Create a file with read write access and open it */
fresult = f_open(&USBHFile, name, FA_OPEN_EXISTING | FA_WRITE);
if (fresult != FR_OK)
{
char buf = malloc(100sizeof(char));
sprintf (buf, "ERROR!!! No. %d in opening file %s\n\n", fresult, name);
Send_Uart(buf);
free(buf);
return fresult;
}
else
{
char buf = malloc(100sizeof(char));
sprintf (buf, "Opening file--> %s To WRITE data in it\n", name);
Send_Uart(buf);
free(buf);
fresult = f_write(&USBHFile, data, strlen(data), &bw);
if (fresult != FR_OK)
{
char buf = malloc(100sizeof(char));
sprintf (buf, "ERROR!!! No. %d while writing to the FILE %s\n\n", fresult, name);
Send_Uart(buf);
free(buf);
}
/* Close file */
fresult = f_close(&USBHFile);
if (fresult != FR_OK)
{
char buf = malloc(100sizeof(char));
sprintf (buf, "ERROR!!! No. %d in closing file %s after writing it\n\n", fresult, name);
Send_Uart(buf);
free(buf);
}
else
{
char buf = malloc(100sizeof(char));
sprintf (buf, "File %s is WRITTEN and CLOSED successfully\n\n", name);
Send_Uart(buf);
free(buf);
}
}
return fresult;
}
}
FRESULT Read_File (char *name)
{
/**** check whether the file exists or not ****/
fresult = f_stat (name, &USBHfno);
if (fresult != FR_OK)
{
char buf = malloc(100sizeof(char));
sprintf (buf, "ERRROR!!! %s does not exists\n\n", name);
Send_Uart (buf);
free(buf);
return fresult;
}
else
{
/* Open file to read */
fresult = f_open(&USBHFile, name, FA_READ);
if (fresult != FR_OK)
{
char buf = malloc(100sizeof(char));
sprintf (buf, "ERROR!!! No. %d in opening file %s\n\n", fresult, name);
Send_Uart(buf);
free(buf);
return fresult;
}
/* Read data from the file
see the function details for the arguments /
char buf = malloc(100sizeof(char));
sprintf (buf, "Opening file--> %s To READ data from it\n", name);
Send_Uart(buf);
free(buf);
char *buffer = malloc(sizeof(f_size(&USBHFile)));
fresult = f_read (&USBHFile, buffer, f_size(&USBHFile), &br);
if (fresult != FR_OK)
{
char buf = malloc(100sizeof(char));
free(buffer);
sprintf (buf, "ERROR!!! No. %d in reading file %s\n\n", fresult, name);
Send_Uart(buffer);
free(buf);
}
else
{
Send_Uart(buffer);
free(buffer);
/* Close file */
fresult = f_close(&USBHFile);
if (fresult != FR_OK)
{
char buf = malloc(100sizeof(char));
sprintf (buf, "ERROR!!! No. %d in closing file %s\n\n", fresult, name);
Send_Uart(buf);
free(buf);
}
else
{
char buf = malloc(100sizeof(char));
sprintf (buf, "File %s CLOSED successfully\n\n", name);
Send_Uart(buf);
free(buf);
}
}
return fresult;
}
}
FRESULT Create_File (char *name)
{
fresult = f_stat (name, &USBHfno);
if (fresult == FR_OK)
{
char buf = malloc(100sizeof(char));
sprintf (buf, "ERROR!!! %s already exists!!!!\n use Update_File \n\n",name);
Send_Uart(buf);
free(buf);
return fresult;
}
else
{
fresult = f_open(&USBHFile, name, FA_CREATE_ALWAYS|FA_READ|FA_WRITE);
if (fresult != FR_OK)
{
char buf = malloc(100sizeof(char));
sprintf (buf, "ERROR!!! No. %d in creating file %s\n\n", fresult, name);
Send_Uart(buf);
free(buf);
return fresult;
}
else
{
char buf = malloc(100sizeof(char));
sprintf (buf, "*%s* created successfully\n Now use Write_File to write data\n",name);
Send_Uart(buf);
free(buf);
}
fresult = f_close(&USBHFile);
if (fresult != FR_OK)
{
char buf = malloc(100sizeof(char));
sprintf (buf, "ERROR No. %d in closing file %s\n\n", fresult, name);
Send_Uart(buf);
free(buf);
}
else
{
char buf = malloc(100sizeof(char));
sprintf (buf, "File %s CLOSED successfully\n\n", name);
Send_Uart(buf);
free(buf);
}
}
return fresult;
}
FRESULT Update_File (char name, char data)
{
/**** check whether the file exists or not ****/
fresult = f_stat (name, &USBHfno);
if (fresult != FR_OK)
{
char buf = malloc(100sizeof(char));
sprintf (buf, "ERROR!!! %s does not exists\n\n", name);
Send_Uart (buf);
free(buf);
return fresult;
}
else
{
/* Create a file with read write access and open it */
fresult = f_open(&USBHFile, name, FA_OPEN_APPEND | FA_WRITE);
if (fresult != FR_OK)
{
char buf = malloc(100sizeof(char));
sprintf (buf, "ERROR!!! No. %d in opening file %s\n\n", fresult, name);
Send_Uart(buf);
free(buf);
return fresult;
}
char buf = malloc(100sizeof(char));
sprintf (buf, "Opening file--> %s To UPDATE data in it\n", name);
Send_Uart(buf);
free(buf);
/* Writing text */
fresult = f_write(&USBHFile, data, strlen (data), &bw);
if (fresult != FR_OK)
{
char buf = malloc(100sizeof(char));
sprintf (buf, "ERROR!!! No. %d in writing file %s\n\n", fresult, name);
Send_Uart(buf);
free(buf);
}
else
{
char buf = malloc(100sizeof(char));
sprintf (buf, "*%s* UPDATED successfully\n", name);
Send_Uart(buf);
free(buf);
}
/* Close file */
fresult = f_close(&USBHFile);
if (fresult != FR_OK)
{
char buf = malloc(100sizeof(char));
sprintf (buf, "ERROR!!! No. %d in closing file %s\n\n", fresult, name);
Send_Uart(buf);
free(buf);
}
else
{
char buf = malloc(100sizeof(char));
sprintf (buf, "File %s CLOSED successfully\n\n", name);
Send_Uart(buf);
free(buf);
}
}
return fresult;
}
FRESULT Remove_File (char *name)
{
/**** check whether the file exists or not ****/
fresult = f_stat (name, &USBHfno);
if (fresult != FR_OK)
{
char buf = malloc(100sizeof(char));
sprintf (buf, "ERROR!!! %s does not exists\n\n", name);
Send_Uart (buf);
free(buf);
return fresult;
}
else
{
fresult = f_unlink (name);
if (fresult == FR_OK)
{
char buf = malloc(100sizeof(char));
sprintf (buf, "*%s* has been removed successfully\n\n", name);
Send_Uart (buf);
free(buf);
}
else
{
char buf = malloc(100sizeof(char));
sprintf (buf, "ERROR No. %d in removing %s\n\n",fresult, name);
Send_Uart (buf);
free(buf);
}
}
return fresult;
}
FRESULT Create_Dir (char *name)
{
fresult = f_mkdir(name);
if (fresult == FR_OK)
{
char buf = malloc(100sizeof(char));
sprintf (buf, "*%s* has been created successfully\n\n", name);
Send_Uart (buf);
free(buf);
}
else
{
char buf = malloc(100sizeof(char));
sprintf (buf, "ERROR No. %d in creating directory %s\n\n", fresult,name);
Send_Uart(buf);
free(buf);
}
return fresult;
}
void Check_USB_Details (void)
{
/* Check free space */
f_getfree("", &fre_clust, &pUSBHFatFS);
total = (uint32_t)((pUSBHFatFS->n_fatent - 2) pUSBHFatFS->csize 0.5);
char buf = malloc(30sizeof(char));
sprintf (buf, "USB Total Size: \t%lu\n",total);
Send_Uart(buf);
free(buf);
free_space = (uint32_t)(fre_clust pUSBHFatFS->csize 0.5);
buf = malloc(30*sizeof(char));
sprintf (buf, "USB Free Space: \t%lu\n",free_space);
Send_Uart(buf);
free(buf);
}
4. File_Handling.h content :-
/*
* File_Handling_RTOS.h
*
* Created on: 30-April-2020
* Author: Controllerstech
*/
#ifndef FILE_HANDLING_H_
#define FILE_HANDLING_H_
#include "fatfs.h"
#include "string.h"
#include "stdio.h"
/* mounts the USB*/
void Mount_USB (void);
/* unmounts the USB*/
void Unmount_USB (void);
/* Start node to be scanned (***also used as work area***) */
FRESULT Scan_USB (char* pat);
/* Only supports removing files from home directory. Directory remover to be added soon */
FRESULT Format_USB (void);
/* write the data to the file
@ name : is the path to the file/
FRESULT Write_File (char name, char data);
/* read data from the file
@ name : is the path to the file/
FRESULT Read_File (char *name);
/* creates the file, if it does not exists
@ name : is the path to the file/
FRESULT Create_File (char *name);
/* Removes the file from the USB
@ name : is the path to the file/
FRESULT Remove_File (char *name);
/* creates a directory
* @ name: is the path to the directory
*/
FRESULT Create_Dir (char *name);
/* checks the free space in the USB*/
void Check_USB_Details (void);
/* updates the file. write pointer is set to the end of the file
* @ name : is the path to the file
*/
FRESULT Update_File (char name, char data);
#endif /* FILE_HANDLING_RTOS_H_ */
Challenge :- forget to configure the VBUS line.
Software Development Environment :- STM32CubeIDE 1.15.0
Evaluation Kit :- STM32F401VC Discovery Kit
Programming Language :- Embedded C
Bluetooth Speaker Researcher
9 个月Please comment if you want to suggest something.