ESP32外设学习部分--UART篇

前言

在我们学习嵌入式的过程中,uart算是我们用的非常多的一个外设了,我们可以用串口打印信息,也可以用于设备通信,总之串口的作用非常多,我们也非常有必要熟练地去掌握这个外设。

uart的配置

uart的参数配置

    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,

    };

还是和上一篇我们学习SPI一样,首先需要配置uart的基本参数,像这些参数我们在学习STM32或者其他单片机的时候应该都比较熟悉了,只需要根据我们项目的需求进行配置就OK了。

esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_config)

配置完成之后使用上面的函数进行设置即可。

安装 uart驱动

esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_buffer_size, int event_queue_size, QueueHandle_t *uart_queue, int intr_alloc_flags)

uart_driver_install 是ESP-IDF中用于安装UART驱动程序的函数,它为UART驱动程序分配所需的内部资源,包括环形缓冲区和事件队列。以下是该函数的作用和使用方法:

作用

  • 分配UART驱动程序所需的内部资源,包括Tx(发送)和Rx(接收)的环形缓冲区。
  • 创建一个事件队列,用于处理UART事件,如数据接收、缓冲区溢出等。
  • 允许UART驱动程序使用中断,提高数据传输的效率和响应性。

使用方法

使用uart_driver_install函数时,需要指定以下参数:

  1. uart_num:指定UART端口号,例如UART_NUM_1UART_NUM_2
  2. rx_buffer_size:接收环形缓冲区的大小。
  3. tx_buffer_size:发送环形缓冲区的大小。
  4. event_queue_size:事件队列的大小,用于存储UART事件。
  5. uart_queue:指向队列句柄的指针,用于存储UART事件。
  6. flags:标志位,用于指定是否需要中断等。

这里我们可以使用他的uart事件,这样更加方便我们编程,这里我使用读取超时的(timeout_flag)的标志,这个就类似触发我们STM32中的空闲接收,代表数据已经接收完成我们可以进行处理。

ESP_ERROR_CHECK(uart_driver_install(ECHO_UART_PORT_NUM, BUF_SIZE * 2, BUF_SIZE * 2, 20, &uart1_queue, intr_alloc_flags));

引脚配置

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)

最后使用上面的函数配置我们的引脚即可。

完整代码

#define TAG "tx_usart"

#define ECHO_TEST_TXD (21)

#define ECHO_TEST_RXD (22)

  
  

#define ECHO_UART_PORT_NUM      (1)

#define ECHO_UART_BAUD_RATE     (115200)

  

#define BUF_SIZE (1024)

  

static QueueHandle_t uart1_queue;

  

void tx_usart_init(void)

{

    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;

    uint8_t timer_cnt = 0;

    ESP_ERROR_CHECK(uart_driver_install(ECHO_UART_PORT_NUM, BUF_SIZE * 2, BUF_SIZE * 2, 20, &uart1_queue, 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, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));

  

    uart_event_t event;

    // Configure a temporary buffer for the incoming data

    uint8_t *data = (uint8_t *) malloc(BUF_SIZE);

   while (1) {

        // Read data from the UART

        //Waiting for UART event.

        if(xQueueReceive(uart1_queue, (void * )&event, (TickType_t)0)) {

            /*以此判断一帧数据传输完成*/

                if(event.timeout_flag)

                {

                    ESP_LOGI(TAG,"Recv TimeOUT");

                }

                xQueueReset(uart1_queue);

        }

        int len = uart_read_bytes(ECHO_UART_PORT_NUM, data, (BUF_SIZE - 1), 0);

        // Write data back to the UART

        uart_write_bytes(ECHO_UART_PORT_NUM, (const char *) data, len);

  

         vTaskDelay(10 / portTICK_PERIOD_MS);

  

    }

}
注释以下每一行代码#include "bflb_mtimer.h" #include "bflb_uart.h" #include "bflb_clock.h" #include "board.h" struct bflb_device_s *uartx; void uart_isr(int irq, void *arg) { uint32_t intstatus = bflb_uart_get_intstatus(uartx); int ret; uint32_t baudrate; if (intstatus & UART_INTSTS_RX_AD5) { bflb_uart_int_clear(uartx, UART_INTCLR_RX_AD5); ret = bflb_uart_feature_control(uartx, UART_CMD_GET_AUTO_BAUD, UART_AUTO_BAUD_0X55); baudrate = bflb_clk_get_peripheral_clock(BFLB_DEVICE_TYPE_UART, uartx->idx) / (ret + 1); printf("Detected baudrate by 0x55 is %d\r\n", baudrate); } if (intstatus & UART_INTSTS_RX_ADS) { bflb_uart_int_clear(uartx, UART_INTCLR_RX_ADS); ret = bflb_uart_feature_control(uartx, UART_CMD_GET_AUTO_BAUD, UART_AUTO_BAUD_START); baudrate = bflb_clk_get_peripheral_clock(BFLB_DEVICE_TYPE_UART, uartx->idx) / (ret + 1); printf("Detected baudrate by startbit is %d\r\n", baudrate); } } int main(void) { board_init(); board_uartx_gpio_init(); uartx = bflb_device_get_by_name(DEFAULT_TEST_UART); struct bflb_uart_config_s cfg; cfg.baudrate = 2000000; cfg.data_bits = UART_DATA_BITS_8; cfg.stop_bits = UART_STOP_BITS_1; cfg.parity = UART_PARITY_NONE; cfg.flow_ctrl = 0; cfg.tx_fifo_threshold = 7; cfg.rx_fifo_threshold = 7; bflb_uart_init(uartx, &cfg); bflb_uart_feature_control(uartx, UART_CMD_SET_AUTO_BAUD, 1); bflb_uart_feature_control(uartx, UART_CMD_SET_ABR_ALLOWABLE_ERROR, 3); bflb_irq_attach(uartx->irq_num, uart_isr, NULL); bflb_irq_enable(uartx->irq_num); while (1) { } }
05-15
这段代码是一个用于检测串口波特率的程序。具体解释如下: 1. `#include "bflb_mtimer.h"`、`#include "bflb_uart.h"`、`#include "bflb_clock.h"`、`#include "board.h"` 为头文件的引用,用于包含程序中需要使用的库。 2. `struct bflb_device_s *uartx;` 定义一个结构体指针变量 `uartx`,用于指向串口设备。 3. `void uart_isr(int irq, void *arg)` 为一个中断服务函数,用于响应串口接收中断。 4. `int main(void)` 是程序主函数,程序从这里开始执行。 5. `board_init();` 是对板子进行初始化。 6. `board_uartx_gpio_init();` 是对板子上的 UART 进行初始化。 7. `uartx = bflb_device_get_by_name(DEFAULT_TEST_UART);` 通过 `bflb_device_get_by_name()` 函数获取默认的 UART 设备并将其赋值给 `uartx` 变量。 8. `struct bflb_uart_config_s cfg;` 定义一个结构体变量 `cfg`,用于存储 UART配置信息。 9. `cfg.baudrate = 2000000;` 设置波特率为 2000000。 10. `cfg.data_bits = UART_DATA_BITS_8;` 设置数据位为 8 位。 11. `cfg.stop_bits = UART_STOP_BITS_1;` 设置停止位为 1 位。 12. `cfg.parity = UART_PARITY_NONE;` 设置校验位为无。 13. `cfg.flow_ctrl = 0;` 关闭流控制。 14. `cfg.tx_fifo_threshold = 7;` 设置发送 FIFO 的阈值。 15. `cfg.rx_fifo_threshold = 7;` 设置接收 FIFO 的阈值。 16. `bflb_uart_init(uartx, &cfg);` 初始化 UART 设备。 17. `bflb_uart_feature_control(uartx, UART_CMD_SET_AUTO_BAUD, 1);` 打开自动波特率检测功能。 18. `bflb_uart_feature_control(uartx, UART_CMD_SET_ABR_ALLOWABLE_ERROR, 3);` 设置自动波特率检测允许误差范围为 3。 19. `bflb_irq_attach(uartx->irq_num, uart_isr, NULL);` 注册 UART 接收中断服务函数。 20. `bflb_irq_enable(uartx->irq_num);` 使能 UART 接收中断。 21. `while (1) { }` 是一个死循环,用于等待中断事件的触发。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值