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)