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);

}

}

}
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。