ESP32-C3第二路串口(非调试)串口打通(4)

接前一篇文章:ESP32-C3第二路串口(非调试)串口打通(3)

本文内容参考:

基于 esp-idf 的 UART 应用例程解读_uart asynchronous example with separate receive an-CSDN博客

特此致谢!

上一回对于FreeRTOS中的“创建和删除任务类”函数进行了讲解,并最终讲到了app_main主函数中通过xTaskCreate函数创建的任务函数echo_task。本回对于该函数进行详细解析。

3. 工程代码详解

(1)main\uart_echo_example_main.c

  • echo_task函数

再次贴出echo_task函数源码:

static void echo_task(void *arg)
{/* Configure parameters of an UART driver,* communication pins and install the driver */uart_config_t uart_config = {.baud_rate = ECHO_UART_BAUD_RATE,.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,};int intr_alloc_flags = 0;#if CONFIG_UART_ISR_IN_IRAMintr_alloc_flags = ESP_INTR_FLAG_IRAM;
#endifESP_ERROR_CHECK(uart_driver_install(ECHO_UART_PORT_NUM, BUF_SIZE * 2, 0, 0, NULL, intr_alloc_flags));ESP_ERROR_CHECK(uart_param_config(ECHO_UART_PORT_NUM, &uart_config));ESP_ERROR_CHECK(uart_set_pin(ECHO_UART_PORT_NUM, ECHO_TEST_TXD, ECHO_TEST_RXD, ECHO_TEST_RTS, ECHO_TEST_CTS));// Configure a temporary buffer for the incoming datauint8_t *data = (uint8_t *) malloc(BUF_SIZE);while (1) {// Read data from the UARTint len = uart_read_bytes(ECHO_UART_PORT_NUM, data, (BUF_SIZE - 1), 20 / portTICK_PERIOD_MS);// Write data back to the UARTuart_write_bytes(ECHO_UART_PORT_NUM, (const char *) data, len);if (len) {data[len] = '\0';ESP_LOGI(TAG, "Recv str: %s", (char *) data);}}
}

一段一段来解析。

1)代码片段1

先来看第1段代码:

    /* Configure parameters of an UART driver,* communication pins and install the driver */uart_config_t uart_config = {.baud_rate = ECHO_UART_BAUD_RATE,.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_config_t的定义在C:\Espressif\frameworks\esp-idf-v5.2.1\components\driver\uart\include\driver\uart.h中,代码如下:

/*** @brief UART configuration parameters for uart_param_config function*/
typedef struct {int baud_rate;                      /*!< UART baud rate*/uart_word_length_t data_bits;       /*!< UART byte size*/uart_parity_t parity;               /*!< UART parity mode*/uart_stop_bits_t stop_bits;         /*!< UART stop bits*/uart_hw_flowcontrol_t flow_ctrl;    /*!< UART HW flow control mode (cts/rts)*/uint8_t rx_flow_ctrl_thresh;        /*!< UART HW RTS threshold*/union {uart_sclk_t source_clk;             /*!< UART source clock selection */
#if (SOC_UART_LP_NUM >= 1)lp_uart_sclk_t lp_source_clk;       /*!< LP_UART source clock selection */
#endif};
} uart_config_t;

其实不外乎就是串口那点事儿:波特率是多少、几位数据位、几位停止位、是否带奇偶校验、是否有流控等。经常使用串口的人应该对于这些设置项很熟悉了。

这里:

波特率为ECHO_UART_BAUD_RATE,其定义在同文件(main\uart_echo_example_main.c)中,如下:

#define ECHO_UART_BAUD_RATE     (CONFIG_EXAMPLE_UART_BAUD_RATE)

而CONFIG_EXAMPLE_UART_BAUD_RATE的定义在build\config\sdkconfig.h中,(当前配置)如下:

#define CONFIG_EXAMPLE_UART_BAUD_RATE 115200

即波特率为115200。

数据位为UART_DATA_8_BITS,即8位数据位。UART_DATA_8_BITS的定义在C:\Espressif\frameworks\esp-idf-v5.2.1\components\hal\include\hal\uart_types.h中,如下:

/*** @brief UART word length constants*/
typedef enum {UART_DATA_5_BITS   = 0x0,    /*!< word length: 5bits*/UART_DATA_6_BITS   = 0x1,    /*!< word length: 6bits*/UART_DATA_7_BITS   = 0x2,    /*!< word length: 7bits*/UART_DATA_8_BITS   = 0x3,    /*!< word length: 8bits*/UART_DATA_BITS_MAX = 0x4,
} uart_word_length_t;

停止位为UART_STOP_BITS_1,即1位停止位。UART_STOP_BITS_1的定义在C:\Espressif\frameworks\esp-idf-v5.2.1\components\hal\include\hal\uart_types.h中,如下:

/*** @brief UART stop bits number*/
typedef enum {UART_STOP_BITS_1   = 0x1,  /*!< stop bit: 1bit*/UART_STOP_BITS_1_5 = 0x2,  /*!< stop bit: 1.5bits*/UART_STOP_BITS_2   = 0x3,  /*!< stop bit: 2bits*/UART_STOP_BITS_MAX = 0x4,
} uart_stop_bits_t;

奇偶校验方式为UART_PARITY_DISABLE,即不使能奇偶校验。UART_PARITY_DISABLE的定义在C:\Espressif\frameworks\esp-idf-v5.2.1\components\hal\include\hal\uart_types.h中,如下:

/*** @brief UART parity constants*/
typedef enum {UART_PARITY_DISABLE  = 0x0,  /*!< Disable UART parity*/UART_PARITY_EVEN     = 0x2,  /*!< Enable UART even parity*/UART_PARITY_ODD      = 0x3   /*!< Enable UART odd parity*/
} uart_parity_t;

流控方式为UART_HW_FLOWCTRL_DISABLE,即不使用流控。UART_HW_FLOWCTRL_DISABLE的定义在C:\Espressif\frameworks\esp-idf-v5.2.1\components\hal\include\hal\uart_types.h中,如下:

/*** @brief UART hardware flow control modes*/
typedef enum {UART_HW_FLOWCTRL_DISABLE = 0x0,   /*!< disable hardware flow control*/UART_HW_FLOWCTRL_RTS     = 0x1,   /*!< enable RX hardware flow control (rts)*/UART_HW_FLOWCTRL_CTS     = 0x2,   /*!< enable TX hardware flow control (cts)*/UART_HW_FLOWCTRL_CTS_RTS = 0x3,   /*!< enable hardware flow control*/UART_HW_FLOWCTRL_MAX     = 0x4,
} uart_hw_flowcontrol_t;

时钟源为UART_SCLK_DEFAULT。UART_SCLK_DEFAULT的定义在C:\Espressif\frameworks\esp-idf-v5.2.1\components\soc\esp32c3\include\soc\clk_tree_defs.h中,

/*** @brief Type of UART clock source, reserved for the legacy UART driver*/
typedef enum {UART_SCLK_APB = SOC_MOD_CLK_APB,     /*!< UART source clock is APB CLK */UART_SCLK_RTC = SOC_MOD_CLK_RC_FAST, /*!< UART source clock is RC_FAST */UART_SCLK_XTAL = SOC_MOD_CLK_XTAL,   /*!< UART source clock is XTAL */UART_SCLK_DEFAULT = SOC_MOD_CLK_APB, /*!< UART source clock default choice is APB */
} soc_periph_uart_clk_src_legacy_t;

即UART(串口)的时钟源来自于APB总线,这也是默认的设置。

总体上,进行以上设置后,就相当于在串口调试助手中进行以下设置:

2)代码片段2

接下来是与intr_alloc_flags相关的代码片段:

    int intr_alloc_flags = 0;#if CONFIG_UART_ISR_IN_IRAMintr_alloc_flags = ESP_INTR_FLAG_IRAM;
#endif

intr_alloc_flagsUART中断优先级设置标志。对应于menuconfig中的“Place UART ISR function into IRAM”配置选项,0表示未使能,1表示使能。

如果不选择此选项,UART中断将长时间禁用并且在进行SPI FLASH操作时可能会导致数据丢失。

3)代码片段3

接下来是与UART配置和设置相关的代码片段:

    ESP_ERROR_CHECK(uart_driver_install(ECHO_UART_PORT_NUM, BUF_SIZE * 2, 0, 0, NULL, intr_alloc_flags));ESP_ERROR_CHECK(uart_param_config(ECHO_UART_PORT_NUM, &uart_config));ESP_ERROR_CHECK(uart_set_pin(ECHO_UART_PORT_NUM, ECHO_TEST_TXD, ECHO_TEST_RXD, ECHO_TEST_RTS, ECHO_TEST_CTS));

这一段代码涉及到的内容较多,因此对于这一段代码的详细解析,放在下一回中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/5099.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

品深茶的抗癌效果怎么样?

茶叶中的一些成分&#xff0c;如茶多酚、儿茶素等&#xff0c;具有抗氧化和抗炎作用&#xff0c;这些作用在一定程度上可以抑制癌细胞的生长和扩散。 然而&#xff0c;这些成分在茶叶中的含量和生物利用率会受到多种因素的影响&#xff0c;如茶叶的品种、制作工艺、饮茶方式等…

我开源了一款阿里云OSS的spring-boot-starter

在上一篇文章中我们介绍了如何使用SpringBoot集成阿里云oss&#xff1a; 什么&#xff01;没有Starter的阿里云OSS也能集成到SpringBoot&#xff1f; 但是这个方式还是需要自己去写配置类去配置很多的东西&#xff0c;那么我在想&#xff0c;为什么不自己写一个阿里云OSS的spri…

K8s: Prometheus 服务结构以及基础抓取数据服务部署

Prometheus 发布应用之后&#xff0c;就有持续运维的事情&#xff0c;就是平台监控Prometheus 是一个云原生的日志监控平台&#xff0c;是一个实时标准的一个技术它是著名的 cncf 里的一个重要的开源项目 上面整个图片是在云原生应用及K8s应用架构下的一个日志监控的一个标准的…

杰发科技AC7840——SPI通信简介(1)_跑通Demo

0. 简介 一些配置项&#xff1a; CPHA&#xff1a;相序 CPLO&#xff1a;极性 看着demo需要按键&#xff0c;于是去掉按键&#xff0c;去掉打印&#xff0c;直接输出波形看逻辑分析仪的信号。 其实现在做这些demo测试应该都有逻辑分析仪&#xff0c;直接看波形更直观一点。…

【C 数据结构】图的存储结构

文章目录 【 1. 图的顺序存储结构 】1.1 基本原理1.2 顺序存储结构的 C 实现 【 2. 图的链式存储结构 】2.1 图的临接表存储结构2.1.1 临接表的 基本原理2.1.2 临接表的 链表节点2.1.3 邻接表 各结构体的C实现2.1.4 临接表 计算顶点的出度和入度邻接表计算 无向图的出度和入度邻…

一款可视化正则表达式工具

regex-vis是一款在线免费且可视化的正则表达式工具 界面图&#xff1a; 只能输入由26个英文字母组成的字符串 ^[A-Za-z]$ 只能输入数字 ^[0-9]*$测试错误 测试正确 快来感受一下叭 官方网址&#xff1a; Regex VisRegex visualizer & editor, make the regular expr…

小红书聚光里的流量洼地:N个百万级别的捡钱机会

小红书聚光里的流量洼地&#xff1a;N个百万级别的捡钱机会 一、前言 在最近的分享会上&#xff0c;笔者主要围绕小红书聚光投流的经验和对其他行业赛道的调研&#xff0c;与大家探讨了小红书的红利机会。在这个竞争激烈的市场中&#xff0c;如何抓住小红书这一流量洼地&…

回溯法——(1)装载问题(C语言讲解)

目录 一、装载问题 1.问题概括&#xff1a; 2.解决方案&#xff08;思路&#xff09;&#xff1a; 3.图片讲解&#xff08;超详细&#xff09;&#xff1a; 4.代码分析&#xff1a; 二、算法改进&#xff1a;引入上界函数 1.问题概念&#xff1a; 2.图片讲解&#xff1a…

【设计模式】工厂方法模式(Factory Method Pattern)

目录标题 工厂方法设计模式详解1. 介绍2. 结构3. 实现步骤3.1 创建抽象产品接口3.2 创建具体产品类3.3 创建抽象工厂接口3.4 创建具体工厂类3.5 客户端使用 4. 好处与优点5. 坏处与缺点6. 适用场景7. 总结 工厂方法设计模式详解 1. 介绍 工厂方法模式是一种创建型设计模式&am…

SpringCloud学习笔记(一)微服务介绍、服务拆分和RestTemplate远程调用、Eureka注册中心

文章目录 1 认识微服务1.1 单体架构1.2 分布式架构1.3 微服务1.4 SpringCloud1.5 总结 2 服务拆分与远程调用2.1 服务拆分原则2.2 服务拆分示例2.2.1 搭建项目2.2.2 创建数据库和表2.2.3 实现远程调用2.2.3.1 需求描述2.2.3.2 注册RestTemplate2.2.3.3 实现远程调用 2.2.4 提供…

strtok,perror,strerror函数·

strtok函数 strtok函数是C语言中的一个字符串函数&#xff0c;用于将一个字符串根据特定的分隔符拆分成多个子字符串。它的函数原型如下&#xff1a; char *strtok(char *str, const char *delim); 在这个函数中&#xff0c;str表示要进行拆分的字符串&#xff0c;delim表示…

Spark01 —— Spark基础

文章目录 Spark01 —— Spark基础一、为什么选择Spark&#xff1f;1.1 MapReduce编程模型的局限性1.2 Spark与MR的区别1.3 版本1.4 优势1.5 Spark其他知识1、多种运行模式2、技术栈3、spark-shell&#xff1a;Spark自带的交互式工具4、Spark服务 二、Spark的基础配置三、Spark实…

Spring-Mybatis-Xml管理(动态sql语句,sql语句复用)

目录 前置条件 动态SQL语句 动态删除数据 1.集合类型:数组 2.集合类型: List 型 SQL语句重用 说明 &#x1f9e8;前置条件 已经创建了实体类(这边举个例子) 实体类User表 表中的字段名User实体类的属性值id (bigint auto increment) 长整型 自动增长private Long iduser…

day17-day20_项目实战项目部署

万信金融 项目部署 目标&#xff1a; 理解DevOps概念 能够使用Docker Compose部署项目 理解持续集成的作用 会使用Jenkins进行持续集成 1 DevOps介绍 1.1 什么是DevOps DevOps是Development和Operations两个词的缩写&#xff0c;引用百度百科的定义&#xff1a; DevOps…

《C语言深度解剖》(10):数组指针、指针数组和数组指针数组

&#x1f921;博客主页&#xff1a;醉竺 &#x1f970;本文专栏&#xff1a;《C语言深度解剖》《精通C指针》 &#x1f63b;欢迎关注&#xff1a;感谢大家的点赞评论关注&#xff0c;祝您学有所成&#xff01; ✨✨&#x1f49c;&#x1f49b;想要学习更多C语言深度解剖点击专栏…

重学java 26.面向对象 内部类⭐

“别担心&#xff0c;你一定能如愿。” —— 24.4.29 1.什么时候使用内部类&#xff1a; 当一个事物的内部&#xff0c;还有一个部分需要完整的结构去描述&#xff0c;而内部的完整结构又只为外部事物提供服务&#xff0c;那么整个内部的完整结构最好使用内部类 比如&#xff1…

人工智能论文:BERT和GPT, GPT-2, GPT-3 的简明对比和主要区别

在BERT的论文里面&#xff1a; 2018.10 BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding&#xff0c;BERT已经解释了BERT&#xff0c;GPT&#xff0c;ELMo的区别。 *ELMo为双向RNN&#xff0c;请忽略。 主要区别&#xff1a; BERT使用的是…

49. 【Android教程】HTTP 使用详解

在你浏览互联网的时候&#xff0c;绝大多数的数据都是通过 HTTP 协议获取到的&#xff0c;也就是说如果你想要实现一个能上网的 App&#xff0c;那么就一定会和 HTTP 打上交道。当然 Android 发展到现在这么多年&#xff0c;已经有很多非常好用&#xff0c;功能非常完善的网络框…

信息系统项目管理师0078:安全系统(5信息系统工程—5.4安全工程—5.4.2安全系统)

点击查看专栏目录 文章目录 5.4.2安全系统1.安全机制2.安全服务3.安全技术5.4.2安全系统 信息安全保障系统一般简称为信息安全系统,它是“信息系统”的一个部分,用于保证“业务应用信息系统”正常运营。现在人们已经明确,要建立一个“信息系统”,就必须要建立一个或多个业务…

hive使用hplsql进行etl或其它数据加工

参照 https://cwiki.apache.org/confluence/pages/viewpage.action?pageId59690156 http://www.hplsql.org/doc Hive HPL/SQL&#xff0c;即Hive Hybrid Procedural SQL一个开源工具&#xff0c;它为hive实现了过程性的SQL功能&#xff0c;类似Oracle的PLSQL。从hive 2.0.0开…