基于STM32F103的CAN bootload程序源码 包含boot和app两个工程已应用到实际项目并量产在嵌入式开发领域CAN bootload程序对于设备的远程升级以及灵活更新有着至关重要的意义。今天就来给大家分享基于STM32F103的CAN bootload程序源码这可是包含boot和app两个工程并且已经成功应用到实际项目甚至实现量产啦。Boot工程Boot工程主要负责初始化系统、检测是否有更新请求并引导程序跳转到APP区域运行。先来看看初始化部分代码void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct {0}; // 这里配置HSE使用外部高速时钟 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.PLLMUL RCC_PLL_MUL9; if (HAL_RCC_OscConfig(RCC_OscInitStruct)! HAL_OK) { Error_Handler(); } // 配置系统时钟AHB、APB1、APB2等总线时钟 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(); } }这段代码主要进行了系统时钟的配置我们选择了HSE作为PLL的时钟源并通过PLLMUL配置将时钟倍频到72MHz这是STM32F103常用的工作频率。之后配置了各个总线时钟的分频以满足不同外设的工作需求。在检测更新请求方面CAN接收中断处理函数是关键void CAN_RX0_IRQHandler(void) { CAN_RxHeaderTypeDef RxHeader; uint8_t RxData[8]; HAL_CAN_GetRxMessage(hcan1, CAN_RX_FIFO0, RxHeader, RxData); // 假设更新请求的CAN ID为0x123 if (RxHeader.StdId 0x123) { // 设置标志位表明有更新请求 update_flag 1; } }这里当CAN接收到ID为0x123的报文时就会设置更新标志位update_flag后续程序检测到这个标志位就会进行相应的更新操作。基于STM32F103的CAN bootload程序源码 包含boot和app两个工程已应用到实际项目并量产当检测到更新并且完成数据接收后就要跳转到APP区域运行了typedef void (*pFunction)(void); pFunction Jump_To_Application; uint32_t JumpAddress; // APP起始地址假设为0x08005000 JumpAddress *(__IO uint32_t*) (0x08005000 4); Jump_To_Application (pFunction) JumpAddress; // 设置主堆栈指针 __set_MSP(*(__IO uint32_t*) 0x08005000); Jump_To_Application();这里通过先获取APP起始地址处存放的栈顶指针设置主堆栈指针再获取复位向量地址并强制转换为函数指针最后调用该函数实现跳转到APP运行。APP工程APP工程就是设备正常运行的主体程序了这里以一个简单的LED闪烁代码为例int main(void) { // 初始化GPIO假设LED连接在PA5 GPIO_InitTypeDef GPIO_InitStruct {0}; __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin GPIO_PIN_5; GPIO_InitStruct.Mode GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Speed GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, GPIO_InitStruct); while (1) { HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); HAL_Delay(500); } }这段代码很简单先使能GPIOA的时钟然后配置PA5为推挽输出模式速度为高速。在主循环中通过HALGPIOTogglePin函数实现LED的闪烁每500毫秒翻转一次电平。基于STM32F103的CAN bootload程序就是这样两个工程相互配合实现设备的正常运行以及远程更新功能。在实际项目中通过这种方式大大提高了产品的维护性和可升级性这也是它能够成功应用并量产的重要原因。希望这篇分享对大家在相关开发工作中有所帮助。