一、硬件软件说明
软件:STM32CubeMX V6.6.1 、 KEIL5 V5.29
硬件:STM32F429ZET6
USB_OTG_FS:PA11/PA12引脚
USART1:PA9/PA10,方便输出调试信息
二、STM32CubeMX配置
1)SYS下载方式选择SW方式,因为要使用FREERTOS,提前将时钟源修改为TIM7(其他定时器也可以)
2) RCC设置,选择高速外部晶振HSE(根据具体硬件选择)
3)USART1设置,方便输出调试信息,参数默认即可,可以使用其他串口
4)USB_OTG_FS配置,Mode选择Host_Only,参数默认
5)FREERTOS配置,将默认任务的堆栈该为1024,其他参数默认
6)USB_HOST配置,Class for FS IP选择Mass Storage Host Class,需要注意将最后一项参数USB_PEOCESS_STACK_SIZE由默认的128改为512。需要注意的是USB任务堆栈别太小,否则读写U盘时容易卡死。
7)FATFS配置,如下图。将CODE_PAGE改为Simplified Chinese,支持中文读写;USE_LFN修改为Enable with dynamic working buffer on the STACK,支持长文件名。其他参数保持默认。MAX_SS默认为512,改为4096测试也正常。
8)时钟树配置,板子使用的外部晶振为8MHz,STM32F429ZET6最大时钟为180MHz,这里配置为168MHz,输入168,回车即可,系统会自动配置好时钟。
9)工程配置,将堆栈大小改大点,如图。
所有配置完成,点击GENERATE CODE,生成代码。
三、代码介绍
添加测试代码
串口重映射,支持printf函数,usart.c修改如下:
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file usart.c
* @brief This file provides code for the configuration
* of the USART instances.
******************************************************************************
* @attention
*
* Copyright (c) 2023 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 "usart.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
UART_HandleTypeDef huart1;
/* USART1 init function */
void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART1_Init 2 */
/* USER CODE END USART1_Init 2 */
}
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspInit 0 */
/* USER CODE END USART1_MspInit 0 */
/* USART1 clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART1 GPIO Configuration
PA9 ------> USART1_TX
PA10 ------> USART1_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART1 interrupt Init */
HAL_NVIC_SetPriority(USART1_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspInit 1 */
/* USER CODE END USART1_MspInit 1 */
}
}
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{
if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspDeInit 0 */
/* USER CODE END USART1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART1_CLK_DISABLE();
/**USART1 GPIO Configuration
PA9 ------> USART1_TX
PA10 ------> USART1_RX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
/* USART1 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspDeInit 1 */
/* USER CODE END USART1_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
#include "stdio.h"
//加入以下代码,支持printf函数
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (int) ch;
return ch;
}
/* USER CODE END 1 */
freertos.c修改如下:
/* USER CODE BEGIN Header */
/**
******************************************************************************
* File Name : freertos.c
* Description : Code for freertos applications
******************************************************************************
* @attention
*
* Copyright (c) 2023 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 "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "fatfs.h"
/* 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 ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */
/* USER CODE END Variables */
/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {
.name = "defaultTask",
.stack_size = 1024 * 4,
.priority = (osPriority_t) osPriorityNormal,
};
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */
/* USER CODE END FunctionPrototypes */
void StartDefaultTask(void *argument);
extern void MX_USB_HOST_Init(void);
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */
/**
* @brief FreeRTOS initialization
* @param None
* @retval None
*/
void MX_FREERTOS_Init(void) {
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* USER CODE BEGIN RTOS_MUTEX */
/* add mutexes, ... */
/* USER CODE END RTOS_MUTEX */
/* USER CODE BEGIN RTOS_SEMAPHORES */
/* add semaphores, ... */
/* USER CODE END RTOS_SEMAPHORES */
/* USER CODE BEGIN RTOS_TIMERS */
/* start timers, add new ones, ... */
/* USER CODE END RTOS_TIMERS */
/* USER CODE BEGIN RTOS_QUEUES */
/* add queues, ... */
/* USER CODE END RTOS_QUEUES */
/* Create the thread(s) */
/* creation of defaultTask */
defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
/* USER CODE END RTOS_THREADS */
/* USER CODE BEGIN RTOS_EVENTS */
/* add events, ... */
/* USER CODE END RTOS_EVENTS */
}
/* USER CODE BEGIN Header_StartDefaultTask */
/**
* @brief Function implementing the defaultTask thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{
/* init code for USB_HOST */
MX_USB_HOST_Init();
/* USER CODE BEGIN StartDefaultTask */
/* Infinite loop */
for(;;)
{
printf("STM32CubeMX USB FATFS FREERTOS Test!\r\n");//输出调试信息
UsbTest();//读写U盘中文件
osDelay(1000);
}
/* USER CODE END StartDefaultTask */
}
/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
/* USER CODE END Application */
fatfs.c修改如下:
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file fatfs.c
* @brief Code for fatfs applications
******************************************************************************
* @attention
*
* Copyright (c) 2023 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 */
#include "fatfs.h"
uint8_t retUSBH; /* Return value for USBH */
char USBHPath[4]; /* USBH logical drive path */
FATFS USBHFatFS; /* File system object for USBH logical drive */
FIL USBHFile; /* File object for USBH */
/* USER CODE BEGIN Variables */
#include "usb_host.h"
extern ApplicationTypeDef Appli_state;
/* USER CODE END Variables */
void MX_FATFS_Init(void)
{
/*## FatFS: Link the USBH driver ###########################*/
retUSBH = FATFS_LinkDriver(&USBH_Driver, USBHPath);
/* USER CODE BEGIN Init */
/* additional user code for init */
/* USER CODE END Init */
}
/**
* @brief Gets Time from RTC
* @param None
* @retval Time in DWORD
*/
DWORD get_fattime(void)
{
/* USER CODE BEGIN get_fattime */
return 0;
/* USER CODE END get_fattime */
}
/* USER CODE BEGIN Application */
static void MSC_Application(void) //USB大容量存储区测试代码
{
FRESULT res;
uint32_t byteswritten; //file write/read counts
//uint8_t wtext[] = "This is USB Mass Storage Application Example!\r\n";
uint8_t wtext[] = "这是一个STM32CubeMX_FATFS_FREERTOS_USB测试!\r\n";
#if 1
/*以下代码测试ok,可以向STM32_USB.txt中写入数据*/
uint32_t bytesread; // 读文件计数
uint8_t rtext[1024]; // 读取的buff
printf("\r\n MSC_Application USB \r\n");
//1.挂载USB
res = f_mount(&USBHFatFS,(const TCHAR*)USBHPath,1);
if(res != FR_OK)
{
Error_Handler();
printf(" mount USB fail: %d \r\n",res);
}
else
{
printf(" mount USB success!!! \r\n");
//2.打开
res = f_open(&USBHFile, "STM32_USB.txt", FA_CREATE_ALWAYS | FA_WRITE);
if(res != FR_OK)
{
Error_Handler();
printf(" open file error : %d\r\n",res);
}
else
{
printf(" open file success!!! \r\n");
//3.写数据
res = f_write(&USBHFile, wtext, sizeof(wtext), (void *)&byteswritten); //在文件内写入wtext内的内容
if(res != FR_OK)
{
Error_Handler();
printf(" write file error : %d\r\n",res);
}
printf(" write file success!!! writen count: %d \r\n",byteswritten);
printf(" write Data : %s\r\n",wtext);
//4.关闭文件
res = f_close(&USBHFile);
}
}
printf(" read USB mass storage data.\r\n");
//5.打开文件
res = f_open(&USBHFile, "STM32_USB.txt", FA_READ); //打开文件,权限为只读
if(res != FR_OK)
{ //返回值不为0(出现问题)
Error_Handler();
printf(" open file error : %d\r\n",res); //打印问题代码
}
else
{
printf(" open file success!!! \r\n");
//6.读取txt文件数据
res = f_read(&USBHFile, rtext, sizeof(rtext), (UINT*)&bytesread);//读取文件内容放到rtext中
if(res)
{ //返回值不为0(出现问题)
Error_Handler();
printf(" read error!!! %d\r\n",res); //打印问题代码
}
else
{
printf(" read success!!! \r\n");
printf(" read Data : %s\r\n",rtext); //打印读取到的数据
}
//7.读写一致性检测
if(bytesread == byteswritten) //如果读写位数一致
{
printf(" bytesread == byteswritten,写入与读出数据一致。\r\n"); //打印文件系统工作正常
}
//8.关闭文件
res = f_close(&USBHFile);
}
#endif
#if 0
/*以下代码测试ok,可以向STM32_USB.txt中写入数据*/
/*如果要使用下面的测试代码,将#if 0 改为#if 1*/
if(f_mount(&USBHFatFS,(const TCHAR*)USBHPath,1) !=FR_OK)
{
//Fatfs Initialization Error
Error_Handler();
printf(" mount USB fail!!! \r\n");
}
else
{
printf(" mount USB success!!! \r\n");
if(f_open(&USBHFile, "STM32_USB.txt", FA_CREATE_ALWAYS | FA_WRITE) !=FR_OK)
{
// "STM32_USB.txt" file open for write error
Error_Handler();
printf(" open usb file fail!!! \r\n");
}
else
{
printf(" open usb file success!!! \r\n");
//write data to the text file
res = f_write(&USBHFile, wtext, sizeof(wtext), (void *)&byteswritten);
if((byteswritten==0) || (res != FR_OK)){
Error_Handler();
printf(" write usb file fail!!! \r\n");
}
else
{
printf(" write usb file success!!! \r\n");
//close the open text file
f_close(&USBHFile);
}
printf(" operate USB file end \r\n");
}
}
#endif
}
void UsbTest(void)
{
switch(Appli_state)
{
case APPLICATION_READY:
MSC_Application();
Appli_state = APPLICATION_DISCONNECT;
break;
case APPLICATION_DISCONNECT:
f_mount(NULL, (const TCHAR*)"",0);
break;
default:
break;
}
}
/* USER CODE END Application */
fatfs.h中加入void UsbTest(void)
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file fatfs.h
* @brief Header for fatfs applications
******************************************************************************
* @attention
*
* Copyright (c) 2023 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 */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __fatfs_H
#define __fatfs_H
#ifdef __cplusplus
extern "C" {
#endif
#include "ff.h"
#include "ff_gen_drv.h"
#include "usbh_diskio.h" /* defines USBH_Driver as external */
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern uint8_t retUSBH; /* Return value for USBH */
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 */
void MX_FATFS_Init(void);
/* USER CODE BEGIN Prototypes */
void UsbTest(void);
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /*__fatfs_H */
四、测试截图
串口调试助手接收的数据:
U盘中文件,文件内容截图:文章来源:https://www.toymoban.com/news/detail-799838.html
五、完整工程链接
https://download.csdn.net/download/chen18221987993/87428373文章来源地址https://www.toymoban.com/news/detail-799838.html
到了这里,关于STM32CubeMX+FATFS+FREERTOS读写U盘的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!