当前位置: 首页 > news >正文

esp32s3中使用串口中断事件消息队列的方式接收数据

在esp32芯片中接收串口数据有多种方式,默认采用串口轮询读取方式效率低下,

通常像51或stm32基于中断的方式对于esp32这种与rtos深度融合的系统来说会降低系统的

实时性,所以可以采用freertos的事件上报的消息队列方式会提高系统的性能。

使用串口1监听数据到来事件再立即读取缓冲区。

#ifndef __BOARD_UART1_H__ #define __BOARD_UART1_H__ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_system.h" #include "esp_log.h" #include "driver/uart.h" #include "string.h" #include "driver/gpio.h" #include "freertos/queue.h" static const char *UART1_TAG = "uart1_events"; #define RX_BUF_SIZE (1024) #define UART_NUM_1 (1) #define TXD_PIN (GPIO_NUM_17) #define RXD_PIN (GPIO_NUM_18) #define EX_UART_NUM UART_NUM_1 #define PATTERN_CHR_NUM (3) #define RD_BUF_SIZE (RX_BUF_SIZE) static QueueHandle_t uart1_queue; #define UART1_QUEUE_SIZE (30) /** * 枚举uart_event_type_t 环形缓冲区中使用的UART事件类型。值: 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_PATTERN_DET 检测到UART模式 UART_EVENT_MAX UART事件最大索引 */ static inline void uart1_init(void) { const uart_config_t uart_config = { .baud_rate = 115200, .data_bits = UART_DATA_8_BITS, .parity = UART_PARITY_DISABLE, .stop_bits = UART_STOP_BITS_1, .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, .source_clk = UART_SCLK_DEFAULT, }; uart_driver_install(EX_UART_NUM, RX_BUF_SIZE * 2, 0,UART1_QUEUE_SIZE,&uart1_queue, 0); uart_param_config(EX_UART_NUM, &uart_config); uart_set_pin(EX_UART_NUM, TXD_PIN, RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); //Set uart pattern detect function. uart_enable_pattern_det_baud_intr(EX_UART_NUM, '+', PATTERN_CHR_NUM, 9, 0, 0); //Reset the pattern queue length to record at most 20 pattern positions. uart_pattern_queue_reset(EX_UART_NUM, UART1_QUEUE_SIZE); } static inline void uart1_send(unsigned char*data,int len) { int offset = 0; int txbytes = 0; while(len > 0) { txbytes = uart_write_bytes(EX_UART_NUM, data + offset, len); offset += txbytes; len -= txbytes; } } #endif /////////////////////////////////////////////////////////////////

事件队列任务

static void uart1_event_task(void *pvParameters) { uart_event_t event; size_t buffered_size; uint8_t* dtmp = (uint8_t*) malloc(RD_BUF_SIZE); for(;;) { //Waiting for UART event. if(xQueueReceive(uart1_queue, (void * )&event, (TickType_t)portMAX_DELAY)) { //bzero(dtmp, RD_BUF_SIZE); //ESP_LOGI(UART1_TAG, "uart[%d] event:", EX_UART_NUM); switch(event.type) { //Event of UART receving data /*We'd better handler data event fast, there would be much more data events than other types of events. If we take too much time on data event, the queue might be full.*/ case UART_DATA: //ESP_LOGI(UART1_TAG, "[UART DATA]: %d", event.size); uart_read_bytes(EX_UART_NUM, dtmp, event.size, portMAX_DELAY); //ESP_LOGI(UART1_TAG, "[DATA EVT]:"); //uart_write_bytes(EX_UART_NUM, (const char*) dtmp, event.size); print0x(dtmp,event.size); break; //Event of HW FIFO overflow detected case UART_FIFO_OVF: ESP_LOGI(UART1_TAG, "hw fifo overflow"); // If fifo overflow happened, you should consider adding flow control for your application. // The ISR has already reset the rx FIFO, // As an example, we directly flush the rx buffer here in order to read more data. uart_flush_input(EX_UART_NUM); xQueueReset(uart1_queue); break; //Event of UART ring buffer full case UART_BUFFER_FULL: ESP_LOGI(UART1_TAG, "ring buffer full"); // If buffer full happened, you should consider increasing your buffer size // As an example, we directly flush the rx buffer here in order to read more data. uart_flush_input(EX_UART_NUM); xQueueReset(uart1_queue); break; //Event of UART RX break detected case UART_BREAK: ESP_LOGI(UART1_TAG, "uart rx break"); break; //Event of UART parity check error case UART_PARITY_ERR: ESP_LOGI(UART1_TAG, "uart parity error"); break; //Event of UART frame error case UART_FRAME_ERR: ESP_LOGI(UART1_TAG, "uart frame error"); break; //UART_PATTERN_DET case UART_PATTERN_DET: uart_get_buffered_data_len(EX_UART_NUM, &buffered_size); int pos = uart_pattern_pop_pos(EX_UART_NUM); ESP_LOGI(UART1_TAG, "[UART PATTERN DETECTED] pos: %d, buffered size: %d", pos, buffered_size); if (pos == -1) { // There used to be a UART_PATTERN_DET event, but the pattern position queue is full so that it can not // record the position. We should set a larger queue size. // As an example, we directly flush the rx buffer here. uart_flush_input(EX_UART_NUM); } else { uart_read_bytes(EX_UART_NUM, dtmp, pos, 100 / portTICK_PERIOD_MS); uint8_t pat[PATTERN_CHR_NUM + 1]; memset(pat, 0, sizeof(pat)); uart_read_bytes(EX_UART_NUM, pat, PATTERN_CHR_NUM, 100 / portTICK_PERIOD_MS); ESP_LOGI(UART1_TAG, "read data: %s", dtmp); ESP_LOGI(UART1_TAG, "read pat : %s", pat); } break; //Others default: ESP_LOGI(UART1_TAG, "uart event type: %d", event.type); break; } } } free(dtmp); dtmp = NULL; vTaskDelete(NULL); } xTaskCreate(uart1_event_task, "uart1_event_task", 4096, NULL, UART1_EVENT_TASK_PRIORITY, NULL);
http://www.jsqmd.com/news/614399/

相关文章:

  • 河道泄洪预警广播系统解决方案详解
  • 单片机世界探秘:09 听懂模拟世界的声音——ADC模拟采集全攻略!
  • 3大技术突破:COMET如何重塑机器翻译质量评估标准
  • 终极指南:如何用虎符台轻松管理全面战争MOD,告别游戏崩溃烦恼
  • 【GraalVM企业级落地红皮书】:金融级静态镜像构建规范(含SBOM生成、符号表剥离、RPM签名、CVE自动扫描闭环)
  • OpenSSF Scorecard安全策略检查:保护代码仓库的终极完整指南
  • 微软2026年Win11路线图梳理:18项关键改进,重塑用户体验
  • 2026届必备的六大AI辅助论文神器横评
  • 如何在Navicat中连接MySQL_基础连接与参数配置
  • PHP异步编程生死线(Swoole/ReactPHP/Laravel Octane选型终极决策图谱)
  • 如何快速无损转换B站缓存视频:终极m4s转MP4指南
  • Windows本地开发环境连接云端RWKV7-1.5B-G1A模型服务指南
  • 选择CAXA还是AutoCAD:没有绝对的“最好”,只有“最适合”。
  • MovieGuide快速入门教程:5分钟搭建你的第一个电影APP
  • React - 组件优化、children props 与 render props、错误边界
  • Windows 11终极优化指南:使用Win11Debloat实现系统性能提升
  • 如何快速将B站m4s缓存视频转换为MP4:终极转换工具使用指南
  • ROS2结合cartographer实现高精度激光SLAM建图实战
  • TALL预设与Laravel Jetstream对比:哪个更适合你的项目?
  • Goqu高级查询技巧:窗口函数、子查询、复杂JOIN实战指南
  • 从AlphaFold到GPT:AI for Science大模型技术演进全解析 [特殊字符]
  • 万字拆解 LLM 运行机制:Token、上下文与采样参数举
  • 台达AS系列PLC的Modbus TCP通信C#源代码及生产数据监控与Excel表格生成
  • 揭秘PoeCharm:如何用精准数据构建《流放之路》完美角色?
  • Simditor自定义配置进阶:掌握allowedTags、allowedAttributes等高级选项的终极指南
  • P8087 『JROI-5』Interval 题解
  • PyTorch 张量与自动微分完全指南:从核心概念到实战训练
  • 小白的第一次edusrc挖洞经历分享
  • 掌握nvim-tree.lua正则表达式:5个高级文件过滤技巧让你的Neovim文件管理效率翻倍
  • 如何通过MiPad5-Drivers开源驱动实现跨系统适配?设备转型与性能优化指南