硬件平台:正點原子阿波羅F429
軟件工具:STM32CubeMX 5.6.0
開發IDE: SW4STM32
參考:STM32CubeMX之FatFS讀寫U盤 - 天外飛仙cug的個人空間 - OSCHINA - 中文開源技術交流社區
STM32CubeMX學習筆記(25)——FatFs文件系統使用(操作SPI Flash) - 簡書 (jianshu.com)
測試基於STM32F429--LTDC顯示字符與圖形 - M&D - 博客園 (cnblogs.com)中的工程
API使用可參考STM32CUBEMX庫文件 STM32Cube\Repository\STM32Cube_FW_F4_V1.25.0\Middlewares\Third_Party\FatFs\doc\en\appnote.html
系統的組織

(a)如果提供了具有FatFs硬盤接口的工作硬盤模塊,則不需要其他。(b)為使現有的磁盤驅動具有不同的接口,需要glue功能來轉換fatf和驅動之間的接口。
限制
文件系統類型:FAT、FAT32(r0.0)和exFAT(r1.0)。
打開的文件數:無限制。(取決於可用內存)
卷數:最多10個。
容量大小:512字節/扇區,最大2 TiB。
文件大小:在FAT卷上高達4gib - 1,在exFAT卷上幾乎沒有限制。
集群大小:FAT卷上最多128個扇區,exFAT卷上最多16個MiB。
扇區大小:512、1024、2048和4096字節。
STM32CUBEMX配置:
1.時鍾樹
時鍾樹需要重新配置,USB OTG FS的時鍾為48MHZ PLLQ,PLLP用於生成系統時鍾最大180MHZ,這里配置成120MHZ同時LCD時鍾配置成6.5MHZ
2.USB_OTG_FS模式選擇Host_Only
3.FATFS文件系統模式配置成USB_DISK,
- CODE_PAGE(Code page on target): Simplified Chinese GBK(DBCS,OEM,Windows)
支持簡體中文編碼
- USE_LFN(Use Long Filename): Enabled with dynamic working buffer on the STACK
支持長文件名,並指定使用棧空間為緩沖區
4.USB_HOST配置大容量存儲,打開USB debug功能
USB調試宏USBH_DEBUG_LEVEL = 2.執行如下,調用printf實現
1 #if (USBH_DEBUG_LEVEL > 0U) 2 #define USBH_UsrLog(...) do { \ 3 printf(__VA_ARGS__); \ 4 printf("\n"); \ 5 } while (0) 6 #else 7 #define USBH_UsrLog(...) do {} while (0) 8 #endif 9 10 #if (USBH_DEBUG_LEVEL > 1U) 11 12 #define USBH_ErrLog(...) do { \ 13 printf("ERROR: ") ; \ 14 printf(__VA_ARGS__); \ 15 printf("\n"); \ 16 } while (0)
5.修改堆棧大小
1 int main(void) 2 { 3 /* USER CODE BEGIN 1 */ 4 static int status = 0; 5 /* USER CODE END 1 */ 6 7 /* MCU Configuration--------------------------------------------------------*/ 8 9 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ 10 HAL_Init(); 11 12 /* USER CODE BEGIN Init */ 13 14 /* USER CODE END Init */ 15 16 /* Configure the system clock */ 17 SystemClock_Config(); 18 19 /* USER CODE BEGIN SysInit */ 20 21 /* USER CODE END SysInit */ 22 23 /* Initialize all configured peripherals */ 24 MX_GPIO_Init(); 25 MX_USART1_UART_Init(); 26 MX_FMC_Init(); 27 MX_DMA2D_Init(); 28 MX_LTDC_Init(); 29 MX_TIM3_Init(); 30 MX_FATFS_Init(); 31 MX_USB_HOST_Init(); 32 33 /* Initialize interrupts */ 34 MX_NVIC_Init(); 35 /* USER CODE BEGIN 2 */ 36 //SDRAM Initialization 37 //刷新頻率計數器(以SDCLK頻率計數),計算方法: 38 //COUNT=SDRAM刷新周期/行數-20=SDRAM刷新周期(us)*SDCLK頻率(Mhz)/行數 39 //我們使用的SDRAM刷新周期為64ms,SDCLK=180/2=90Mhz,行數為8192(2^13). 40 //所以,COUNT=64*1000*90/8192-20=683 主頻:180MHZ 41 //COUNT=64*1000*60/8192-20=448 主頻:120MHZ 42 BSP_SDRAM_Initialization_sequence(REFRESH_COUNT); 43 44 //LCD Background light 45 LCD_BL_PWM_Start(); 46 LCD_BL_PWM_SetVal(0); 47 HAL_Delay(2000); 48 LCD_BL_PWM_SetVal(100); 49 50 //Clear LCD 51 BSP_LCD_Clear(LCD_COLOR_BLUE); 52 53 //Set text color 54 BSP_LCD_SetTextColor(LCD_COLOR_RED); 55 56 //draw Rectangle 57 BSP_LCD_DrawRect(100,100,50,50); 58 59 //draw line 60 BSP_LCD_DrawHLine(150,150,100); 61 62 //draw circle 63 BSP_LCD_SetTextColor(LCD_COLOR_GREEN); 64 BSP_LCD_DrawCircle(200,200,50); 65 66 //set font type 67 BSP_LCD_SetFont(&LCD_DEFAULT_FONT); 68 69 70 //display string 71 BSP_LCD_SetTextColor(LCD_COLOR_GREEN); 72 BSP_LCD_SetBackColor(LCD_COLOR_WHITE); 73 BSP_LCD_DisplayStringAt(0,0,(uint8_t*)"LCD TEST FONT",LEFT_MODE); 74 /* USER CODE END 2 */ 75 76 /* Infinite loop */ 77 /* USER CODE BEGIN WHILE */ 78 79 while (1) 80 { 81 /* USER CODE END WHILE */ 82 MX_USB_HOST_Process(); 83 84 /* USER CODE BEGIN 3 */ 85 if(Appli_state == APPLICATION_READY) 86 { 87 BSP_LCD_DisplayStringAt(0,16,(uint8_t*)"1.U Disk load finish!",LEFT_MODE); 88 89 if(status == 0) 90 { 91 status = 1; 92 93 FRESULT retUSBH=f_mount(&USBHFatFS, (TCHAR const*)USBHPath, 1); 94 95 if(retUSBH == FR_OK) 96 { 97 BSP_LCD_DisplayStringAt(0,16*2,(uint8_t*)"2.U Disk mount success!!",LEFT_MODE); 98 BSP_LCD_DisplayStringAt(0,16*3,(uint8_t*)"3.Write file test!!",LEFT_MODE); 99 retUSBH = f_open(&USBHFile,(const char*)"usb_test.txt",FA_CREATE_ALWAYS|FA_WRITE); 100 if(retUSBH == FR_OK) 101 { 102 BSP_LCD_DisplayStringAt(0,16*4,(uint8_t*)"4.Create/open file Success!!",LEFT_MODE); 103 } 104 105 retUSBH = f_write(&USBHFile,FileBuf,23,&bw); 106 107 if(retUSBH == FR_OK) 108 { 109 BSP_LCD_DisplayStringAt(0,16*5,(uint8_t*)"5.Write file Success!!",LEFT_MODE); 110 } 111 112 retUSBH = f_close(&USBHFile); 113 114 if(retUSBH == FR_OK) 115 { 116 BSP_LCD_DisplayStringAt(0,16*6,(uint8_t*)"6.Close file Success!!",LEFT_MODE); 117 } 118 119 BSP_LCD_DisplayStringAt(0,16*7,(uint8_t*)"7.Read file test!!",LEFT_MODE); 120 121 retUSBH = f_open(&USBHFile,(const char*)"usb_test.txt",FA_READ); 122 123 retUSBH = f_read(&USBHFile,RdBuf,23,&bw); 124 125 if(retUSBH == FR_OK) 126 { 127 BSP_LCD_DisplayStringAt(0,16*8,(uint8_t*)"8.Read file Success!!",LEFT_MODE); 128 BSP_LCD_DisplayStringAt(0,16*9,(uint8_t*)RdBuf,LEFT_MODE); 129 } 130 131 132 retUSBH = f_close(&USBHFile); 133 134 if(retUSBH == FR_OK) 135 { 136 BSP_LCD_DisplayStringAt(0,16*10,(uint8_t*)"9.Close file Success!!",LEFT_MODE); 137 } 138 } 139 } 140 141 } 142 else if(Appli_state == APPLICATION_START) 143 { 144 BSP_LCD_DisplayStringAt(240,16*0,(uint8_t*)"USB Insert!",LEFT_MODE); 145 status = 0; 146 } 147 else if(Appli_state == APPLICATION_DISCONNECT) 148 { 149 BSP_LCD_DisplayStringAt(240,16*0,(uint8_t*)"USB disconnect!",LEFT_MODE); 150 HAL_Delay(1000); 151 BSP_LCD_Clear(LCD_COLOR_BLUE); 152 } 153 } 154 /* USER CODE END 3 */ 155 }
U盤讀寫文件測試效果: