From 50e6b12cbcc316a0f15a171521921ee5fbe194aa Mon Sep 17 00:00:00 2001 From: Robofish <1683502971@qq.com> Date: Fri, 3 Oct 2025 22:08:44 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0can?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Core/Src/stm32f4xx_it.c | 1086 +++++++++++++++++++-------------------- User/bsp/can.c | 292 ++++++----- User/bsp/can.h | 46 +- User/device/motor_dm.c | 8 +- User/device/motor_rm.c | 13 +- 5 files changed, 734 insertions(+), 711 deletions(-) diff --git a/Core/Src/stm32f4xx_it.c b/Core/Src/stm32f4xx_it.c index 65d3b51..02c8be5 100644 --- a/Core/Src/stm32f4xx_it.c +++ b/Core/Src/stm32f4xx_it.c @@ -1,543 +1,543 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file stm32f4xx_it.c - * @brief Interrupt Service Routines. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2025 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" -#include "stm32f4xx_it.h" -#include "FreeRTOS.h" -#include "task.h" -/* Private includes ----------------------------------------------------------*/ -/* USER CODE BEGIN Includes */ -#include "bsp/uart.h" -/* USER CODE END Includes */ - -/* Private typedef -----------------------------------------------------------*/ -/* USER CODE BEGIN TD */ - -/* USER CODE END TD */ - -/* 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 -----------------------------------------------*/ -/* USER CODE BEGIN PFP */ - -/* USER CODE END PFP */ - -/* Private user code ---------------------------------------------------------*/ -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -/* External variables --------------------------------------------------------*/ -extern PCD_HandleTypeDef hpcd_USB_OTG_FS; -extern CAN_HandleTypeDef hcan1; -extern CAN_HandleTypeDef hcan2; -extern DMA_HandleTypeDef hdma_i2c2_tx; -extern DMA_HandleTypeDef hdma_i2c3_rx; -extern DMA_HandleTypeDef hdma_spi1_rx; -extern DMA_HandleTypeDef hdma_spi1_tx; -extern TIM_HandleTypeDef htim1; -extern TIM_HandleTypeDef htim7; -extern DMA_HandleTypeDef hdma_usart1_tx; -extern DMA_HandleTypeDef hdma_usart1_rx; -extern DMA_HandleTypeDef hdma_usart3_rx; -extern DMA_HandleTypeDef hdma_usart6_rx; -extern DMA_HandleTypeDef hdma_usart6_tx; -extern UART_HandleTypeDef huart1; -extern UART_HandleTypeDef huart6; -/* USER CODE BEGIN EV */ - -/* USER CODE END EV */ - -/******************************************************************************/ -/* Cortex-M4 Processor Interruption and Exception Handlers */ -/******************************************************************************/ -/** - * @brief This function handles Non maskable interrupt. - */ -void NMI_Handler(void) -{ - /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ - - /* USER CODE END NonMaskableInt_IRQn 0 */ - /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ - while (1) - { - } - /* USER CODE END NonMaskableInt_IRQn 1 */ -} - -/** - * @brief This function handles Hard fault interrupt. - */ -void HardFault_Handler(void) -{ - /* USER CODE BEGIN HardFault_IRQn 0 */ - - /* USER CODE END HardFault_IRQn 0 */ - while (1) - { - /* USER CODE BEGIN W1_HardFault_IRQn 0 */ - /* USER CODE END W1_HardFault_IRQn 0 */ - } -} - -/** - * @brief This function handles Memory management fault. - */ -void MemManage_Handler(void) -{ - /* USER CODE BEGIN MemoryManagement_IRQn 0 */ - - /* USER CODE END MemoryManagement_IRQn 0 */ - while (1) - { - /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */ - /* USER CODE END W1_MemoryManagement_IRQn 0 */ - } -} - -/** - * @brief This function handles Pre-fetch fault, memory access fault. - */ -void BusFault_Handler(void) -{ - /* USER CODE BEGIN BusFault_IRQn 0 */ - - /* USER CODE END BusFault_IRQn 0 */ - while (1) - { - /* USER CODE BEGIN W1_BusFault_IRQn 0 */ - /* USER CODE END W1_BusFault_IRQn 0 */ - } -} - -/** - * @brief This function handles Undefined instruction or illegal state. - */ -void UsageFault_Handler(void) -{ - /* USER CODE BEGIN UsageFault_IRQn 0 */ - - /* USER CODE END UsageFault_IRQn 0 */ - while (1) - { - /* USER CODE BEGIN W1_UsageFault_IRQn 0 */ - /* USER CODE END W1_UsageFault_IRQn 0 */ - } -} - -/** - * @brief This function handles Debug monitor. - */ -void DebugMon_Handler(void) -{ - /* USER CODE BEGIN DebugMonitor_IRQn 0 */ - - /* USER CODE END DebugMonitor_IRQn 0 */ - /* USER CODE BEGIN DebugMonitor_IRQn 1 */ - - /* USER CODE END DebugMonitor_IRQn 1 */ -} - -/** - * @brief This function handles System tick timer. - */ -void SysTick_Handler(void) -{ - /* USER CODE BEGIN SysTick_IRQn 0 */ - - /* USER CODE END SysTick_IRQn 0 */ - HAL_IncTick(); -#if (INCLUDE_xTaskGetSchedulerState == 1 ) - if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) - { -#endif /* INCLUDE_xTaskGetSchedulerState */ - xPortSysTickHandler(); -#if (INCLUDE_xTaskGetSchedulerState == 1 ) - } -#endif /* INCLUDE_xTaskGetSchedulerState */ - /* USER CODE BEGIN SysTick_IRQn 1 */ - - /* USER CODE END SysTick_IRQn 1 */ -} - -/******************************************************************************/ -/* STM32F4xx Peripheral Interrupt Handlers */ -/* Add here the Interrupt Handlers for the used peripherals. */ -/* For the available peripheral interrupt handler names, */ -/* please refer to the startup file (startup_stm32f4xx.s). */ -/******************************************************************************/ - -/** - * @brief This function handles EXTI line0 interrupt. - */ -void EXTI0_IRQHandler(void) -{ - /* USER CODE BEGIN EXTI0_IRQn 0 */ - - /* USER CODE END EXTI0_IRQn 0 */ - HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0); - /* USER CODE BEGIN EXTI0_IRQn 1 */ - - /* USER CODE END EXTI0_IRQn 1 */ -} - -/** - * @brief This function handles EXTI line3 interrupt. - */ -void EXTI3_IRQHandler(void) -{ - /* USER CODE BEGIN EXTI3_IRQn 0 */ - - /* USER CODE END EXTI3_IRQn 0 */ - HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_3); - /* USER CODE BEGIN EXTI3_IRQn 1 */ - - /* USER CODE END EXTI3_IRQn 1 */ -} - -/** - * @brief This function handles EXTI line4 interrupt. - */ -void EXTI4_IRQHandler(void) -{ - /* USER CODE BEGIN EXTI4_IRQn 0 */ - - /* USER CODE END EXTI4_IRQn 0 */ - HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4); - /* USER CODE BEGIN EXTI4_IRQn 1 */ - - /* USER CODE END EXTI4_IRQn 1 */ -} - -/** - * @brief This function handles DMA1 stream1 global interrupt. - */ -void DMA1_Stream1_IRQHandler(void) -{ - /* USER CODE BEGIN DMA1_Stream1_IRQn 0 */ - - /* USER CODE END DMA1_Stream1_IRQn 0 */ - HAL_DMA_IRQHandler(&hdma_usart3_rx); - /* USER CODE BEGIN DMA1_Stream1_IRQn 1 */ - - /* USER CODE END DMA1_Stream1_IRQn 1 */ -} - -/** - * @brief This function handles DMA1 stream2 global interrupt. - */ -void DMA1_Stream2_IRQHandler(void) -{ - /* USER CODE BEGIN DMA1_Stream2_IRQn 0 */ - - /* USER CODE END DMA1_Stream2_IRQn 0 */ - HAL_DMA_IRQHandler(&hdma_i2c3_rx); - /* USER CODE BEGIN DMA1_Stream2_IRQn 1 */ - - /* USER CODE END DMA1_Stream2_IRQn 1 */ -} - -/** - * @brief This function handles CAN1 TX interrupts. - */ -void CAN1_TX_IRQHandler(void) -{ - /* USER CODE BEGIN CAN1_TX_IRQn 0 */ - - /* USER CODE END CAN1_TX_IRQn 0 */ - HAL_CAN_IRQHandler(&hcan1); - /* USER CODE BEGIN CAN1_TX_IRQn 1 */ - - /* USER CODE END CAN1_TX_IRQn 1 */ -} - -/** - * @brief This function handles CAN1 RX0 interrupts. - */ -void CAN1_RX0_IRQHandler(void) -{ - /* USER CODE BEGIN CAN1_RX0_IRQn 0 */ - - /* USER CODE END CAN1_RX0_IRQn 0 */ - HAL_CAN_IRQHandler(&hcan1); - /* USER CODE BEGIN CAN1_RX0_IRQn 1 */ - - /* USER CODE END CAN1_RX0_IRQn 1 */ -} - -/** - * @brief This function handles CAN1 RX1 interrupt. - */ -void CAN1_RX1_IRQHandler(void) -{ - /* USER CODE BEGIN CAN1_RX1_IRQn 0 */ - - /* USER CODE END CAN1_RX1_IRQn 0 */ - HAL_CAN_IRQHandler(&hcan1); - /* USER CODE BEGIN CAN1_RX1_IRQn 1 */ - - /* USER CODE END CAN1_RX1_IRQn 1 */ -} - -/** - * @brief This function handles EXTI line[9:5] interrupts. - */ -void EXTI9_5_IRQHandler(void) -{ - /* USER CODE BEGIN EXTI9_5_IRQn 0 */ - - /* USER CODE END EXTI9_5_IRQn 0 */ - HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_5); - /* USER CODE BEGIN EXTI9_5_IRQn 1 */ - - /* USER CODE END EXTI9_5_IRQn 1 */ -} - -/** - * @brief This function handles TIM1 break interrupt and TIM9 global interrupt. - */ -void TIM1_BRK_TIM9_IRQHandler(void) -{ - /* USER CODE BEGIN TIM1_BRK_TIM9_IRQn 0 */ - - /* USER CODE END TIM1_BRK_TIM9_IRQn 0 */ - HAL_TIM_IRQHandler(&htim1); - /* USER CODE BEGIN TIM1_BRK_TIM9_IRQn 1 */ - - /* USER CODE END TIM1_BRK_TIM9_IRQn 1 */ -} - -/** - * @brief This function handles USART1 global interrupt. - */ -void USART1_IRQHandler(void) -{ - /* USER CODE BEGIN USART1_IRQn 0 */ - - /* USER CODE END USART1_IRQn 0 */ - HAL_UART_IRQHandler(&huart1); - /* USER CODE BEGIN USART1_IRQn 1 */ - BSP_UART_IRQHandler(&huart1); - - /* USER CODE END USART1_IRQn 1 */ -} - -/** - * @brief This function handles DMA1 stream7 global interrupt. - */ -void DMA1_Stream7_IRQHandler(void) -{ - /* USER CODE BEGIN DMA1_Stream7_IRQn 0 */ - - /* USER CODE END DMA1_Stream7_IRQn 0 */ - HAL_DMA_IRQHandler(&hdma_i2c2_tx); - /* USER CODE BEGIN DMA1_Stream7_IRQn 1 */ - - /* USER CODE END DMA1_Stream7_IRQn 1 */ -} - -/** - * @brief This function handles TIM7 global interrupt. - */ -void TIM7_IRQHandler(void) -{ - /* USER CODE BEGIN TIM7_IRQn 0 */ - - /* USER CODE END TIM7_IRQn 0 */ - HAL_TIM_IRQHandler(&htim7); - /* USER CODE BEGIN TIM7_IRQn 1 */ - - /* USER CODE END TIM7_IRQn 1 */ -} - -/** - * @brief This function handles DMA2 stream1 global interrupt. - */ -void DMA2_Stream1_IRQHandler(void) -{ - /* USER CODE BEGIN DMA2_Stream1_IRQn 0 */ - - /* USER CODE END DMA2_Stream1_IRQn 0 */ - HAL_DMA_IRQHandler(&hdma_usart6_rx); - /* USER CODE BEGIN DMA2_Stream1_IRQn 1 */ - - /* USER CODE END DMA2_Stream1_IRQn 1 */ -} - -/** - * @brief This function handles DMA2 stream2 global interrupt. - */ -void DMA2_Stream2_IRQHandler(void) -{ - /* USER CODE BEGIN DMA2_Stream2_IRQn 0 */ - - /* USER CODE END DMA2_Stream2_IRQn 0 */ - HAL_DMA_IRQHandler(&hdma_spi1_rx); - /* USER CODE BEGIN DMA2_Stream2_IRQn 1 */ - - /* USER CODE END DMA2_Stream2_IRQn 1 */ -} - -/** - * @brief This function handles DMA2 stream3 global interrupt. - */ -void DMA2_Stream3_IRQHandler(void) -{ - /* USER CODE BEGIN DMA2_Stream3_IRQn 0 */ - - /* USER CODE END DMA2_Stream3_IRQn 0 */ - HAL_DMA_IRQHandler(&hdma_spi1_tx); - /* USER CODE BEGIN DMA2_Stream3_IRQn 1 */ - - /* USER CODE END DMA2_Stream3_IRQn 1 */ -} - -/** - * @brief This function handles CAN2 TX interrupts. - */ -void CAN2_TX_IRQHandler(void) -{ - /* USER CODE BEGIN CAN2_TX_IRQn 0 */ - - /* USER CODE END CAN2_TX_IRQn 0 */ - HAL_CAN_IRQHandler(&hcan2); - /* USER CODE BEGIN CAN2_TX_IRQn 1 */ - - /* USER CODE END CAN2_TX_IRQn 1 */ -} - -/** - * @brief This function handles CAN2 RX0 interrupts. - */ -void CAN2_RX0_IRQHandler(void) -{ - /* USER CODE BEGIN CAN2_RX0_IRQn 0 */ - - /* USER CODE END CAN2_RX0_IRQn 0 */ - HAL_CAN_IRQHandler(&hcan2); - /* USER CODE BEGIN CAN2_RX0_IRQn 1 */ - - /* USER CODE END CAN2_RX0_IRQn 1 */ -} - -/** - * @brief This function handles CAN2 RX1 interrupt. - */ -void CAN2_RX1_IRQHandler(void) -{ - /* USER CODE BEGIN CAN2_RX1_IRQn 0 */ - - /* USER CODE END CAN2_RX1_IRQn 0 */ - HAL_CAN_IRQHandler(&hcan2); - /* USER CODE BEGIN CAN2_RX1_IRQn 1 */ - - /* USER CODE END CAN2_RX1_IRQn 1 */ -} - -/** - * @brief This function handles USB On The Go FS global interrupt. - */ -void OTG_FS_IRQHandler(void) -{ - /* USER CODE BEGIN OTG_FS_IRQn 0 */ - - /* USER CODE END OTG_FS_IRQn 0 */ - HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS); - /* USER CODE BEGIN OTG_FS_IRQn 1 */ - - /* USER CODE END OTG_FS_IRQn 1 */ -} - -/** - * @brief This function handles DMA2 stream5 global interrupt. - */ -void DMA2_Stream5_IRQHandler(void) -{ - /* USER CODE BEGIN DMA2_Stream5_IRQn 0 */ - - /* USER CODE END DMA2_Stream5_IRQn 0 */ - HAL_DMA_IRQHandler(&hdma_usart1_rx); - /* USER CODE BEGIN DMA2_Stream5_IRQn 1 */ - - /* USER CODE END DMA2_Stream5_IRQn 1 */ -} - -/** - * @brief This function handles DMA2 stream6 global interrupt. - */ -void DMA2_Stream6_IRQHandler(void) -{ - /* USER CODE BEGIN DMA2_Stream6_IRQn 0 */ - - /* USER CODE END DMA2_Stream6_IRQn 0 */ - HAL_DMA_IRQHandler(&hdma_usart6_tx); - /* USER CODE BEGIN DMA2_Stream6_IRQn 1 */ - - /* USER CODE END DMA2_Stream6_IRQn 1 */ -} - -/** - * @brief This function handles DMA2 stream7 global interrupt. - */ -void DMA2_Stream7_IRQHandler(void) -{ - /* USER CODE BEGIN DMA2_Stream7_IRQn 0 */ - - /* USER CODE END DMA2_Stream7_IRQn 0 */ - HAL_DMA_IRQHandler(&hdma_usart1_tx); - /* USER CODE BEGIN DMA2_Stream7_IRQn 1 */ - - /* USER CODE END DMA2_Stream7_IRQn 1 */ -} - -/** - * @brief This function handles USART6 global interrupt. - */ -void USART6_IRQHandler(void) -{ - /* USER CODE BEGIN USART6_IRQn 0 */ - - /* USER CODE END USART6_IRQn 0 */ - HAL_UART_IRQHandler(&huart6); - /* USER CODE BEGIN USART6_IRQn 1 */ - BSP_UART_IRQHandler(&huart6); - - /* USER CODE END USART6_IRQn 1 */ -} - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32f4xx_it.c + * @brief Interrupt Service Routines. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2025 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "stm32f4xx_it.h" +#include "FreeRTOS.h" +#include "task.h" +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +#include "bsp/uart.h" +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN TD */ + +/* USER CODE END TD */ + +/* 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 -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* External variables --------------------------------------------------------*/ +extern PCD_HandleTypeDef hpcd_USB_OTG_FS; +extern CAN_HandleTypeDef hcan1; +extern CAN_HandleTypeDef hcan2; +extern DMA_HandleTypeDef hdma_i2c2_tx; +extern DMA_HandleTypeDef hdma_i2c3_rx; +extern DMA_HandleTypeDef hdma_spi1_rx; +extern DMA_HandleTypeDef hdma_spi1_tx; +extern TIM_HandleTypeDef htim1; +extern TIM_HandleTypeDef htim7; +extern DMA_HandleTypeDef hdma_usart1_tx; +extern DMA_HandleTypeDef hdma_usart1_rx; +extern DMA_HandleTypeDef hdma_usart3_rx; +extern DMA_HandleTypeDef hdma_usart6_rx; +extern DMA_HandleTypeDef hdma_usart6_tx; +extern UART_HandleTypeDef huart1; +extern UART_HandleTypeDef huart6; +/* USER CODE BEGIN EV */ + +/* USER CODE END EV */ + +/******************************************************************************/ +/* Cortex-M4 Processor Interruption and Exception Handlers */ +/******************************************************************************/ +/** + * @brief This function handles Non maskable interrupt. + */ +void NMI_Handler(void) +{ + /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ + + /* USER CODE END NonMaskableInt_IRQn 0 */ + /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ + while (1) + { + } + /* USER CODE END NonMaskableInt_IRQn 1 */ +} + +/** + * @brief This function handles Hard fault interrupt. + */ +void HardFault_Handler(void) +{ + /* USER CODE BEGIN HardFault_IRQn 0 */ + + /* USER CODE END HardFault_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_HardFault_IRQn 0 */ + /* USER CODE END W1_HardFault_IRQn 0 */ + } +} + +/** + * @brief This function handles Memory management fault. + */ +void MemManage_Handler(void) +{ + /* USER CODE BEGIN MemoryManagement_IRQn 0 */ + + /* USER CODE END MemoryManagement_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */ + /* USER CODE END W1_MemoryManagement_IRQn 0 */ + } +} + +/** + * @brief This function handles Pre-fetch fault, memory access fault. + */ +void BusFault_Handler(void) +{ + /* USER CODE BEGIN BusFault_IRQn 0 */ + + /* USER CODE END BusFault_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_BusFault_IRQn 0 */ + /* USER CODE END W1_BusFault_IRQn 0 */ + } +} + +/** + * @brief This function handles Undefined instruction or illegal state. + */ +void UsageFault_Handler(void) +{ + /* USER CODE BEGIN UsageFault_IRQn 0 */ + + /* USER CODE END UsageFault_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_UsageFault_IRQn 0 */ + /* USER CODE END W1_UsageFault_IRQn 0 */ + } +} + +/** + * @brief This function handles Debug monitor. + */ +void DebugMon_Handler(void) +{ + /* USER CODE BEGIN DebugMonitor_IRQn 0 */ + + /* USER CODE END DebugMonitor_IRQn 0 */ + /* USER CODE BEGIN DebugMonitor_IRQn 1 */ + + /* USER CODE END DebugMonitor_IRQn 1 */ +} + +/** + * @brief This function handles System tick timer. + */ +void SysTick_Handler(void) +{ + /* USER CODE BEGIN SysTick_IRQn 0 */ + + /* USER CODE END SysTick_IRQn 0 */ + HAL_IncTick(); +#if (INCLUDE_xTaskGetSchedulerState == 1 ) + if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) + { +#endif /* INCLUDE_xTaskGetSchedulerState */ + xPortSysTickHandler(); +#if (INCLUDE_xTaskGetSchedulerState == 1 ) + } +#endif /* INCLUDE_xTaskGetSchedulerState */ + /* USER CODE BEGIN SysTick_IRQn 1 */ + + /* USER CODE END SysTick_IRQn 1 */ +} + +/******************************************************************************/ +/* STM32F4xx Peripheral Interrupt Handlers */ +/* Add here the Interrupt Handlers for the used peripherals. */ +/* For the available peripheral interrupt handler names, */ +/* please refer to the startup file (startup_stm32f4xx.s). */ +/******************************************************************************/ + +/** + * @brief This function handles EXTI line0 interrupt. + */ +void EXTI0_IRQHandler(void) +{ + /* USER CODE BEGIN EXTI0_IRQn 0 */ + + /* USER CODE END EXTI0_IRQn 0 */ + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0); + /* USER CODE BEGIN EXTI0_IRQn 1 */ + + /* USER CODE END EXTI0_IRQn 1 */ +} + +/** + * @brief This function handles EXTI line3 interrupt. + */ +void EXTI3_IRQHandler(void) +{ + /* USER CODE BEGIN EXTI3_IRQn 0 */ + + /* USER CODE END EXTI3_IRQn 0 */ + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_3); + /* USER CODE BEGIN EXTI3_IRQn 1 */ + + /* USER CODE END EXTI3_IRQn 1 */ +} + +/** + * @brief This function handles EXTI line4 interrupt. + */ +void EXTI4_IRQHandler(void) +{ + /* USER CODE BEGIN EXTI4_IRQn 0 */ + + /* USER CODE END EXTI4_IRQn 0 */ + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4); + /* USER CODE BEGIN EXTI4_IRQn 1 */ + + /* USER CODE END EXTI4_IRQn 1 */ +} + +/** + * @brief This function handles DMA1 stream1 global interrupt. + */ +void DMA1_Stream1_IRQHandler(void) +{ + /* USER CODE BEGIN DMA1_Stream1_IRQn 0 */ + + /* USER CODE END DMA1_Stream1_IRQn 0 */ + HAL_DMA_IRQHandler(&hdma_usart3_rx); + /* USER CODE BEGIN DMA1_Stream1_IRQn 1 */ + + /* USER CODE END DMA1_Stream1_IRQn 1 */ +} + +/** + * @brief This function handles DMA1 stream2 global interrupt. + */ +void DMA1_Stream2_IRQHandler(void) +{ + /* USER CODE BEGIN DMA1_Stream2_IRQn 0 */ + + /* USER CODE END DMA1_Stream2_IRQn 0 */ + HAL_DMA_IRQHandler(&hdma_i2c3_rx); + /* USER CODE BEGIN DMA1_Stream2_IRQn 1 */ + + /* USER CODE END DMA1_Stream2_IRQn 1 */ +} + +/** + * @brief This function handles CAN1 TX interrupts. + */ +void CAN1_TX_IRQHandler(void) +{ + /* USER CODE BEGIN CAN1_TX_IRQn 0 */ + + /* USER CODE END CAN1_TX_IRQn 0 */ + HAL_CAN_IRQHandler(&hcan1); + /* USER CODE BEGIN CAN1_TX_IRQn 1 */ + + /* USER CODE END CAN1_TX_IRQn 1 */ +} + +/** + * @brief This function handles CAN1 RX0 interrupts. + */ +void CAN1_RX0_IRQHandler(void) +{ + /* USER CODE BEGIN CAN1_RX0_IRQn 0 */ + + /* USER CODE END CAN1_RX0_IRQn 0 */ + HAL_CAN_IRQHandler(&hcan1); + /* USER CODE BEGIN CAN1_RX0_IRQn 1 */ + + /* USER CODE END CAN1_RX0_IRQn 1 */ +} + +/** + * @brief This function handles CAN1 RX1 interrupt. + */ +void CAN1_RX1_IRQHandler(void) +{ + /* USER CODE BEGIN CAN1_RX1_IRQn 0 */ + + /* USER CODE END CAN1_RX1_IRQn 0 */ + HAL_CAN_IRQHandler(&hcan1); + /* USER CODE BEGIN CAN1_RX1_IRQn 1 */ + + /* USER CODE END CAN1_RX1_IRQn 1 */ +} + +/** + * @brief This function handles EXTI line[9:5] interrupts. + */ +void EXTI9_5_IRQHandler(void) +{ + /* USER CODE BEGIN EXTI9_5_IRQn 0 */ + + /* USER CODE END EXTI9_5_IRQn 0 */ + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_5); + /* USER CODE BEGIN EXTI9_5_IRQn 1 */ + + /* USER CODE END EXTI9_5_IRQn 1 */ +} + +/** + * @brief This function handles TIM1 break interrupt and TIM9 global interrupt. + */ +void TIM1_BRK_TIM9_IRQHandler(void) +{ + /* USER CODE BEGIN TIM1_BRK_TIM9_IRQn 0 */ + + /* USER CODE END TIM1_BRK_TIM9_IRQn 0 */ + HAL_TIM_IRQHandler(&htim1); + /* USER CODE BEGIN TIM1_BRK_TIM9_IRQn 1 */ + + /* USER CODE END TIM1_BRK_TIM9_IRQn 1 */ +} + +/** + * @brief This function handles USART1 global interrupt. + */ +void USART1_IRQHandler(void) +{ + /* USER CODE BEGIN USART1_IRQn 0 */ + + /* USER CODE END USART1_IRQn 0 */ + HAL_UART_IRQHandler(&huart1); + /* USER CODE BEGIN USART1_IRQn 1 */ + BSP_UART_IRQHandler(&huart1); + + /* USER CODE END USART1_IRQn 1 */ +} + +/** + * @brief This function handles DMA1 stream7 global interrupt. + */ +void DMA1_Stream7_IRQHandler(void) +{ + /* USER CODE BEGIN DMA1_Stream7_IRQn 0 */ + + /* USER CODE END DMA1_Stream7_IRQn 0 */ + HAL_DMA_IRQHandler(&hdma_i2c2_tx); + /* USER CODE BEGIN DMA1_Stream7_IRQn 1 */ + + /* USER CODE END DMA1_Stream7_IRQn 1 */ +} + +/** + * @brief This function handles TIM7 global interrupt. + */ +void TIM7_IRQHandler(void) +{ + /* USER CODE BEGIN TIM7_IRQn 0 */ + + /* USER CODE END TIM7_IRQn 0 */ + HAL_TIM_IRQHandler(&htim7); + /* USER CODE BEGIN TIM7_IRQn 1 */ + + /* USER CODE END TIM7_IRQn 1 */ +} + +/** + * @brief This function handles DMA2 stream1 global interrupt. + */ +void DMA2_Stream1_IRQHandler(void) +{ + /* USER CODE BEGIN DMA2_Stream1_IRQn 0 */ + + /* USER CODE END DMA2_Stream1_IRQn 0 */ + HAL_DMA_IRQHandler(&hdma_usart6_rx); + /* USER CODE BEGIN DMA2_Stream1_IRQn 1 */ + + /* USER CODE END DMA2_Stream1_IRQn 1 */ +} + +/** + * @brief This function handles DMA2 stream2 global interrupt. + */ +void DMA2_Stream2_IRQHandler(void) +{ + /* USER CODE BEGIN DMA2_Stream2_IRQn 0 */ + + /* USER CODE END DMA2_Stream2_IRQn 0 */ + HAL_DMA_IRQHandler(&hdma_spi1_rx); + /* USER CODE BEGIN DMA2_Stream2_IRQn 1 */ + + /* USER CODE END DMA2_Stream2_IRQn 1 */ +} + +/** + * @brief This function handles DMA2 stream3 global interrupt. + */ +void DMA2_Stream3_IRQHandler(void) +{ + /* USER CODE BEGIN DMA2_Stream3_IRQn 0 */ + + /* USER CODE END DMA2_Stream3_IRQn 0 */ + HAL_DMA_IRQHandler(&hdma_spi1_tx); + /* USER CODE BEGIN DMA2_Stream3_IRQn 1 */ + + /* USER CODE END DMA2_Stream3_IRQn 1 */ +} + +/** + * @brief This function handles CAN2 TX interrupts. + */ +void CAN2_TX_IRQHandler(void) +{ + /* USER CODE BEGIN CAN2_TX_IRQn 0 */ + + /* USER CODE END CAN2_TX_IRQn 0 */ + HAL_CAN_IRQHandler(&hcan2); + /* USER CODE BEGIN CAN2_TX_IRQn 1 */ + + /* USER CODE END CAN2_TX_IRQn 1 */ +} + +/** + * @brief This function handles CAN2 RX0 interrupts. + */ +void CAN2_RX0_IRQHandler(void) +{ + /* USER CODE BEGIN CAN2_RX0_IRQn 0 */ + + /* USER CODE END CAN2_RX0_IRQn 0 */ + HAL_CAN_IRQHandler(&hcan2); + /* USER CODE BEGIN CAN2_RX0_IRQn 1 */ + + /* USER CODE END CAN2_RX0_IRQn 1 */ +} + +/** + * @brief This function handles CAN2 RX1 interrupt. + */ +void CAN2_RX1_IRQHandler(void) +{ + /* USER CODE BEGIN CAN2_RX1_IRQn 0 */ + + /* USER CODE END CAN2_RX1_IRQn 0 */ + HAL_CAN_IRQHandler(&hcan2); + /* USER CODE BEGIN CAN2_RX1_IRQn 1 */ + + /* USER CODE END CAN2_RX1_IRQn 1 */ +} + +/** + * @brief This function handles USB On The Go FS global interrupt. + */ +void OTG_FS_IRQHandler(void) +{ + /* USER CODE BEGIN OTG_FS_IRQn 0 */ + + /* USER CODE END OTG_FS_IRQn 0 */ + HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS); + /* USER CODE BEGIN OTG_FS_IRQn 1 */ + + /* USER CODE END OTG_FS_IRQn 1 */ +} + +/** + * @brief This function handles DMA2 stream5 global interrupt. + */ +void DMA2_Stream5_IRQHandler(void) +{ + /* USER CODE BEGIN DMA2_Stream5_IRQn 0 */ + + /* USER CODE END DMA2_Stream5_IRQn 0 */ + HAL_DMA_IRQHandler(&hdma_usart1_rx); + /* USER CODE BEGIN DMA2_Stream5_IRQn 1 */ + + /* USER CODE END DMA2_Stream5_IRQn 1 */ +} + +/** + * @brief This function handles DMA2 stream6 global interrupt. + */ +void DMA2_Stream6_IRQHandler(void) +{ + /* USER CODE BEGIN DMA2_Stream6_IRQn 0 */ + + /* USER CODE END DMA2_Stream6_IRQn 0 */ + HAL_DMA_IRQHandler(&hdma_usart6_tx); + /* USER CODE BEGIN DMA2_Stream6_IRQn 1 */ + + /* USER CODE END DMA2_Stream6_IRQn 1 */ +} + +/** + * @brief This function handles DMA2 stream7 global interrupt. + */ +void DMA2_Stream7_IRQHandler(void) +{ + /* USER CODE BEGIN DMA2_Stream7_IRQn 0 */ + + /* USER CODE END DMA2_Stream7_IRQn 0 */ + HAL_DMA_IRQHandler(&hdma_usart1_tx); + /* USER CODE BEGIN DMA2_Stream7_IRQn 1 */ + + /* USER CODE END DMA2_Stream7_IRQn 1 */ +} + +/** + * @brief This function handles USART6 global interrupt. + */ +void USART6_IRQHandler(void) +{ + /* USER CODE BEGIN USART6_IRQn 0 */ + + /* USER CODE END USART6_IRQn 0 */ + HAL_UART_IRQHandler(&huart6); + /* USER CODE BEGIN USART6_IRQn 1 */ + BSP_UART_IRQHandler(&huart6); + + /* USER CODE END USART6_IRQn 1 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/User/bsp/can.c b/User/bsp/can.c index f29cb3d..e401cdd 100644 --- a/User/bsp/can.c +++ b/User/bsp/can.c @@ -37,16 +37,21 @@ static osMutexId_t queue_mutex = NULL; static void (*CAN_Callback[BSP_CAN_NUM][BSP_CAN_CB_NUM])(void); static bool inited = false; static BSP_CAN_IdParser_t id_parser = NULL; /* ID解析器 */ +static BSP_CAN_TxQueue_t tx_queues[BSP_CAN_NUM]; /* 每个CAN的发送队列 */ /* Private function prototypes ---------------------------------------------- */ static BSP_CAN_t CAN_Get(CAN_HandleTypeDef *hcan); static osMessageQueueId_t BSP_CAN_FindQueue(BSP_CAN_t can, uint32_t can_id); static int8_t BSP_CAN_CreateIdQueue(BSP_CAN_t can, uint32_t can_id, uint8_t queue_size); -static int8_t BSP_CAN_DeleteIdQueue(BSP_CAN_t can, uint32_t can_id); static void BSP_CAN_RxFifo0Callback(void); static void BSP_CAN_RxFifo1Callback(void); +static void BSP_CAN_TxCompleteCallback(void); static BSP_CAN_FrameType_t BSP_CAN_GetFrameType(CAN_RxHeaderTypeDef *header); static uint32_t BSP_CAN_DefaultIdParser(uint32_t original_id, BSP_CAN_FrameType_t frame_type); +static void BSP_CAN_TxQueueInit(BSP_CAN_t can); +static bool BSP_CAN_TxQueuePush(BSP_CAN_t can, BSP_CAN_TxMessage_t *msg); +static bool BSP_CAN_TxQueuePop(BSP_CAN_t can, BSP_CAN_TxMessage_t *msg); +static bool BSP_CAN_TxQueueIsEmpty(BSP_CAN_t can); /* Private functions -------------------------------------------------------- */ /* USER FUNCTION BEGIN */ @@ -121,29 +126,7 @@ static int8_t BSP_CAN_CreateIdQueue(BSP_CAN_t can, uint32_t can_id, uint8_t queu return BSP_OK; } -/** - * @brief 删除指定CAN ID的消息队列 - * @note 内部函数,已包含互斥锁保护 - */ -static int8_t BSP_CAN_DeleteIdQueue(BSP_CAN_t can, uint32_t can_id) { - if (osMutexAcquire(queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) { - return BSP_ERR_TIMEOUT; - } - BSP_CAN_QueueNode_t **current = &queue_list; - while (*current != NULL) { - if ((*current)->can == can && (*current)->can_id == can_id) { - BSP_CAN_QueueNode_t *to_delete = *current; - *current = (*current)->next; - osMessageQueueDelete(to_delete->queue); - BSP_Free(to_delete); - osMutexRelease(queue_mutex); - return BSP_OK; - } - current = &(*current)->next; - } - osMutexRelease(queue_mutex); - return BSP_ERR; // 未找到 -} + /** * @brief 获取帧类型 */ @@ -163,6 +146,106 @@ static uint32_t BSP_CAN_DefaultIdParser(uint32_t original_id, BSP_CAN_FrameType_ return original_id; } +/** + * @brief 初始化发送队列 + */ +static void BSP_CAN_TxQueueInit(BSP_CAN_t can) { + if (can >= BSP_CAN_NUM) return; + + tx_queues[can].head = 0; + tx_queues[can].tail = 0; +} + +/** + * @brief 向发送队列添加消息(无锁) + */ +static bool BSP_CAN_TxQueuePush(BSP_CAN_t can, BSP_CAN_TxMessage_t *msg) { + if (can >= BSP_CAN_NUM || msg == NULL) return false; + + BSP_CAN_TxQueue_t *queue = &tx_queues[can]; + uint32_t next_head = (queue->head + 1) % BSP_CAN_TX_QUEUE_SIZE; + + // 队列满 + if (next_head == queue->tail) { + return false; + } + + // 复制消息 + queue->buffer[queue->head] = *msg; + + // 更新头指针(原子操作) + queue->head = next_head; + + return true; +} + + +/** + * @brief 从发送队列取出消息(无锁) + */ +static bool BSP_CAN_TxQueuePop(BSP_CAN_t can, BSP_CAN_TxMessage_t *msg) { + if (can >= BSP_CAN_NUM || msg == NULL) return false; + + BSP_CAN_TxQueue_t *queue = &tx_queues[can]; + + // 队列空 + if (queue->head == queue->tail) { + return false; + } + + // 复制消息 + *msg = queue->buffer[queue->tail]; + + // 更新尾指针(原子操作) + queue->tail = (queue->tail + 1) % BSP_CAN_TX_QUEUE_SIZE; + + return true; +} + +/** + * @brief 检查发送队列是否为空 + */ +static bool BSP_CAN_TxQueueIsEmpty(BSP_CAN_t can) { + if (can >= BSP_CAN_NUM) return true; + + return tx_queues[can].head == tx_queues[can].tail; +} + +/** + * @brief 处理所有CAN实例的发送队列 + */ +static void BSP_CAN_TxCompleteCallback(void) { + // 处理所有CAN实例的发送队列 + for (int i = 0; i < BSP_CAN_NUM; i++) { + BSP_CAN_t can = (BSP_CAN_t)i; + CAN_HandleTypeDef *hcan = BSP_CAN_GetHandle(can); + if (hcan == NULL) continue; + + BSP_CAN_TxMessage_t msg; + uint32_t mailbox; + + // 尝试发送队列中的消息 + while (!BSP_CAN_TxQueueIsEmpty(can)) { + // 检查是否有空闲邮箱 + if (HAL_CAN_GetTxMailboxesFreeLevel(hcan) == 0) { + break; // 没有空闲邮箱,等待下次中断 + } + + // 从队列中取出消息 + if (!BSP_CAN_TxQueuePop(can, &msg)) { + break; + } + + // 发送消息 + if (HAL_CAN_AddTxMessage(hcan, &msg.header, msg.data, &mailbox) != HAL_OK) { + // 发送失败,消息已经从队列中移除,直接丢弃 + break; + } + } + } +} + + /** * @brief FIFO0接收处理函数 */ @@ -347,7 +430,12 @@ int8_t BSP_CAN_Init(void) { // 清零回调函数数组 memset(CAN_Callback, 0, sizeof(CAN_Callback)); - + + // 初始化发送队列 + for (int i = 0; i < BSP_CAN_NUM; i++) { + BSP_CAN_TxQueueInit((BSP_CAN_t)i); + } + // 初始化ID解析器为默认解析器 id_parser = BSP_CAN_DefaultIdParser; @@ -377,6 +465,9 @@ int8_t BSP_CAN_Init(void) { // 自动注册CAN1接收回调函数 BSP_CAN_RegisterCallback(BSP_CAN_1, HAL_CAN_RX_FIFO0_MSG_PENDING_CB, BSP_CAN_RxFifo0Callback); + BSP_CAN_RegisterCallback(BSP_CAN_1, HAL_CAN_TX_MAILBOX0_CPLT_CB, BSP_CAN_TxCompleteCallback); + BSP_CAN_RegisterCallback(BSP_CAN_1, HAL_CAN_TX_MAILBOX1_CPLT_CB, BSP_CAN_TxCompleteCallback); + BSP_CAN_RegisterCallback(BSP_CAN_1, HAL_CAN_TX_MAILBOX2_CPLT_CB, BSP_CAN_TxCompleteCallback); // 激活CAN1中断 HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING | @@ -390,48 +481,19 @@ int8_t BSP_CAN_Init(void) { // 自动注册CAN2接收回调函数 BSP_CAN_RegisterCallback(BSP_CAN_2, HAL_CAN_RX_FIFO1_MSG_PENDING_CB, BSP_CAN_RxFifo1Callback); + BSP_CAN_RegisterCallback(BSP_CAN_2, HAL_CAN_TX_MAILBOX0_CPLT_CB, BSP_CAN_TxCompleteCallback); + BSP_CAN_RegisterCallback(BSP_CAN_2, HAL_CAN_TX_MAILBOX1_CPLT_CB, BSP_CAN_TxCompleteCallback); + BSP_CAN_RegisterCallback(BSP_CAN_2, HAL_CAN_TX_MAILBOX2_CPLT_CB, BSP_CAN_TxCompleteCallback); // 激活CAN2中断 - HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO1_MSG_PENDING); + HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO1_MSG_PENDING | + CAN_IT_TX_MAILBOX_EMPTY); // 激活发送邮箱空中断 inited = true; return BSP_OK; } -int8_t BSP_CAN_DeInit(void) { - if (!inited) { - return BSP_ERR; - } - - // 删除所有队列 - if (osMutexAcquire(queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) == osOK) { - BSP_CAN_QueueNode_t *current = queue_list; - while (current != NULL) { - BSP_CAN_QueueNode_t *next = current->next; - osMessageQueueDelete(current->queue); - BSP_Free(current); - current = next; - } - queue_list = NULL; - osMutexRelease(queue_mutex); - } - - // 删除互斥锁 - if (queue_mutex != NULL) { - osMutexDelete(queue_mutex); - queue_mutex = NULL; - } - - // 清零回调函数数组 - memset(CAN_Callback, 0, sizeof(CAN_Callback)); - - // 重置ID解析器 - id_parser = NULL; - - inited = false; - return BSP_OK; -} CAN_HandleTypeDef *BSP_CAN_GetHandle(BSP_CAN_t can) { if (can >= BSP_CAN_NUM) { @@ -487,44 +549,58 @@ int8_t BSP_CAN_Transmit(BSP_CAN_t can, BSP_CAN_Format_t format, return BSP_ERR_NULL; } - CAN_TxHeaderTypeDef header = {0}; - uint32_t mailbox; + // 准备发送消息 + BSP_CAN_TxMessage_t tx_msg = {0}; switch (format) { case BSP_CAN_FORMAT_STD_DATA: - header.StdId = id; - header.IDE = CAN_ID_STD; - header.RTR = CAN_RTR_DATA; + tx_msg.header.StdId = id; + tx_msg.header.IDE = CAN_ID_STD; + tx_msg.header.RTR = CAN_RTR_DATA; break; case BSP_CAN_FORMAT_EXT_DATA: - header.ExtId = id; - header.IDE = CAN_ID_EXT; - header.RTR = CAN_RTR_DATA; + tx_msg.header.ExtId = id; + tx_msg.header.IDE = CAN_ID_EXT; + tx_msg.header.RTR = CAN_RTR_DATA; break; case BSP_CAN_FORMAT_STD_REMOTE: - header.StdId = id; - header.IDE = CAN_ID_STD; - header.RTR = CAN_RTR_REMOTE; + tx_msg.header.StdId = id; + tx_msg.header.IDE = CAN_ID_STD; + tx_msg.header.RTR = CAN_RTR_REMOTE; break; case BSP_CAN_FORMAT_EXT_REMOTE: - header.ExtId = id; - header.IDE = CAN_ID_EXT; - header.RTR = CAN_RTR_REMOTE; + tx_msg.header.ExtId = id; + tx_msg.header.IDE = CAN_ID_EXT; + tx_msg.header.RTR = CAN_RTR_REMOTE; break; default: return BSP_ERR; } - header.DLC = dlc; - header.TransmitGlobalTime = DISABLE; + tx_msg.header.DLC = dlc; + tx_msg.header.TransmitGlobalTime = DISABLE; - HAL_StatusTypeDef result = HAL_CAN_AddTxMessage(hcan, &header, data, &mailbox); - - if (result != HAL_OK) { - return BSP_ERR; + // 复制数据 + if (data != NULL && dlc > 0) { + memcpy(tx_msg.data, data, dlc); } - return BSP_OK; + // 尝试直接发送到邮箱 + uint32_t mailbox; + if (HAL_CAN_GetTxMailboxesFreeLevel(hcan) > 0) { + HAL_StatusTypeDef result = HAL_CAN_AddTxMessage(hcan, &tx_msg.header, tx_msg.data, &mailbox); + if (result == HAL_OK) { + return BSP_OK; // 发送成功 + } + } + + // 邮箱满,尝试放入队列 + if (BSP_CAN_TxQueuePush(can, &tx_msg)) { + return BSP_OK; // 成功放入队列 + } + + // 队列也满,丢弃数据 + return BSP_ERR; // 数据丢弃 } int8_t BSP_CAN_TransmitStdDataFrame(BSP_CAN_t can, BSP_CAN_StdDataFrame_t *frame) { @@ -556,12 +632,6 @@ int8_t BSP_CAN_RegisterId(BSP_CAN_t can, uint32_t can_id, uint8_t queue_size) { return BSP_CAN_CreateIdQueue(can, can_id, queue_size); } -int8_t BSP_CAN_UnregisterIdQueue(BSP_CAN_t can, uint32_t can_id) { - if (!inited) { - return BSP_ERR_INITED; - } - return BSP_CAN_DeleteIdQueue(can, can_id); -} int8_t BSP_CAN_GetMessage(BSP_CAN_t can, uint32_t can_id, BSP_CAN_Message_t *msg, uint32_t timeout) { if (!inited) { @@ -628,15 +698,6 @@ int8_t BSP_CAN_RegisterIdParser(BSP_CAN_IdParser_t parser) { return BSP_OK; } -int8_t BSP_CAN_UnregisterIdParser(void) { - if (!inited) { - return BSP_ERR_INITED; - } - - id_parser = BSP_CAN_DefaultIdParser; - return BSP_OK; -} - uint32_t BSP_CAN_ParseId(uint32_t original_id, BSP_CAN_FrameType_t frame_type) { if (id_parser != NULL) { return id_parser(original_id, frame_type); @@ -644,43 +705,4 @@ uint32_t BSP_CAN_ParseId(uint32_t original_id, BSP_CAN_FrameType_t frame_type) { return BSP_CAN_DefaultIdParser(original_id, frame_type); } -int8_t BSP_CAN_WaitTxMailboxEmpty(BSP_CAN_t can, uint32_t timeout) { - if (!inited) { - return BSP_ERR_INITED; - } - if (can >= BSP_CAN_NUM) { - return BSP_ERR; - } - - CAN_HandleTypeDef *hcan = BSP_CAN_GetHandle(can); - if (hcan == NULL) { - return BSP_ERR_NULL; - } - - uint32_t start_time = HAL_GetTick(); - - // 如果超时时间为0,立即检查并返回 - if (timeout == 0) { - uint32_t free_level = HAL_CAN_GetTxMailboxesFreeLevel(hcan); - return (free_level > 0) ? BSP_OK : BSP_ERR_TIMEOUT; - } - - // 等待至少有一个邮箱空闲 - while (true) { - uint32_t free_level = HAL_CAN_GetTxMailboxesFreeLevel(hcan); - if (free_level > 0) { - return BSP_OK; - } - - // 检查超时 - if (timeout != BSP_CAN_TIMEOUT_FOREVER) { - uint32_t elapsed = HAL_GetTick() - start_time; - if (elapsed >= timeout) { - return BSP_ERR_TIMEOUT; - } - } - - // 短暂延时,避免占用过多CPU - osDelay(1); - } -} + diff --git a/User/bsp/can.h b/User/bsp/can.h index 00b60fe..e6b5f71 100644 --- a/User/bsp/can.h +++ b/User/bsp/can.h @@ -21,6 +21,7 @@ extern "C" { #define BSP_CAN_DEFAULT_QUEUE_SIZE 10 #define BSP_CAN_TIMEOUT_IMMEDIATE 0 #define BSP_CAN_TIMEOUT_FOREVER osWaitForever +#define BSP_CAN_TX_QUEUE_SIZE 32 /* 发送队列大小 */ /* USER DEFINE BEGIN */ @@ -102,6 +103,19 @@ typedef struct { /* ID解析回调函数类型 */ typedef uint32_t (*BSP_CAN_IdParser_t)(uint32_t original_id, BSP_CAN_FrameType_t frame_type); +/* CAN发送消息结构体 */ +typedef struct { + CAN_TxHeaderTypeDef header; /* 发送头 */ + uint8_t data[BSP_CAN_MAX_DLC]; /* 数据 */ +} BSP_CAN_TxMessage_t; + +/* 无锁环形队列结构体 */ +typedef struct { + BSP_CAN_TxMessage_t buffer[BSP_CAN_TX_QUEUE_SIZE]; /* 缓冲区 */ + volatile uint32_t head; /* 队列头 */ + volatile uint32_t tail; /* 队列尾 */ +} BSP_CAN_TxQueue_t; + /* USER STRUCT BEGIN */ /* USER STRUCT END */ @@ -114,12 +128,6 @@ typedef uint32_t (*BSP_CAN_IdParser_t)(uint32_t original_id, BSP_CAN_FrameType_t */ int8_t BSP_CAN_Init(void); -/** - * @brief 反初始化 CAN 模块 - * @return BSP_OK 成功,其他值失败 - */ -int8_t BSP_CAN_DeInit(void); - /** * @brief 获取 CAN 句柄 * @param can CAN 枚举 @@ -173,13 +181,20 @@ int8_t BSP_CAN_TransmitExtDataFrame(BSP_CAN_t can, BSP_CAN_ExtDataFrame_t *frame */ int8_t BSP_CAN_TransmitRemoteFrame(BSP_CAN_t can, BSP_CAN_RemoteFrame_t *frame); + /** - * @brief 等待CAN发送邮箱空闲 + * @brief 获取发送队列中待发送消息数量 + * @param can CAN 枚举 + * @return 队列中消息数量,-1表示错误 + */ +int32_t BSP_CAN_GetTxQueueCount(BSP_CAN_t can); + +/** + * @brief 清空发送队列 * @param can CAN 枚举 - * @param timeout 超时时间(毫秒),0为立即返回,osWaitForever为永久等待 * @return BSP_OK 成功,其他值失败 */ -int8_t BSP_CAN_WaitTxMailboxEmpty(BSP_CAN_t can, uint32_t timeout); +int8_t BSP_CAN_FlushTxQueue(BSP_CAN_t can); /** * @brief 注册 CAN ID 接收队列 @@ -190,13 +205,7 @@ int8_t BSP_CAN_WaitTxMailboxEmpty(BSP_CAN_t can, uint32_t timeout); */ int8_t BSP_CAN_RegisterId(BSP_CAN_t can, uint32_t can_id, uint8_t queue_size); -/** - * @brief 注销 CAN ID 接收队列 - * @param can CAN 枚举 - * @param can_id 解析后的CAN ID - * @return BSP_OK 成功,其他值失败 - */ -int8_t BSP_CAN_UnregisterIdQueue(BSP_CAN_t can, uint32_t can_id); + /** * @brief 获取 CAN 消息 @@ -231,11 +240,6 @@ int8_t BSP_CAN_FlushQueue(BSP_CAN_t can, uint32_t can_id); */ int8_t BSP_CAN_RegisterIdParser(BSP_CAN_IdParser_t parser); -/** - * @brief 注销ID解析器 - * @return BSP_OK 成功,其他值失败 - */ -int8_t BSP_CAN_UnregisterIdParser(void); /** * @brief 解析CAN ID diff --git a/User/device/motor_dm.c b/User/device/motor_dm.c index b394d59..0f20982 100644 --- a/User/device/motor_dm.c +++ b/User/device/motor_dm.c @@ -109,7 +109,6 @@ static int8_t MOTOR_DM_SendMITCmd(MOTOR_DM_t *motor, MOTOR_MIT_Output_t *output) uint8_t data[8]; uint16_t pos_tmp,vel_tmp,kp_tmp,kd_tmp,tor_tmp; - uint16_t id = motor->param.can_id; pos_tmp = float_to_uint(output->angle, DM_P_MIN , DM_P_MAX, 16); vel_tmp = float_to_uint(output->velocity, DM_V_MIN , DM_V_MAX, 12); @@ -133,7 +132,6 @@ static int8_t MOTOR_DM_SendMITCmd(MOTOR_DM_t *motor, MOTOR_MIT_Output_t *output) frame.dlc = 8; memcpy(frame.data, data, 8); - BSP_CAN_WaitTxMailboxEmpty(motor->param.can, 1); return BSP_CAN_TransmitStdDataFrame(motor->param.can, &frame) == BSP_OK ? DEVICE_OK : DEVICE_ERR; } @@ -163,7 +161,8 @@ static int8_t MOTOR_DM_SendPosVelCmd(MOTOR_DM_t *motor, float pos, float vel) { frame.dlc = 8; memcpy(frame.data, data, 8); - BSP_CAN_WaitTxMailboxEmpty(motor->param.can, 1); + + return BSP_CAN_TransmitStdDataFrame(motor->param.can, &frame) == BSP_OK ? DEVICE_OK : DEVICE_ERR; } @@ -190,7 +189,6 @@ static int8_t MOTOR_DM_SendVelCmd(MOTOR_DM_t *motor, float vel) { frame.dlc = 4; memcpy(frame.data, data, 4); - BSP_CAN_WaitTxMailboxEmpty(motor->param.can, 1); return BSP_CAN_TransmitStdDataFrame(motor->param.can, &frame) == BSP_OK ? DEVICE_OK : DEVICE_ERR; } @@ -460,7 +458,7 @@ int8_t MOTOR_DM_Enable(MOTOR_DM_Param_t *param){ frame.data[5] = 0xFF; frame.data[6] = 0xFF; frame.data[7] = 0xFC; - BSP_CAN_WaitTxMailboxEmpty(motor->param.can, 1); + return BSP_CAN_TransmitStdDataFrame(motor->param.can, &frame) == BSP_OK ? DEVICE_OK : DEVICE_ERR; } diff --git a/User/device/motor_rm.c b/User/device/motor_rm.c index 1b61374..ba10434 100644 --- a/User/device/motor_rm.c +++ b/User/device/motor_rm.c @@ -139,13 +139,13 @@ static void Motor_RM_Decode(MOTOR_RM_t *motor, BSP_CAN_Message_t *msg) { motor->feedback.rotor_speed = rotor_speed; motor->feedback.torque_current = torque_current; } - while (motor->feedback.rotor_abs_angle < 0) { - motor->feedback.rotor_abs_angle += M_2PI; - } - while (motor->feedback.rotor_abs_angle >= M_2PI) { - motor->feedback.rotor_abs_angle -= M_2PI; - } if (motor->motor.reverse) { + while (motor->feedback.rotor_abs_angle < 0) { + motor->feedback.rotor_abs_angle += M_2PI; + } + while (motor->feedback.rotor_abs_angle >= M_2PI) { + motor->feedback.rotor_abs_angle -= M_2PI; + } motor->feedback.rotor_abs_angle = M_2PI - motor->feedback.rotor_abs_angle; motor->feedback.rotor_speed = -motor->feedback.rotor_speed; motor->feedback.torque_current = -motor->feedback.torque_current; @@ -291,7 +291,6 @@ int8_t MOTOR_RM_Ctrl(MOTOR_RM_Param_t *param) { default: return DEVICE_ERR; } - BSP_CAN_WaitTxMailboxEmpty(param->can, 1); // 等待发送邮箱空闲 return BSP_CAN_TransmitStdDataFrame(param->can, &tx_frame) == BSP_OK ? DEVICE_OK : DEVICE_ERR; }