STM32F407配置USART1作为串口232的接收,但是无论如何都进入不了接收中断。硬件一步步检查,最后发现忘记软件开串口中断。分享下一种FreeRTOS串口接收AT指令处理思路吧
1.创建一个串口结构体
//定义串口最大 发送和接收长度 #define RX_BUFFER_SIZE 512 #define TX_BUFFER_SIZE 512 // 创建一个串口结构体,用于DMA串口的发送和接收 typedef struct { uint8_t receive_buffer[RX_BUFFER_SIZE]; // 接收数组,大小512 uint16_t received_size; // 已接收大小 uint8_t transmit_buffer[TX_BUFFER_SIZE]; // 发送数组,大小512 SemaphoreHandle_t rx_idle_semaphore; // 接收 idle信号量 SemaphoreHandle_t tx_complete_semaphore; // 发送完成的信号量 } UART_DMA_HandleTypeDef;
2.创建中断接收函数,并实现串口发送完成和串口接受空闲中断,如果更严谨的话还需要创建一个
void RS232_TxCpltCallback(void) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; xSemaphoreGiveFromISR(rs232_uart_handle.tx_complete_semaphore, &xHigherPriorityTaskWoken); } void RS232_UART_IDLECallback(void) { HAL_UART_DMAStop(&huart1); // 停止本次DMA传输 rs232_uart_handle.received_size = RX_BUFFER_SIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx); // 计算接收到的数据长度 // 从ISR中释放信号量以通知任务 BaseType_t xHigherPriorityTaskWoken = pdFALSE; xSemaphoreGiveFromISR(rs232_uart_handle.rx_idle_semaphore, &xHigherPriorityTaskWoken); portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } void RS232_UART_IRQHandler(void) { if (USART1 == huart1.Instance) // 判断是否是串口1 { if (RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE)) // 判断是否是空闲中断 { __HAL_UART_CLEAR_IDLEFLAG(&huart1); // 清楚空闲中断标志(否则会一直不断进入中断) RS232_UART_IDLECallback(); // 调用中断处理函数 } // 是否是DMA发送完成中断 if (RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_TC)) { __HAL_UART_CLEAR_FLAG(&huart1, UART_FLAG_TC); // 清除DMA发送完成中断标志 RS232_TxCpltCallback(); // 调用DMA发送完成中断处理函数 } } }
3.创建一个Task专门用于接收和处理串口数据。
void RS232_Loop(void) { // 清除UART1相关的中断错误标志 __HAL_UART_CLEAR_FLAG(&huart1, UART_FLAG_ORE); // 清除溢出错误标志 __HAL_UART_CLEAR_FLAG(&huart1, UART_FLAG_NE); // 清除噪声错误标志 __HAL_UART_CLEAR_FLAG(&huart1, UART_FLAG_FE); // 清除帧错误标志 __HAL_UART_CLEAR_FLAG(&huart1, UART_FLAG_PE); // 清除奇偶校验错误标志 __HAL_UART_CLEAR_FLAG(&huart1, UART_FLAG_RXNE); // 清除奇偶校验错误标志 __HAL_UART_CLEAR_IDLEFLAG(&huart1); __HAL_UART_ENABLE_IT(&huart1, UART_IT_ERR); __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); // 使能串UART2 IDLE中断 HAL_UART_Receive_DMA(&huart1, (uint8_t *)rs232_uart_handle.receive_buffer, RX_BUFFER_SIZE); xSemaphoreTake(rs232_uart_handle.rx_idle_semaphore, 0); while (1) { // 等待 RS-232 接收到完整的 AT 命令 if (xSemaphoreTake(rs232_uart_handle.rx_idle_semaphore, pdMS_TO_TICKS(1000)) == pdTRUE) { // 解析 AT 命令并执行 alon_rs232_process_at_command((const char *)rs232_uart_handle.receive_buffer); // 重置接收缓冲区 memset(rs232_uart_handle.receive_buffer, 0, sizeof(rs232_uart_handle.receive_buffer)); HAL_UART_Receive_DMA(&huart1, (uint8_t *)rs232_uart_handle.receive_buffer, RX_BUFFER_SIZE); } } }
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
评论(0)