为什么无法传输数据,灯正常闪烁,快速发送时print twinkle_index,但单条发送却无反应
#include "laser_slave.h"
#include "main.h"
#include "dma.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
#include "modbus.h"
#include "modbus-rtu-private.h"
#include "uart_device.h"
#include "laser_slave.h"
#include "string.h"
#include "stdlib.h"
#include "iwdg.h"
// 定义全局变量
uint8_t aRxBuffer_Uart6[20] = {0};
uint8_t aRxBuffer_Uart4[20] = {0};
uint8_t aRxBuffer_Uart5[20] = {0};
uint8_t aRxBuffer_Uart7[20] = {0};
uint8_t aRxBuffer_Uart8[20] = {0};
uint8_t aRxBuffer_Uart1[20] = {0};
volatile uint8_t rx_complete_uart6 = 0;
volatile uint8_t rx_complete_uart4 = 0;
volatile uint8_t rx_complete_uart5 = 0;
volatile uint8_t rx_complete_uart7 = 0;
volatile uint8_t rx_complete_uart8 = 0;
volatile uint8_t rx_complete_uart1 = 0;
volatile uint16_t len_uart6 = 0;
volatile uint16_t len_uart4 = 0;
volatile uint16_t len_uart5 = 0;
volatile uint16_t len_uart7 = 0;
volatile uint16_t len_uart8 = 0;
volatile uint16_t len_uart1 = 0;
uint32_t time_clip = 0;
uint32_t time_twinkle[2] = {100, 600};
uint16_t twinkle_index = 0;
/**
* 自动生成16位校验码并填入数组最后两位
* @param data: 数据数组(最后两位将被覆盖)
* @param len: 实际参与校验的数据长度(不包含最后两位原位置)
*/
void generate_checksum(uint8_t data[], uint16_t len)
{
uint32_t crc = 0xFFFF; // 初始值
uint16_t i, j;
for (i = 0; i < len; i++) {
crc ^= data[i]; // 当前字节异或到crc
for (j = 0; j < 8; j++) {
if (crc & 0x0001) {
crc >>= 1;
crc ^= 0xA001; // 多项式:x^16 + x^15 + x^2 + 1 (0xA001 反向)
} else {
crc >>= 1;
}
}
}
// 此时 crc 为 16 位结果,低字节在前,高字节在后
uint8_t crc_low = (uint8_t)(crc & 0xFF); // 低字节
uint8_t crc_high = (uint8_t)((crc >> 8) & 0xFF); // 高字节
// 写入数组最后两位:先低后高(Modbus RTU 要求)
data[len] = crc_low;
data[len + 1] = crc_high;
}
// 各个串口的具体处理函数(可加中文注释)
static void handle_uart6_data(uint8_t *buf, uint16_t len)
{
uint16_t prefix = buf[0];
UART_HandleTypeDef *dest_uart = NULL;
switch (prefix)
{
case 0x01: dest_uart = &huart5; break;
case 0x02: dest_uart = &huart1; break;
case 0x03: dest_uart = &huart7; break;
case 0x04: dest_uart = &huart8; break;
case 0x05: dest_uart = &huart4; break;
default:
dest_uart = &huart6;
buf[0] = 0x0E;
goto SEND;
}
buf[0] = 0x01;
if (len >= 2) generate_checksum(buf, len - 2);
SEND:
HAL_UART_Transmit(dest_uart, buf, len, 500);
printf("len: %d ",len);
printf("Prefix hex: 0x%02X\r\n", prefix);
printf("UART6 Data: ");
for (int i = 0; i < len; i++) printf("%02X ", buf[i]);
printf("\r\n");
}
static void handle_uart1_data(uint8_t *buf, uint16_t len)
{
buf[0] = 0x02;
if (len >= 2) generate_checksum(buf, len - 2);
HAL_UART_Transmit(&huart6, buf, len, 500);
printf("UART1 Data: ");
for (int i = 0; i < len; i++) printf("%02X ", buf[i]);
printf("\r\n");
}
static void handle_uart4_data(uint8_t *buf, uint16_t len)
{
buf[0] = 0x05;
if (len >= 2) generate_checksum(buf, len - 2);
HAL_UART_Transmit(&huart6, buf, len, 500);
printf("UART4 Data: ");
for (int i = 0; i < len; i++) printf("%02X ", buf[i]);
printf("\r\n");
}
static void handle_uart5_data(uint8_t *buf, uint16_t len)
{
buf[0] = 0x01;
if (len >= 2) generate_checksum(buf, len - 2);
HAL_UART_Transmit(&huart6, buf, len, 500);
printf("len: %d ",len);
printf("UART5 Data: ");
for (int i = 0; i < len; i++) printf("%02X ", buf[i]);
printf("\r\n");
}
static void handle_uart7_data(uint8_t *buf, uint16_t len)
{
buf[0] = 0x03;
if (len >= 2) generate_checksum(buf, len - 2);
HAL_UART_Transmit(&huart6, buf, len, 500);
printf("UART7 Data: ");
for (int i = 0; i < len; i++) printf("%02X ", buf[i]);
printf("\r\n");
}
static void handle_uart8_data(uint8_t *buf, uint16_t len)
{
buf[0] = 0x04;
if (len >= 2) generate_checksum(buf, len - 2);
HAL_UART_Transmit(&huart6, buf, len, 500);
printf("UART8 Data: ");
for (int i = 0; i < len; i++) printf("%02X ", buf[i]);
printf("\r\n");
}
void process_all_uart_data(void)
{
//——————————————————喂狗加闪灯
HAL_IWDG_Refresh(&hiwdg);//dog
time_clip++;
if(time_clip > time_twinkle[twinkle_index % 2]){
time_clip = 0;
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_2);
}
if(rx_complete_uart6){
//rx_complete_flag = 0;
twinkle_index++;
printf(" twinkle_index: %d\n", twinkle_index);
}
//——————————————————处理串口
if (rx_complete_uart6)
{
uint16_t len = len_uart6;
uint8_t *data = malloc(len);
if (data)
{
memcpy(data, aRxBuffer_Uart6, len);
rx_complete_uart6 = 0;
handle_uart6_data(data, len);
free(data);
}
}
if (rx_complete_uart1)
{
uint16_t len = len_uart1;
uint8_t *data = malloc(len);
if (data)
{
memcpy(data, aRxBuffer_Uart1, len);
rx_complete_uart1 = 0;
handle_uart1_data(data, len);
free(data);
}
}
if (rx_complete_uart4)
{
uint16_t len = len_uart4;
uint8_t *data = malloc(len);
if (data)
{
memcpy(data, aRxBuffer_Uart4, len);
rx_complete_uart4 = 0;
handle_uart4_data(data, len);
free(data);
}
}
if (rx_complete_uart5)
{
uint16_t len = len_uart5;
uint8_t *data = malloc(len);
if (data)
{
memcpy(data, aRxBuffer_Uart5, len);
rx_complete_uart5 = 0;
handle_uart5_data(data, len);
free(data);
}
}
if (rx_complete_uart7)
{
uint16_t len = len_uart7;
uint8_t *data = malloc(len);
if (data)
{
memcpy(data, aRxBuffer_Uart7, len);
rx_complete_uart7 = 0;
handle_uart7_data(data, len);
free(data);
}
}
if (rx_complete_uart8)
{
uint16_t len = len_uart8;
uint8_t *data = malloc(len);
if (data)
{
memcpy(data, aRxBuffer_Uart8, len);
rx_complete_uart8 = 0;
handle_uart8_data(data, len);
free(data);
}
}
}
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32f0xx_it.c
* @brief Interrupt Service Routines.
******************************************************************************
* @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 "stm32f0xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "usart.h"
#include "modbus-rtu-private.h"
#include "uart_device.h"
#include "stdio.h"
#include "laser_slave.h"
extern uint8_t aRxBuffer[256];
uint16_t rx_complete_flag;
uint8_t len;
/* 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 TIM_HandleTypeDef htim6;
extern DMA_HandleTypeDef hdma_usart1_rx;
extern DMA_HandleTypeDef hdma_usart4_rx;
extern DMA_HandleTypeDef hdma_usart5_rx;
extern DMA_HandleTypeDef hdma_usart6_rx;
extern DMA_HandleTypeDef hdma_usart7_rx;
extern DMA_HandleTypeDef hdma_usart8_rx;
extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart2;
extern UART_HandleTypeDef huart4;
extern UART_HandleTypeDef huart5;
extern UART_HandleTypeDef huart6;
extern UART_HandleTypeDef huart7;
extern UART_HandleTypeDef huart8;
/* USER CODE BEGIN EV */
/* USER CODE END EV */
/******************************************************************************/
/* Cortex-M0 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 System service call via SWI instruction.
*/
void SVC_Handler(void)
{
/* USER CODE BEGIN SVC_IRQn 0 */
/* USER CODE END SVC_IRQn 0 */
/* USER CODE BEGIN SVC_IRQn 1 */
/* USER CODE END SVC_IRQn 1 */
}
/**
* @brief This function handles Pendable request for system service.
*/
void PendSV_Handler(void)
{
/* USER CODE BEGIN PendSV_IRQn 0 */
/* USER CODE END PendSV_IRQn 0 */
/* USER CODE BEGIN PendSV_IRQn 1 */
/* USER CODE END PendSV_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();
/* USER CODE BEGIN SysTick_IRQn 1 */
/* USER CODE END SysTick_IRQn 1 */
}
/******************************************************************************/
/* STM32F0xx 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_stm32f0xx.s). */
/******************************************************************************/
/**
* @brief This function handles DMA1 channel 1 interrupt.
*/
void DMA1_Ch1_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Ch1_IRQn 0 */
/* USER CODE END DMA1_Ch1_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart4_rx);
/* USER CODE BEGIN DMA1_Ch1_IRQn 1 */
/* USER CODE END DMA1_Ch1_IRQn 1 */
}
/**
* @brief This function handles DMA1 channel 2 to 3 and DMA2 channel 1 to 2 interrupts.
*/
void DMA1_Ch2_3_DMA2_Ch1_2_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Ch2_3_DMA2_Ch1_2_IRQn 0 */
/* USER CODE END DMA1_Ch2_3_DMA2_Ch1_2_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart1_rx);
HAL_DMA_IRQHandler(&hdma_usart6_rx);
/* USER CODE BEGIN DMA1_Ch2_3_DMA2_Ch1_2_IRQn 1 */
/* USER CODE END DMA1_Ch2_3_DMA2_Ch1_2_IRQn 1 */
}
/**
* @brief This function handles DMA1 channel 4 to 7 and DMA2 channel 3 to 5 interrupts.
*/
void DMA1_Ch4_7_DMA2_Ch3_5_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Ch4_7_DMA2_Ch3_5_IRQn 0 */
/* USER CODE END DMA1_Ch4_7_DMA2_Ch3_5_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart8_rx);
HAL_DMA_IRQHandler(&hdma_usart5_rx);
HAL_DMA_IRQHandler(&hdma_usart7_rx);
/* USER CODE BEGIN DMA1_Ch4_7_DMA2_Ch3_5_IRQn 1 */
/* USER CODE END DMA1_Ch4_7_DMA2_Ch3_5_IRQn 1 */
}
/**
* @brief This function handles TIM6 global and DAC channel underrun error interrupts.
*/
void TIM6_DAC_IRQHandler(void)
{
/* USER CODE BEGIN TIM6_DAC_IRQn 0 */
/* USER CODE END TIM6_DAC_IRQn 0 */
HAL_TIM_IRQHandler(&htim6);
/* USER CODE BEGIN TIM6_DAC_IRQn 1 */
/* USER CODE END TIM6_DAC_IRQn 1 */
}
/**
* @brief This function handles USART1 global interrupt / USART1 wake-up interrupt through EXTI line 25.
*/
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) != RESET &&
__HAL_UART_GET_IT_SOURCE(&huart1, UART_IT_IDLE) != RESET)
{
__HAL_UART_CLEAR_IDLEFLAG(&huart1);
uint16_t remain = __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
len_uart1 = 20 - remain;
if (len_uart1 > 0)
{
rx_complete_uart1 = 1;
}
HAL_UART_Receive_DMA(&huart1, aRxBuffer_Uart1, 20);
}
/* USER CODE END USART1_IRQn 0 */
// HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}
/**
* @brief This function handles USART2 global interrupt / USART2 wake-up interrupt through EXTI line 26.
*/
void USART2_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */
/* USER CODE END USART2_IRQn 0 */
HAL_UART_IRQHandler(&huart2);
/* USER CODE BEGIN USART2_IRQn 1 */
/* USER CODE END USART2_IRQn 1 */
}
/**
* @brief This function handles USART3 to USART8 global interrupts / USART3 wake-up interrupt through EXTI line 28.
*/
void USART3_8_IRQHandler(void)
{
/* USER CODE BEGIN USART3_8_IRQn 0 */
// 处理串口空闲中断
// UART6 IDLE 中断
if (__HAL_UART_GET_FLAG(&huart6, UART_FLAG_IDLE) != RESET)
{
__HAL_UART_CLEAR_IDLEFLAG(&huart6);
// 获取接收到的数据长度(此时 DMA 已基本暂停)
uint16_t remain = __HAL_DMA_GET_COUNTER(&hdma_usart6_rx);
len_uart6 = 25 - remain;
if (len_uart6 > 0)
{
rx_complete_uart6 = 1;
}
// ✅ 让 HAL 自动管理 DMA 启停 —— 不要手动 disable
HAL_UART_Receive_DMA(&huart6, aRxBuffer_Uart6, 20);
}
// ------------------- UART4 IDLE 中断 ---------------------
if (__HAL_UART_GET_FLAG(&huart4, UART_FLAG_IDLE) != RESET &&
__HAL_UART_GET_IT_SOURCE(&huart4, UART_IT_IDLE) != RESET)
{
__HAL_UART_CLEAR_IDLEFLAG(&huart4);
uint16_t remain = __HAL_DMA_GET_COUNTER(&hdma_usart4_rx);
len_uart4 = 20 - remain;
if (len_uart4 > 0)
{
rx_complete_uart4 = 1; // 标志置位,交由主循环处理
}
// ✅ 让 HAL 自动管理重启,不要手动 disable/enable
HAL_UART_Receive_DMA(&huart4, aRxBuffer_Uart4, 20);
}
// ------------------- UART5 IDLE 中断 ---------------------
if (__HAL_UART_GET_FLAG(&huart5, UART_FLAG_IDLE) != RESET &&
__HAL_UART_GET_IT_SOURCE(&huart5, UART_IT_IDLE) != RESET)
{
__HAL_UART_CLEAR_IDLEFLAG(&huart5);
uint16_t remain = __HAL_DMA_GET_COUNTER(&hdma_usart5_rx);
len_uart5 = 20 - remain;
if (len_uart5 > 0)
{
rx_complete_uart5 = 1;
}
HAL_UART_Receive_DMA(&huart5, aRxBuffer_Uart5, 20);
}
// ------------------- UART7 IDLE 中断 ---------------------
if (__HAL_UART_GET_FLAG(&huart7, UART_FLAG_IDLE) != RESET &&
__HAL_UART_GET_IT_SOURCE(&huart7, UART_IT_IDLE) != RESET)
{
__HAL_UART_CLEAR_IDLEFLAG(&huart7);
uint16_t remain = __HAL_DMA_GET_COUNTER(&hdma_usart7_rx);
len_uart7 = 20 - remain;
if (len_uart7 > 0)
{
rx_complete_uart7 = 1;
}
HAL_UART_Receive_DMA(&huart7, aRxBuffer_Uart7, 20);
}
// ------------------- UART8 IDLE 中断 ---------------------
if (__HAL_UART_GET_FLAG(&huart8, UART_FLAG_IDLE) != RESET &&
__HAL_UART_GET_IT_SOURCE(&huart8, UART_IT_IDLE) != RESET)
{
__HAL_UART_CLEAR_IDLEFLAG(&huart8);
uint16_t remain = __HAL_DMA_GET_COUNTER(&hdma_usart8_rx);
len_uart8 = 20 - remain;
if (len_uart8 > 0)
{
rx_complete_uart8 = 1;
}
HAL_UART_Receive_DMA(&huart8, aRxBuffer_Uart8, 20);
}
/* USER CODE END USART3_8_IRQn 0 */
// HAL_UART_IRQHandler(&huart4);
// HAL_UART_IRQHandler(&huart5);
// HAL_UART_IRQHandler(&huart6);
// HAL_UART_IRQHandler(&huart7);
// HAL_UART_IRQHandler(&huart8);
/* USER CODE BEGIN USART3_8_IRQn 1 */
/* USER CODE END USART3_8_IRQn 1 */
}
/* USER CODE BEGIN 1 */
/**
* @brief Period elapsed callback in non-blocking mode
* @param htim TIM handle
* @retval None
*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
printf("[error] measure modbus rtu communication speed time out, time > 500ms.");
HAL_TIM_Base_Stop_IT(&htim6);
__HAL_TIM_SET_COUNTER(&htim6, 0);
}
/* USER CODE END 1 */
int main(void)
{
/* USER CODE BEGIN 1 */
/* 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_DMA_Init();
MX_USART4_UART_Init();
MX_USART1_UART_Init();
MX_USART2_UART_Init();
MX_USART5_UART_Init();
MX_USART6_UART_Init();
MX_USART7_UART_Init();
MX_USART8_UART_Init();
MX_TIM6_Init();
MX_IWDG_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
// Start DMA reception for all UARTs
HAL_UART_Receive_DMA(&huart4, aRxBuffer_Uart4, 20);
HAL_UART_Receive_DMA(&huart5, aRxBuffer_Uart5, 20);
HAL_UART_Receive_DMA(&huart6, aRxBuffer_Uart6, 20);
HAL_UART_Receive_DMA(&huart7, aRxBuffer_Uart7, 20);
HAL_UART_Receive_DMA(&huart8, aRxBuffer_Uart8, 20);
// // Clear transfer register to allow CNDTR write
// __HAL_DMA_DISABLE(&hdma_usart4_rx);
// __HAL_DMA_DISABLE(&hdma_usart5_rx);
// __HAL_DMA_DISABLE(&hdma_usart6_rx);
// __HAL_DMA_DISABLE(&hdma_usart7_rx);
// __HAL_DMA_DISABLE(&hdma_usart8_rx);
// 启用 IDLE 中断
__HAL_UART_ENABLE_IT(&huart6, UART_IT_IDLE);
__HAL_UART_ENABLE_IT(&huart4, UART_IT_IDLE);
__HAL_UART_ENABLE_IT(&huart5, UART_IT_IDLE);
__HAL_UART_ENABLE_IT(&huart7, UART_IT_IDLE);
__HAL_UART_ENABLE_IT(&huart8, UART_IT_IDLE);
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
printf(" twinkle_index: \n");
while(1){
process_all_uart_data(); // importent
HAL_Delay(1); // 可选:轻微延时降低 CPU 占用
}
/* USER CODE END 3 */
}
最新发布