主页 > 互联网 > 内容页

[esp32教程] 5、UART使用

2023-06-13 09:18:06 来源:板凳说

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_uartidf.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_1#define TX_PIN GPIO_NUM_0uint8_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);    }}

审核编辑:汤梓红

标签:

上一篇:【Linux篇】mosquttio移植到Ubuntu 焦点滚动
下一篇:最后一页