stm32f103 canbus Bootloader 升级程序代码 采用hal库
时间: 2023-08-03 21:04:07 浏览: 173
stm32f103基于hal库的usb驱动
以下是一个基于STM32F103的CAN Bootloader升级程序代码,采用HAL库实现,仅供参考:
```c
#include "main.h"
#include "stm32f1xx_hal.h"
#define CAN_CMD_BOOTLOADER_START 0x01
#define CAN_CMD_BOOTLOADER_DATA 0x02
#define CAN_CMD_BOOTLOADER_END 0x03
#define CAN_BOOTLOADER_STATE_IDLE 0
#define CAN_BOOTLOADER_STATE_READY 1
#define CAN_BOOTLOADER_STATE_TRANSFER 2
#define CAN_BOOTLOADER_STATE_COMPLETE 3
#define CAN_BOOTLOADER_DATA_SIZE 8
typedef struct {
uint8_t cmd;
uint32_t address;
uint32_t length;
uint8_t data[CAN_BOOTLOADER_DATA_SIZE];
} can_bootloader_packet_t;
volatile uint8_t can_bootloader_state = CAN_BOOTLOADER_STATE_IDLE;
volatile can_bootloader_packet_t can_bootloader_packet;
CAN_HandleTypeDef hcan;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_CAN_Init(void);
void can_bootloader_handle_command(uint8_t cmd, uint32_t address, uint32_t length) {
switch(cmd) {
case CAN_CMD_BOOTLOADER_START:
can_bootloader_state = CAN_BOOTLOADER_STATE_READY;
can_bootloader_packet.address = address;
can_bootloader_packet.length = length;
break;
case CAN_CMD_BOOTLOADER_DATA:
if(can_bootloader_state == CAN_BOOTLOADER_STATE_TRANSFER) {
uint8_t* address_ptr = (uint8_t*) address;
for(int i = 0; i < CAN_BOOTLOADER_DATA_SIZE && length > 0; i++, address_ptr++, length--) {
*address_ptr = can_bootloader_packet.data[i];
}
if(length == 0) {
can_bootloader_state = CAN_BOOTLOADER_STATE_COMPLETE;
}
}
break;
case CAN_CMD_BOOTLOADER_END:
can_bootloader_state = CAN_BOOTLOADER_STATE_IDLE;
memset(&can_bootloader_packet, 0, sizeof(can_bootloader_packet_t));
break;
default:
break;
}
}
void can_bootloader_handle_data(uint8_t* data, uint8_t length) {
if(can_bootloader_state == CAN_BOOTLOADER_STATE_READY) {
memcpy(can_bootloader_packet.data, data, length);
can_bootloader_state = CAN_BOOTLOADER_STATE_TRANSFER;
} else if(can_bootloader_state == CAN_BOOTLOADER_STATE_TRANSFER) {
if(length <= CAN_BOOTLOADER_DATA_SIZE) {
memcpy(can_bootloader_packet.data, data, length);
}
}
}
void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan) {
if(hcan->Instance == CAN1) {
can_bootloader_handle_data(hcan->pRxMsg->Data, hcan->pRxMsg->DLC);
HAL_CAN_Receive_IT(&hcan1, CAN_FIFO0);
}
}
void can_send_message(uint32_t id, uint8_t* data, uint8_t length) {
CanTxMsgTypeDef tx_msg;
tx_msg.IDE = CAN_ID_STD;
tx_msg.RTR = CAN_RTR_DATA;
tx_msg.StdId = id;
tx_msg.DLC = length;
memcpy(tx_msg.Data, data, length);
HAL_CAN_Transmit(&hcan, 1000);
}
int main(void) {
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_CAN_Init();
while (1) {
switch(can_bootloader_state) {
case CAN_BOOTLOADER_STATE_IDLE:
// 空闲状态
break;
case CAN_BOOTLOADER_STATE_READY:
// 准备接收数据
break;
case CAN_BOOTLOADER_STATE_TRANSFER:
// 正在传输数据
break;
case CAN_BOOTLOADER_STATE_COMPLETE:
// 数据传输完成,执行升级操作
break;
default:
break;
}
}
}
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.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();
}
}
static void MX_CAN_Init(void) {
hcan.Instance = CAN1;
hcan.Init.Prescaler = 6;
hcan.Init.Mode = CAN_MODE_NORMAL;
hcan.Init.SJW = CAN_SJW_1TQ;
hcan.Init.BS1 = CAN_BS1_6TQ;
hcan.Init.BS2 = CAN_BS2_8TQ;
hcan.Init.TTCM = DISABLE;
hcan.Init.ABOM = DISABLE;
hcan.Init.AWUM = DISABLE;
hcan.Init.NART = DISABLE;
hcan.Init.RFLM = DISABLE;
hcan.Init.TXFP = DISABLE;
if (HAL_CAN_Init(&hcan) != HAL_OK) {
Error_Handler();
}
CAN_FilterTypeDef can_filter;
can_filter.FilterIdHigh = 0x0000;
can_filter.FilterIdLow = 0x0000;
can_filter.FilterMaskIdHigh = 0x0000;
can_filter.FilterMaskIdLow = 0x0000;
can_filter.FilterFIFOAssignment = CAN_FILTER_FIFO0;
can_filter.FilterBank = 0;
can_filter.FilterMode = CAN_FILTERMODE_IDMASK;
can_filter.FilterScale = CAN_FILTERSCALE_32BIT;
can_filter.FilterActivation = ENABLE;
HAL_CAN_ConfigFilter(&hcan, &can_filter);
HAL_CAN_Receive_IT(&hcan, CAN_FIFO0);
}
static void MX_GPIO_Init(void) {
__HAL_RCC_GPIOC_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}
void Error_Handler(void) {
while(1) {}
}
```
需要注意的是,HAL库实现的CAN协议栈不支持CAN Bootloader协议,因此需要手动解析CAN消息并进行处理。在这里,`can_bootloader_handle_command()`函数和`can_bootloader_handle_data()`函数用于处理CAN Bootloader命令和数据,`HAL_CAN_RxCpltCallback()`函数用于接收CAN消息,并调用`can_bootloader_handle_data()`函数进行处理。
此外,需要根据具体的硬件和软件环境,调整CAN的波特率、过滤器设置等参数,确保CAN Bootloader升级功能正常运行。
阅读全文