嵌入式工具库 -- 脱机离线下载器(STM32F103C8T6)
目錄
前言
脫機下載器資料獲取
關注微信公眾號 -- 星之援工作室 發(fā)送關鍵字(脫機下載器)
原理圖:
PCB
3D效果
正面
反面
實物圖
主要代碼展示
main.c
演示視頻
USB文件(自己使用自己的HEX文件即可)
百度網盤
🫡若需要幫助,請咨詢博主🫡
前言
在Gitee上發(fā)現(xiàn)了一個脫機下載器項目,我決定實踐復刻它。首先,我閱讀了項目的代碼,了解其實現(xiàn)原理和功能。接著,我自己進行一個電路圖的繪畫,并通過STM32系列的芯片進行了配置和連接。然后,按照原理圖對代碼進行了適當?shù)男薷暮驼{整,以適配我的硬件環(huán)境。最后,我進行了編譯、燒錄和調試的工作,測試了脫機下載器的功能,確保其正常工作。
最后進行了整機的調試,完成了這個復刻,后續(xù)將添加在線下載功能 ~~~~~
脫機下載器資料獲取
關注微信公眾號 -- 星之援工作室 發(fā)送關鍵字(脫機下載器)
??🫡🫡🫡🫡🫡🫡🫡🫡??
歡迎關注微信公眾號星之援工作室,公眾號不定時開源設計項目
支持單片機,Android系統(tǒng)設計成品定制,項目代做
請聯(lián)系微信:13648103287
原理圖:
主要運用到的元器件:
STM32F103C8T6,W25Q128,無源晶振(8M),3.3穩(wěn)壓模塊,RGB燈(0805)
使用立創(chuàng)經行的換圖與連線,咱就圖個免費 ~~
完成功能
1.離線下載
2.設置下載地址
3.添加提示音以及狀態(tài)燈
PCB
繪制了兩板圖,一版是直接焊屏幕,一版就是直接買屏幕,個人偏向買屏幕,畢竟少焊點東西啦,節(jié)約時間以及提高容錯率
3D效果
正面
反面
實物圖
?
主要代碼展示
main.c
/* USER CODE BEGIN Header */ /********************************************************************************* @file : main.c* @brief : Main program body******************************************************************************* @attention** Copyright (c) 2022 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 "usb_device.h" #include "key.h" #include "led.h" #include "oled.h" #include "ff.h" #include "flash_blob.h" #include "offline.h" #include "hex2bin.h" #include "stmflash.h"FRESULT Res; FIL fnew; /* file objects */ FATFS fs; /* FatFs文件系統(tǒng)對象 */ DIR DirInfo; /* 目錄信息 */ FILINFO FileInfo; /* 文件信息 */ int8_t name_cnt = 0; /* 文件個數(shù) */ BYTE work[FF_MAX_SS]; /* FatFs文件工作區(qū)域 */ char Name_Buffer[20][20]; /* 文件名 */ int8_t Select_file = 0; /* 選中下載文件 */ uint32_t flash_addr = 0x8000000; uint8_t mode = 0;int main(void) {uint8_t RES_FS = 0;uint8_t addr[4];HAL_Init();SystemClock_Config();OLED_Init();MX_USB_DEVICE_Init();MX_KEY_Init();MX_LED_Init();// 賦值falsh// STMFLASH_Read(FLASH_SAVE_ADDR, (uint16_t *)addr, 4);// flash_addr = ((addr[0] << 8 | addr[1]) << 8 | addr[2]) << 8 | addr[3];// FATFS文件系統(tǒng)掛載algo_init(); // 下載算法初始化RES_FS = f_mount(&fs, "", 1); // 掛載文件系統(tǒng)if (RES_FS == FR_OK);else if (RES_FS == FR_NO_FILESYSTEM) // 如果是新芯片還沒有文件系統(tǒng){OLED_ShowString(0, 2, "Fatfs Format..", 12);f_mkfs("", 0, work, sizeof(work));OLED_ShowString(0, 2, "Format Finished", 12);}elseOLED_ShowString(0, 2, "Fatfs Failed..", 12);// f_unlink("write.bin");// 讀取文件名到文件列表if (f_opendir(&DirInfo, (const TCHAR *)"0:") == FR_OK) // 讀取根目錄下文件信息{f_readdir(&DirInfo, &FileInfo);while (f_readdir(&DirInfo, &FileInfo) == FR_OK) // 讀文件信息到文件狀態(tài)結構體中{if (!FileInfo.fname[0])break;strcpy(Name_Buffer[name_cnt], FileInfo.fname);if (strstr(Name_Buffer[name_cnt], ".BIN")){name_cnt++;if (name_cnt >= 20) // 最多保存20個文件名break;}if (strstr(Name_Buffer[name_cnt], ".HEX")){name_cnt++;if (name_cnt >= 20) // 最多保存20個文件名break;}}}while (1){menu();}/* USER CODE END 3 */ }void menu(void) {static uint8_t mode_status = 0;switch (mode){case 0: // 功能選擇select_function();break;case 1: // 離線下載模式Downloader();break;case 2: // flash下載地址FlashAddr_Set();break;}if (mode != mode_status){mode_status = mode;OLED_Clear();} }void OLED_ShowMenu(uint8_t num) {switch (num){case 0: // 離線下載OLED_ShowCH(24, 0, 0);OLED_ShowCH(36, 0, 1);OLED_ShowCH(48, 0, 2);OLED_ShowCH(60, 0, 3);// 地址設置OLED_ShowCH(24, 2, 4);OLED_ShowCH(36, 2, 5);OLED_ShowCH(48, 2, 6);OLED_ShowCH(60, 2, 7);break;case 1: // 文件選擇OLED_ShowCH(0, 0, 8);OLED_ShowCH(12, 0, 9);OLED_ShowCH(24, 0, 10);OLED_ShowCH(36, 0, 11);break;case 2: // 地址OLED_ShowString(0, 0, "FLASH", 12);OLED_ShowCH(40, 0, 12);OLED_ShowCH(52, 0, 13);OLED_ShowCH(64, 0, 4);OLED_ShowCH(76, 0, 5);break;} }void select_function(void) {static uint8_t t = 1;uint8_t key;key = KEY_Scan();if (key == KEY0_PRES){t++;if (t > 2)t = 1;}else if (key == KEY1_PRES) // 返回主頁面{mode = 0;t = 1;}else if (key == KEY2_PRES) // 確認{mode = t;t = 1;}switch (t){case 1:OLED_ShowString(0, 2, " ", 12);OLED_ShowString(0, 0, "->", 12);break;case 2:OLED_ShowString(0, 0, " ", 12);OLED_ShowString(0, 2, "->", 12);break;}OLED_ShowMenu(0); }void Downloader(void) {uint8_t key = 0;key = KEY_Scan();if (key == KEY0_PRES){Select_file++;OLED_ShowString(0, 2, " ", 12);}else if (key == KEY1_PRES) // 返回主頁面mode = 0;else if (key == KEY2_PRES)Auto_Fash();if (name_cnt == 0)Select_file = 0;else{if (Select_file >= name_cnt)Select_file = 0;else if (Select_file < 0)Select_file = name_cnt - 1;}OLED_ShowMenu(1);OLED_ShowString(0, 2, (uint8_t *)Name_Buffer[Select_file], 12);if (name_cnt == 0)OLED_ShowNum(90, 0, Select_file, 2, 12);elseOLED_ShowNum(90, 0, Select_file + 1, 2, 12);OLED_ShowString(102, 0, "/", 12);OLED_ShowNum(114, 0, name_cnt, 2, 12); }void FlashAddr_Set(void) {static uint8_t k = 0, k1 = 0;static uint8_t setmode = 0;static uint8_t ad[4];static uint8_t addr[8];uint8_t key = 0, i;addr[7] = (flash_addr / 0x01) % 16;addr[6] = (flash_addr / 0x10) % 16;addr[5] = (flash_addr / 0x100) % 16;addr[4] = (flash_addr / 0x1000) % 16;addr[3] = (flash_addr / 0x10000) % 16;addr[2] = (flash_addr / 0x100000) % 16;addr[1] = (flash_addr / 0x1000000) % 16;addr[0] = (flash_addr / 0x10000000) % 16;OLED_ShowMenu(2);OLED_ShowString(0, 2, "0x", 12);while (1){for (i = 0; i < 8; i++){if (addr[i] < 10)OLED_ShowChar(18 + 6 * i, 2, addr[i] + 48, 12);elseOLED_ShowChar(18 + 6 * i, 2, addr[i] + 65 - 10, 12);}key = KEY_Scan();if (key == KEY0_PRES){if (setmode == 0){OLED_ShowString(18 + 6 * k, 3, "|", 12);setmode = 1;}else if (setmode == 1){addr[k]++;if (addr[k] > 15)addr[k] = 0;}}else if (key == KEY1_PRES){if (setmode == 0){mode = 0;break;}else if (setmode == 1){k++;if (k >= 8)k = 0;}}else if (key == KEY2_PRES){if (setmode == 0){// flash_addr = 0;ad[0] = addr[0] << 4 | addr[1];ad[1] = addr[2] << 4 | addr[3];ad[2] = addr[4] << 4 | addr[5];ad[3] = addr[6] << 4 | addr[7];flash_addr = ((ad[0] << 8 | ad[1]) << 8 | ad[2]) << 8 | ad[3];STMFLASH_Write(FLASH_SAVE_ADDR, (uint16_t *)ad, 4);HAL_Delay(1000);mode = 0;k = 0;break;}else if (setmode == 1){setmode = 0;OLED_ShowString(18 + 6 * k1, 3, " ", 12);}}if (k1 != k){OLED_ShowString(18 + 6 * k1, 3, " ", 12);OLED_ShowString(18 + 6 * k, 3, "|", 12);k1 = k;}} }/*** @brief System Clock Configuration* @retval None*/ void SystemClock_Config(void) {RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};/** 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.HSEPredivValue = RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;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();}PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB;PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5;if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK){Error_Handler();} }/* 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 */演示視頻
USB文件(自己使用自己的HEX文件即可)
百度網盤
鏈接:https://pan.baidu.com/s/1sz5dzR5yzwIxZ_9EqGQ5Yw?pwd=xzy0?
提取碼:xzy0?
🫡若需要幫助,請咨詢博主🫡
????END????
總結
以上是生活随笔為你收集整理的嵌入式工具库 -- 脱机离线下载器(STM32F103C8T6)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android安装Mysql服务,and
- 下一篇: yolov5笔记(3)——移动端部署自己