1、参考首篇文章搭建好esp32环境
2、准备好一块esp32开发开发板(本作者使用了esp32c3作为开发平台)
UART称为通用异步收发器,可以进行全双工/半双工数据通讯数据通讯,通讯距离取决于上拉驱动能力、波特率,一般只在电路板上使用,如果需要长距离通讯可以外接RS232(最长通讯距离15M)、RS485电平转换芯片,但是要注意如果外接的是RS485电平芯片,只能进行半双工通讯,在理想情况下使用9600波特率,其通讯距离可达1200M。
乐鑫EPS32C3带有2个UART控制器,不仅可以用来进行数据通讯,还能来用驱动红外发射管。(目前本文只用来作uart通讯)
LEDC的配置流程可分为以下3步
1、uart配置:设置波特率、数据位、停止位、奇偶校验位和流控
2、引脚绑定:设置UART使用哪几个引脚
3、 注册uart中断驱动(可选--建议进行该配置,本文给出例子就使用该方式)
uart的配置主要是给 uart_config_t 结构体赋值,然后通过uart_param_config函数进行uart设置
以下对uart_config_t 结构体进行说明
typedefstruct{intbaud_rate;//波特率uart_word_length_tdata_bits;//数据位uart_parity_tparity;//奇偶校验位uart_stop_bits_tstop_bits;//停止位uart_hw_flowcontrol_tflow_ctrl;//硬件流控uint8_trx_flow_ctrl_thresh;//硬件流控的RTS阈值union{uart_sclk_tsource_clk;//时钟源booluse_ref_tick __attribute__((deprecated)); }; }uart_config_t;
例子:
// uart1配置// 115200 8 1 无奇偶校验位 无流控uart_config_tuart_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);
设置UART使用哪几个引脚
esp_err_tuart_set_pin(uart_port_tuart_num,inttx_io_num,intrx_io_num,intrts_io_num,intcts_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);
通过注册uart中断,可以不用开一个任务实时的去读取串口,判断串口有没有数据发送过来,提高系统实时性。
中断驱动uart_driver_install函数参数说明如下:
esp_err_tuart_driver_install(uart_port_tuart_num,intrx_buffer_size,inttx_buffer_size,intqueue_size, QueueHandle_t *uart_queue,intintr_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);
本文只介绍发送和接收两个函数,更多函数可参考乐鑫官网
intuart_read_bytes(uart_port_tuart_num,void*buf,uint32_tlength, TickType_t ticks_to_wait);//参数 : uart_num:串口编号 可查看uart.h,进行选择// buf:接收数组名// length:接收到的数据长度// ticks_to_wait:读取等待的RTOS 滴答个数//返回 : -1:表示错误// 其他:表示从uart的接收fifo读取到的数据intuart_write_bytes(uart_port_tuart_num,constvoid*src,size_tsize);//参数 : uart_num:串口编号 可查看uart.h,进行选择// src:发送数组名// size:发送的数据长度//返回 : -1:表示错误// 其他:表示uart发送给发送fifo的数据
idf.py create-project project_uart # 新建工程 cd project_uart idf.py set-target esp32c3 # 设置工程使用的芯片
#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 >#defineLOG_EVENT_TAG"uart"QueueHandle_t uart_queue =NULL;#defineRX_BUFF_SIZE 1024#defineUART_PORT UART_NUM_2#defineRX_PIN GPIO_NUM_1#defineTX_PIN GPIO_NUM_0uint8_tuart_buff[RX_BUFF_SIZE];voidUartEventHandle(void* param);voidinit_uart(void){uart_config_tuart_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); }voidUartEventHandle(void* param){uart_event_tevent;memset(&uart_data,0,sizeof(UartData)); uart_data.rx_status = pdFALSE;while(pdTRUE) {if(xQueueReceive(uart_queue, (void*)&event, portMAX_DELAY)) {switch(event.type) {caseUART_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;caseUART_FIFO_OVF:caseUART_BUFFER_FULL: uart_flush_input(UART_PORT); xQueueReset(uart_queue);break;default: ESP_LOGI(LOG_EVENT_TAG,"uart event type: %d", event.type);break; } } } }voidapp_main(void){ init_uart();while(1) { vTaskDelay(1000/ portTICK_RATE_MS); } }