
不直接在ISR程序中处理中断,利用分配资源函数,传递一个消息队列,进行保存中断类型,再通过任务进行处理对应的中断
专用包装中带:封装好的一个中断,利用rtos任务来响应中断
在ESP32------关于UART(串口)的使用(1)这篇文章中,通过 uart_driver_install 方法安装一个串口驱动来分配资源,同时也注册了一个中断,其中一个参数就是 消息队列

通过在任务中接收消息队列,根据消息队列中的值,判断当前串口的中断类型,然后再进行处理;Ps:这个消息队列的值是 uart_event_t类型的
枚举器UART_DATA
UART数据事件枚举器UART_BREAK
UART中断事件枚举器UART_BUFFER_FULL
UART RX缓冲区已满事件枚举器UART_FIFO_OVF
UART FIFO溢出事件枚举器UART_FRAME_ERR
UART RX帧错误事件枚举器UART_PARITY_ERR
UART RX奇偶校验事件枚举器UART_DATA_BREAK
UART TX数据和中断事件枚举器UART_PATTER_DET
检测到UART模式枚举器UART_EVENT_MAX
UART事件最大索引参考代码
/// @brief 串口2的事件检测 /// @param param void Uart2_Test_Task( void *param ) { uart_event_t my_event; char buffer[128]; char* test_str = "This is a uart2 data \n"; char* test_str1 = "This is uart2 break \n"; char* buffer_full = "buffer is full \n"; while (1) { if (xQueueReceive(uart2_queue,&my_event,10)) { switch (my_event.type) { /*================================================================================ 数据事件:最好要快速处理,因为数据事件比其他类型多得多,不及时就会导致,队列满了,错过其他 事件 ================================================================================*/ case UART_DATA: //接收到数据,或则说是串口有数据传输? uart_write_bytes(UART_NUM_2, (const char*)test_str,22); break; /*================================================================================ 中断事件:没搞懂!! ================================================================================*/ case UART_BREAK: uart_write_bytes(UART_NUM_2, (const char*)test_str1,strlen(test_str1)); break; /*================================================================================ 接收缓冲区溢出:如果缓冲区已满,则应考虑增加缓冲区大小 例如,为了读取更多的数据,我们在这里直接刷新rx缓冲区。 ================================================================================*/ case UART_BUFFER_FULL: uart_write_bytes(UART_NUM_2, (const char*)buffer_full,strlen(buffer_full)); uart_flush_input(UART_NUM_2); xQueueReset(uart2_queue); break; /*================================================================================ FIFO溢出:则应考虑流控制,为了读取更多的数据,我们在这里直接刷新rx缓冲区。 ================================================================================*/ case UART_FIFO_OVF: uart_flush_input(UART_NUM_2); xQueueReset(uart2_queue); break; default: break; } } // vTaskDelay(1); } }完整代码
#define Uart2_Tx 17 #define Uart2_Rx 16 #define Uart2_RTS 7 #define Uart2_CTS 8 QueueHandle_t uart2_queue; //串口2的消息队列,z这个消息队列是用来存储中断事件类型的 /// @brief 串口2的事件检测 /// @param param void Uart2_Test_Task( void *param ) { uart_event_t my_event; char buffer[128]; char* test_str = "This is a uart2 data \n"; char* test_str1 = "This is uart2 break \n"; char* buffer_full = "buffer is full \n"; while (1) { if (xQueueReceive(uart2_queue,&my_event,10)) { switch (my_event.type) { /*================================================================================ 数据事件:最好要快速处理,因为数据事件比其他类型多得多,不及时就会导致,队列满了,错过其他 事件 ================================================================================*/ case UART_DATA: //接收到数据,或则说是串口有数据传输? uart_write_bytes(UART_NUM_2, (const char*)test_str,22); break; /*================================================================================ 中断事件:没搞懂!! ================================================================================*/ case UART_BREAK: uart_write_bytes(UART_NUM_2, (const char*)test_str1,strlen(test_str1)); break; /*================================================================================ 接收缓冲区溢出:如果缓冲区已满,则应考虑增加缓冲区大小 例如,为了读取更多的数据,我们在这里直接刷新rx缓冲区。 ================================================================================*/ case UART_BUFFER_FULL: uart_write_bytes(UART_NUM_2, (const char*)buffer_full,strlen(buffer_full)); uart_flush_input(UART_NUM_2); xQueueReset(uart2_queue); break; /*================================================================================ FIFO溢出:则应考虑流控制,为了读取更多的数据,我们在这里直接刷新rx缓冲区。 ================================================================================*/ case UART_FIFO_OVF: uart_flush_input(UART_NUM_2); xQueueReset(uart2_queue); break; default: break; } } // vTaskDelay(1); } } /// @brief 串口2的参数配置以及资源分配 /// @param 无 void Uart2_Study_Init( void ) { uart_config_t my_uart={ .baud_rate = 115200, //波特率 .data_bits = UART_DATA_8_BITS, //数据位 .stop_bits = UART_STOP_BITS_1, //停止位 .parity = UART_PARITY_DISABLE, //奇偶校验位 .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, //流控 .rx_flow_ctrl_thresh = 122, //触发流控的阈值 // .source_clk = UART_SCLK_DEFAULT, //设置时钟源 }; //uart_config //设置一个默认的串口,使用串口1 uart_param_config(UART_NUM_2,&my_uart); ///设置了对应的引脚和对应的串口号,因为有可能你并没有使用一些引脚 uart_set_pin(UART_NUM_2,Uart2_Tx,Uart2_Rx,UART_PIN_NO_CHANGE,UART_PIN_NO_CHANGE); ///分配了串口的资源 ,在这里就已经注册了一个idf默认自带的一个中断服务程序 uart_driver_install(UART_NUM_2,1024,1024,10,&uart2_queue,0); //创建一个任务来处理来自ISR的UART事件 xTaskCreate(Uart2_Test_Task,"Uart2_Test_Task",1024,NULL,3,NULL); }其他中断:还没整明白

#好好学习!