首页 > 其他分享 >记录3:ESP32-C3的串口使用

记录3:ESP32-C3的串口使用

时间:2024-08-10 16:23:24浏览次数:20  
标签:PIN uart ESP32 queue UART num 串口 C3 size

0、前期准备

1、参考首篇文章搭建好esp32环境

2、准备好一块esp32开发开发板(本作者使用了esp32c3作为开发平台)

1、知识储备

1.1 概述

​ UART称为通用异步收发器,可以进行全双工/半双工数据通讯数据通讯,通讯距离取决于上拉驱动能力、波特率,一般只在电路板上使用,如果需要长距离通讯可以外接RS232(最长通讯距离15M)、RS485电平转换芯片,但是要注意如果外接的是RS485电平芯片,只能进行半双工通讯,在理想情况下使用9600波特率,其通讯距离可达1200M。

1.2 功能架构

​ 乐鑫EPS32C3带有2个UART控制器,不仅可以用来进行数据通讯,还能来用驱动红外发射管。(目前本文只用来作uart通讯)

1.3 uart配置流程介绍

LEDC的配置流程可分为以下3步

1、uart配置:设置波特率、数据位、停止位、奇偶校验位和流控

2、引脚绑定:设置UART使用哪几个引脚

3、 注册uart中断驱动(可选–建议进行该配置,本文给出例子就使用该方式)

1、uart配置

uart的配置主要是给 uart_config_t 结构体赋值,然后通过uart_param_config函数进行uart设置

以下对uart_config_t 结构体进行说明

typedef struct {
    int baud_rate;                      //波特率
    uart_word_length_t data_bits;       //数据位
    uart_parity_t parity;               //奇偶校验位
    uart_stop_bits_t stop_bits;         //停止位
    uart_hw_flowcontrol_t flow_ctrl;    //硬件流控
    uint8_t rx_flow_ctrl_thresh;        //硬件流控的RTS阈值
    union {
        uart_sclk_t source_clk;         //时钟源
        bool use_ref_tick  __attribute__((deprecated)); 
    };
} uart_config_t;

例子:

// uart1配置
// 115200 8 1 无奇偶校验位 无流控
uart_config_t uart_conf = {
    .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,
    .source_clk = UART_SCLK_APB,
};

uart_param_config(UART_NUM_1, &uart_conf);
2、引脚绑定

设置UART使用哪几个引脚

esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int rts_io_num, int cts_io_num);
// 参数 :uart_num:串口编号 可查看uart.h,进行选择
//     tx_io_num:发送引脚编号,不需要可填:UART_PIN_NO_CHANGE
//     rx_io_num: 接收引脚编号,不需要可填:UART_PIN_NO_CHANGE
//     rts_io_num:rts引脚编号,不需要可填:UART_PIN_NO_CHANGE
//     cts_io_num:cts引脚编号,不需要可填:UART_PIN_NO_CHANGE

例子:

// 引脚绑定
uart_set_pin(UART_NUM_1, TX_PIN, RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
3、 注册uart中断驱动(配置可选)

通过注册uart中断,可以不用开一个任务实时的去读取串口,判断串口有没有数据发送过来,提高系统实时性。

中断驱动uart_driver_install函数参数说明如下:

esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_buffer_size, int queue_size, QueueHandle_t *uart_queue, int intr_alloc_flags);
// 参数 :uart_num:串口编号 可查看uart.h,进行选择
//     rx_buffer_size:uart接收数组大小
//     tx_buffer_size: uart发送数组大小
//     queue_size: uart接收消息队列大小,和新建的消息队列大小一致
//     uart_queue:uart接收消息队列句柄
//     intr_alloc_flags:中断标志位

例子:

QueueHandle_t uart_queue = NULL;    
uart_queue = xQueueCreate(8, 512);
uart_driver_install(UART_PORT, RX_BUFF_SIZE, RX_BUFF_SIZE, 8, &uart_queue, 0);
4、 其他函数

本文只介绍发送和接收两个函数,更多函数可参考乐鑫官网

int uart_read_bytes(uart_port_t uart_num, void *buf, uint32_t length, TickType_t ticks_to_wait);
//参数 : uart_num:串口编号 可查看uart.h,进行选择
//       buf:接收数组名
//       length:接收到的数据长度
//       ticks_to_wait:读取等待的RTOS 滴答个数
//返回 : -1:表示错误
//      其他:表示从uart的接收fifo读取到的数据

int uart_write_bytes(uart_port_t uart_num, const void *src, size_t size);
//参数 : uart_num:串口编号 可查看uart.h,进行选择
//       src:发送数组名
//       size:发送的数据长度
//返回 : -1:表示错误
//      其他:表示uart发送给发送fifo的数据

2、新建工程

idf.py create-project project_uart # 新建工程
cd project_uart
idf.py set-target esp32c3 # 设置工程使用的芯片

2、查看原理图确定uart引脚

3、编写程序

#include <freertos/FreeRTOS.h>
#include <freertos/queue.h>
#include <freertos/task.h>

#include <driver/gpio.h>
#include <driver/uart.h>
#include <esp_log.h>

#include <string.h>

#define LOG_EVENT_TAG "uart"

QueueHandle_t uart_queue = NULL;

#define RX_BUFF_SIZE 1024

#define UART_PORT UART_NUM_2
#define RX_PIN GPIO_NUM_13
#define TX_PIN GPIO_NUM_15

uint8_t uart_buff[RX_BUFF_SIZE];

void UartEventHandle(void* param);

void init_uart(void) {
    uart_config_t uart_conf = {
        .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,
        .source_clk = UART_SCLK_APB,
    };

    uart_param_config(UART_PORT, &uart_conf);
    uart_set_pin(UART_PORT, TX_PIN, RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);

    uart_queue = xQueueCreate(8, 512);
    uart_driver_install(UART_PORT, RX_BUFF_SIZE, RX_BUFF_SIZE, 8, &uart_queue, 0);

    xTaskCreate(UartEventHandle, "uart_event_hanle", 1024, NULL, 5, NULL);
}

void UartEventHandle(void* param) {
    uart_event_t event;
    memset(&uart_data, 0, sizeof(UartData));
    uart_data.rx_status = pdFALSE;
    while (pdTRUE) {
        if (xQueueReceive(uart_queue, (void*)&event, portMAX_DELAY)) {
            switch (event.type) {
                case UART_DATA:
                    memset(&uart_data, 0, sizeof(UartData));
                    uart_data.rx_status = pdFALSE;
                    if (event.size <= sizeof(uart_data.buff)) {
                        uart_data.rx_status = pdTRUE;
                        uart_data.rx_uart_len = event.size;
                        uart_read_bytes(UART_PORT, uart_buff, event.size, portMAX_DELAY);
                        ESP_LOGI(LOG_EVENT_TAG, "uart_buff: %s", uart_buff);
                    }

                    break;
                case UART_FIFO_OVF:
                case UART_BUFFER_FULL:
                    uart_flush_input(UART_PORT);
                    xQueueReset(uart_queue);
                    break;
                default:
                    ESP_LOGI(LOG_EVENT_TAG, "uart event type: %d", event.type);
                    break;
            }
        }
    }
}

void app_main(void) {
    init_uart();

    while (1) {
        vTaskDelay(1000 / portTICK_RATE_MS);
    }
}



4、编译下载

# 编译
idf.py build
# 烧录
idf.py -p /dev/ttyUSB0 flash monitor

标签:PIN,uart,ESP32,queue,UART,num,串口,C3,size
From: https://blog.csdn.net/qq_28695769/article/details/141054479

相关文章

  • STM32 虚拟串口发不出数据
    在某个项目上,使用到了USB虚拟串口功能,芯片是STM32F105,在芯片刚复位时功能是正常,但是多发几次数据后,就发不出去了,一直返回USBD_BUSY,在下图中的344行返回USBD_BUSY解决办法是在这个函数内增加一些代码,等待数据发送完成之后再退出,或者超时退出,超时时间可以自己调整,根据自己的使......
  • proteus 中单片机串口仿真实验
    位置:                    连线如图:问题解决在进行仿真的时候,可能不会出现terminal显示框,可以在菜单栏debug->virtualterminal来让它显示:如果visualterminal显示的是乱码,我们就需要根据实际情况修改单片机时钟频率,双击单片机,在......
  • 【题解】ABC365(A~E)
    前四题30min切,然后T5死磕70min+几发小唐错,距离比赛结束还有16s交最后一发,AC了。目录A.LeapYear题目描述思路代码B.SecondBest题目描述思路代码C.TransportationExpenses题目描述思路代码D.AtCoderJanken3题目描述思路代码E.XorSigmaProblem题目描述思路代码A.Lea......
  • ABC349D题解
    [ABC349D]DivideInterval题解传送门:luogu|atcoder题目简述给定非负整数\(l\)和\(r\)(\(l<r\)),令\(S(l,r)\)表示序列\((l,l+1,\ldots,r-2,r-1)\),其中包含从\(l\)到\(r-1\)的所有整数。此外,一个序列被称为“好序列”,当且仅当它可以表示为\(S(2^ij,2^{i}(j+1))\),......
  • ABC349D题解
    [ABC349D]DivideInterval题解传送门:luogu|atcoder题目简述给定非负整数$l$和$r$($l<r$),令$S(l,r)$表示序列$(l,l+1,\ldots,r-2,r-1)$,其中包含从$l$到$r-1$的所有整数。此外,一个序列被称为“好序列”,当且仅当它可以表示为$S(2^ij,2^{i}(j+1))$,其中$i$和$j$......
  • python3如何使用‘pexpect’自动与串口交互?
    如何在Windows中使用python'pexpect'自动与串口(例如:COM3)交互并在开机时通过串口登录嵌入式开发板时输入用户密码?ser=serial.Serial(port=serial_port,baudrate=baudrate,bytesize=bytesize,parity=parity,stopbits=stopbits,timeout=timeout)channel=pexpect.fdpexp......
  • 如何把Connection 封装到工具类里面 调用工具类方法实现 增删改查操作 java JDBC使用
    如何把Connection封装到工具类里面调用工具类方法实现增删改查操作javaJDBC使用C3P0数据库连接池答:当使用C3P0作为数据库连接池时,你可以按照类似的模式来配置和使用它。以下是一个示例,展示了如何在Java项目中配置C3P0连接池,并创建一个工具类来管理数据库连接和执行基本的......
  • ABC365F Takahashi on Grid 题解
    ##题目大意有一个网格图,对于$i=1,2,\dotsn$,第$i$列的$[L_i,U_i]$上的单元格是可到达的,形如下面这张图。![](https://img.atcoder.jp/abc365/4d07a40c98eda33ee86b773e564681c7.png)图中对于$i=1,2,\dots7$,$[L_i,U_i]$分别为:```15331311142435```......
  • ESP8266串口
    Serial.print(val)–串口输出数据并。Serial.println(val)–串口输出数据并换行。Serial.available()–判断串口缓冲区的状态,返回从串口缓冲区读取的字节数。Serial.read()–读取串口数据,一次读一个字符,读完后删除已读数据。当没有可读数据时返回-1,整数类型。Serial.readB......
  • esp32安装circuitpython
    安装Thonnyhttps://thonny.org/在Thonny中安装circuitpython在配置解释器中选择circuitython然后点击右下角“安装或更新...“variant这里我选择了DOITesp32DevelopmentBoard(试过其他的一些个,不知道为什么安装完之后会无限重启,所以最后选择了这个)烧录完之后,重新连接,Th......