菜鸟如何做网站计算机网络技术就业方向网站开发

张小明 2026/1/10 2:34:55
菜鸟如何做网站,计算机网络技术就业方向网站开发,壹互联是网站公司吗,网址英文单片机IAP#xff08;In Application Programming#xff0c;在线应用编程#xff09;是一种允许用户程序在运行过程中直接对Flash存储器进行读写操作的功能#xff0c;主要用于产品发布后的固件升级。‌‌简单来说#xff0c;就是设备在正常工作状态下#xff0c;无需借…单片机IAPIn Application Programming在线应用编程是一种允许用户程序在运行过程中直接对Flash存储器进行读写操作的功能主要用于产品发布后的固件升级。‌‌简单来说就是设备在正常工作状态下无需借助外部编程工具或拆除硬件直接通过自身的软件程序完成系统升级。首先先使用STM32CubeMX配置好基础设置。配置好后生成程序。然后更改main.c加入自己的Bootloader内容。/* USER CODE BEGIN Header */ /** ****************************************************************************** * file : main.c * brief : Main program body ****************************************************************************** * attention * * Copyright (c) 2025 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 usart.h #include gpio.h /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include stdio.h #include string.h #include stdio.h /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ // 内存地址宏定义根据芯片实际SRAM/FLASH大小调整 #define RAM_Start ((uint32_t)0x20000000) // SRAM起始地址STM32F1系列通用 #define RAM_End ((uint32_t)0x20020000) // SRAM结束地址128KB SRAM0x20000000~0x20020000 #define RAM_FLASH ((uint32_t)0x08000000) // FLASH起始地址STM32F1主FLASH起始 // Bootloader分区配置 #define BOOT_SIZE 0x3000 // Bootloader大小12KB0x300012*1024 #define AppAddress (RAM_FLASH BOOT_SIZE) // APP起始地址0x08003000 #define USER_FLASH_PAGES 52 // APP占用FLASH页数每页1KB共52KB #define UPDATE_CMD update // 升级触发指令串口发送该字符串则擦除APP区 #define ADDR_END_FLASH ((FLASH_PAGE_SIZE*USER_FLASH_PAGES)AppAddress) //App结束地址 // 函数指针类型定义指向无参数、无返回值的函数用于跳转APP的复位函数 typedef void (*iapfun)(void); /* 重定向fputc函数将printf输出重定向到USART1 */ int fputc(int ch, FILE *f) { // 阻塞发送1个字节到串口1超时时间0xFFFF无实际超时 HAL_UART_Transmit(huart1, (uint8_t *)ch, 1, 0xffff); return ch; // 返回发送的字符 } /* 全局变量定义 */ iapfun jump2app; // 跳转APP的函数指针 unsigned int count2 0; // 预留计数变量暂未使用 unsigned char datatemp[256] {0}; // 串口接收缓存每次接收256字节 unsigned char boot_flag 0; // 升级标志0不升级1触发升级 unsigned char time_out_flag 0; // 接收超时标志用于判断APP数据是否接收完成 /* 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 PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * brief 应用程序入口函数 * retval int */ int main(void) { /* USER CODE BEGIN 1 */ unsigned char i; // 10秒倒计时循环变量 /* USER CODE END 1 */ /* MCU初始化配置--------------------------------------------------------*/ /* 1. 复位所有外设初始化FLASH接口和SysTick定时器 */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* 2. 配置系统时钟此处为72MHz由SystemClock_Config实现 */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* 3. 初始化所有已配置的外设GPIO、USART1 */ MX_GPIO_Init(); MX_USART1_UART_Init(); /* USER CODE BEGIN 2 */ // Bootloader启动提示 printf(Bootloader 启动\r\n); printf(输入\update\擦除用户区FLASH或等待10秒自动启动用户程序\r\n); // 10秒倒计时检测升级指令每秒接收1次串口数据共10次 for(i 0; i10; i) { // 阻塞接收串口数据缓存datatemp长度256字节超时1000ms1秒 HAL_UART_Receive(huart1, datatemp, 256, 1000); // 判断接收缓存中是否包含升级指令updatestrstr函数查找datatemp中是否有update字符串 if(strstr((const char *)datatemp, UPDATE_CMD) ! NULL) { /* 触发升级擦除APP区FLASH */ FLASH_EraseInitTypeDef EraseInitStruct; // FLASH擦除配置结构体 unsigned int PageError; // 擦除错误页地址用于定位擦除失败位置 // 解锁FLASHFLASH操作前必须解锁否则硬件拒绝擦写 HAL_FLASH_Unlock(); // 配置FLASH擦除参数 EraseInitStruct.TypeErase FLASH_TYPEERASE_PAGES; // 擦除类型按页擦除 EraseInitStruct.PageAddress AppAddress ; // 起始擦除地址APP区起始地址 EraseInitStruct.NbPages USER_FLASH_PAGES; // 擦除页数APP区总页数 // 执行批量擦除若失败则打印错误页地址 if(HAL_FLASHEx_Erase(EraseInitStruct, PageError) ! HAL_OK) { HAL_FLASH_Lock(); // 擦除失败锁定FLASH printf(擦除失败错误页地址:0x%x\n\r,PageError); return 0; // 退出程序 } HAL_FLASH_Lock(); // 擦除成功锁定FLASH boot_flag 1; // 设置升级标志为1 printf(擦除APP区成功\n\r); break; // 退出10秒循环进入接收APP数据阶段 } } // 触发升级收到update指令 if(boot_flag 1) { HAL_StatusTypeDef temp; // HAL库状态变量接收/写入状态 unsigned int Address; // FLASH编程地址从APP起始地址开始 unsigned int data_32; // 32位数据缓存FLASH按字编程每次写4字节 unsigned char j 0; // 接收计数统计已接收/写入的256字节包数 printf(准备接收APP二进制文件请在30秒内发送\r\n); Address AppAddress ; // 初始化编程地址为APP起始地址 // 阻塞接收APP数据超时30秒若超时则退出 temp HAL_UART_Receive(huart1, datatemp, 256, 30*1000); // 30秒内未收到任何数据退出升级流程 if(temp HAL_TIMEOUT) { printf(接收超时结束等待APP数据\r\n); return 0; } // 成功接收到第一批数据进入循环接收写入流程 else if(temp HAL_OK) { while(1) { unsigned char i; HAL_FLASH_Unlock(); // 解锁FLASH准备编程 // 按字4字节写入FLASH256字节64个字64*4256 for(i0; i64; i) { // 从接收缓存中提取4字节数据i2 i*4按字对齐 data_32 *(unsigned int *)(datatemp[i2]); // 确保编程地址未超出APP区范围 if(Address ADDR_END_FLASH) { // 按字编程FLASH地址Address数据data_32 if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Address, data_32)HAL_OK) { Address 4; // 编程成功地址偏移4字节指向下一个字 } else { HAL_FLASH_Lock(); // 编程失败锁定FLASH printf(写入失败错误地址: 0x%x\n\r, Address); return 0; // 退出程序 } } } HAL_FLASH_Lock(); // 编程完成锁定FLASH // 打印写入状态当前编程地址、已接收包数 printf(成功写入256字节当前地址: 0x%x\t已接收包数: %d\n\r,Address,j); // 继续接收下一批数据超时2秒最后一包数据不足256字节时会超时 temp HAL_UART_Receive(huart1, datatemp, 256, 2*1000); // 接收超时说明无后续数据 if(temp HAL_TIMEOUT) { time_out_flag; // 超时计数1 // 连续2次超时则判定数据接收完成避免单次超时误判 if(time_out_flag 2) { printf(APP数据接收完成写入结束\r\n); goto START_APP; // 跳转到启动APP的逻辑 } } } } } // 未触发升级10秒内未收到update指令 else if(boot_flag 0) { START_APP: // 启动APP的标签升级完成后也会跳转到此处 printf(准备启动用户APP程序\r\n); HAL_Delay(10); // 短暂延时确保串口打印完成 /* 校验APP是否存在判断APP栈顶地址是否合法 */ // 原理APP的中断向量表首4字节是栈顶地址必须在SRAM范围内才视为有效APP printf(APP栈顶地址:0x%x\r\n, (*(unsigned int *)AppAddress )); // 栈顶地址需在SRAM起始~结束地址之间0x20000000~0x20020000 if(((*(unsigned int *)AppAddress ) RAM_Start) ((*(unsigned int *)AppAddress ) RAM_End)) { // 可选关闭全局中断跳转前关闭需在APP中重新开启 //__disable_irq(); // 设置主栈指针MSP为APP的栈顶地址模拟STM32复位流程 __set_MSP(*(unsigned int *)AppAddress ); // 提取APP复位函数地址中断向量表第2项地址4 jump2app (iapfun)*(unsigned int *)(AppAddress 4); jump2app(); // 跳转到APP的复位函数执行APP程序 } else { printf(未检测到有效用户APP程序\r\n); return 0; // 无有效APP退出程序 } } /* USER CODE END 2 */ /* 无限循环理论上不会执行到此处要么跳转APP要么退出程序 */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } /** * brief 系统时钟配置函数 * note 配置为HSE(8MHz) → PLL倍频9倍 → 72MHz系统时钟 * retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct {0}; // 振荡器初始化结构体 RCC_ClkInitTypeDef RCC_ClkInitStruct {0}; // 时钟初始化结构体 /** 初始化RCC振荡器参数 */ RCC_OscInitStruct.OscillatorType RCC_OSCILLATORTYPE_HSE; // 振荡器类型外部高速晶振HSE RCC_OscInitStruct.HSEState RCC_HSE_ON; // 开启HSE RCC_OscInitStruct.HSEPredivValue RCC_HSE_PREDIV_DIV1; // HSE预分频1分频8MHz RCC_OscInitStruct.HSIState RCC_HSI_ON; // 开启内部高速晶振备用 RCC_OscInitStruct.PLL.PLLState RCC_PLL_ON; // 开启PLL RCC_OscInitStruct.PLL.PLLSource RCC_PLLSOURCE_HSE; // PLL时钟源HSE RCC_OscInitStruct.PLL.PLLMUL RCC_PLL_MUL9; // PLL倍频9倍8*972MHz // 配置振荡器失败则进入错误处理 if (HAL_RCC_OscConfig(RCC_OscInitStruct) ! HAL_OK) { Error_Handler(); } /** 初始化CPU、AHB、APB总线时钟 */ RCC_ClkInitStruct.ClockType RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource RCC_SYSCLKSOURCE_PLLCLK; // 系统时钟源PLL输出72MHz RCC_ClkInitStruct.AHBCLKDivider RCC_SYSCLK_DIV1; // AHB总线分频1分频72MHz RCC_ClkInitStruct.APB1CLKDivider RCC_HCLK_DIV2; // APB1总线分频2分频36MHz RCC_ClkInitStruct.APB2CLKDivider RCC_HCLK_DIV1; // APB2总线分频1分频72MHz // 配置时钟FLASH延迟2个周期72MHz需2周期 if (HAL_RCC_ClockConfig(RCC_ClkInitStruct, FLASH_LATENCY_2) ! HAL_OK) { Error_Handler(); } } /* USER CODE BEGIN 4 */ /* USER CODE END 4 */ /** * brief 错误处理函数硬件初始化/FLASH操作失败时调用 * retval None */ void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ /* 用户可自定义错误处理逻辑如LED闪烁报警 */ __disable_irq(); // 关闭全局中断 while (1) // 死循环程序卡死 { } /* USER CODE END Error_Handler_Debug */ } #ifdef USE_FULL_ASSERT /** * brief 断言失败处理函数参数校验失败时调用 * param file: 出错文件名称指针 * param line: 出错行号 * retval None */ void assert_failed(uint8_t *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* 用户可自定义打印出错文件和行号如 printf(参数错误文件 %s 第 %d 行\r\n, file, line); */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */注意写入时需要更改代码写入大小与代码里宏定义的大小一样。配置完成后写入stm32f103c8t6单片机。然后接着编写单片机内运行的程序APP使用上面的Bootloader程序升级写入并且跳转运行。基础配置使用STM32CubeMX同上一样配置。APP程序可以是任意程序我们这里写入一个串口不断发送数据的示例程序/* USER CODE BEGIN Header */ /** ****************************************************************************** * file : main.c * brief : Main program body ****************************************************************************** * attention * * Copyright (c) 2025 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 usart.h #include gpio.h /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include stdio.h /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ #define ROM_FLASH ((uint32_t)0x08000000) //Flash起始地址 #define ROM_SIZE 0x3000 //Bootloader程序大小 /* 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 PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP */ int fputc(int ch, FILE *f) { HAL_UART_Transmit(huart1, (uint8_t *)ch, 1, 0xffff); return ch; } /* 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 */ uint32_t SUM 0; /* 设置中断向量偏移地址 */ SCB-VTOR ROM_FLASH | ROM_SIZE; /* 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_USART1_UART_Init(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ HAL_Delay(10); if(SUM%100 0) { printf(this is app!\t%d\n\r,SUM/100); } SUM; } /* USER CODE END 3 */ } /** * brief System Clock Configuration * retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct {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(); } } /* 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 */关键点是这里需要程序写入改为偏移量偏移到Bootloader程序之后起始位置为0x8003000字节为0xD000然后生成为.bin文件使用命令//添加这条命令用来生成bin文件 $K\ARM\ARMCC\bin\fromelf.exe --bin --outputBin\L.bin !L生成了一个.bin文件等下我们引导写入到单片机中。打开串口工具sscom5.13.1配置串口发送文件延时为100ms.因为stm32是接收一包写一包的比较耗时启动单片机写入APP程序串口提示请在10s内输入升级命令发送update命令开始升级选择.bin文件并发送。升级升级完成并运行程序了。
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

自己免费做网站(四)网络促销的方法有哪些

Dify中RAG技术实战应用解析 在大模型能力日益强大的今天,一个现实问题却始终困扰着企业AI落地:为什么模型“懂得很多”,但在具体业务场景中总是答非所问? 答案往往不在于模型本身,而在于知识的“时效性”与“专有性”。…

张小明 2025/12/23 3:40:40 网站建设

上海网站维护专门做酒店自助餐的网站

Bash脚本常见问题及解决方法 1. 管道创建子shell问题 在编写Bash脚本时,有时会遇到变量值异常的情况,例如 $COUNT 始终为零。这是因为管道会创建子shell,而 while 循环在子shell中运行,其内部对变量的更改不会影响脚本外部的变量。 解决方案 避免使用管道 :可以使…

张小明 2025/12/23 3:40:42 网站建设

东莞万江做网站宣传片拍摄脚本范本

在 Hive SQL 中,COALESCE()、NVL()和IFNULL()都是用于处理NULL 值的函数,但在参数数量、语法兼容、功能范围等方面存在显著区别。 一、函数基本定义与用法 1. NVL() 函数 Hive 中的NVL()是双参数函数,用于将 NULL 值替换为指定的非 NULL 值&a…

张小明 2025/12/23 3:40:42 网站建设

管理类手机网站小程序代理模板

🎯 项目亮点速览 【免费下载链接】HoYo.Gacha ✨ An unofficial tool for managing and analyzing your miHoYo gacha records. (Genshin Impact | Honkai: Star Rail) 一个非官方的工具,用于管理和分析你的 miHoYo 抽卡记录。(原神 | 崩坏&a…

张小明 2025/12/23 3:19:33 网站建设

中山网站建设文化咨询wordpress固定连接设置404

导师总说“表达不严谨”“逻辑有跳跃”?别慌!你的专属“论文质检官”已上线各位在学术表达中“踩坑无数”的论文战士,是否经历过这样的痛苦时刻:明明觉得自己写得清晰流畅,却被导师批注“此处表述不专业”“论证逻辑不…

张小明 2025/12/23 3:40:43 网站建设

网站建设代码容易出错蛋糕店网页设计图片

5G 时代光通信中的超信道传输与灵活栅格波长路由 1. 单通道和多通道非线性补偿(NLC)的缩放规则 在光通信系统中,接收器检测带宽之外的波分复用(WDM)通道无法进行数字补偿,这降低了数字反向传播(DBP)的有效性。为了评估全负载 WDM 系统中通道内和多通道 NLC 的有效性,…

张小明 2025/12/23 3:40:44 网站建设