提示:本博客作为学习笔记,有错误的地方希望指正
文章目录
一、ESP32串口介绍
UART 是一种以字符为导向的通用数据链,可以实现设备间的通信。异步传输的意思是不需要在发送数据上添加时钟信息。这也要求发送端和接收端的速率、停止位、奇偶校验位等都要相同,通信才能成功。
一个典型的 UART 帧开始于一个起始位,紧接着是有效数据,然后是奇偶校验位(可有可无),最后是停止位。
ESP32 上的 UART 控制器支持多种字符长度和停止位。另外,控制器还支持软硬件流控和 DMA,可以实现无缝高速的数据传输。开发者可以使用多个 UART 端口,同时又能保证很少的软件开销。
ESP32 芯片中有 3 个 UART 控制器可供使用,并且兼容不同的 UART 设备。另外,UART 还可以用作红外数据交换 (IrDA) 或 RS-485 调制解调器。
• 可编程收发波特率
• 3 个 UART 的发送 FIFO 以及接收 FIFO 共享 1024 × 8-bit RAM
• 全双工异步通信
• 支持输入信号波特率自检功能
• 支持 5/6/7/8 位数据长度
• 支持 1/1.5/2/3 个停止位
• 支持奇偶校验位
• 支持 RS485 协议
• 支持 IrDA 协议
• 支持 DMA 高速数据通信
• 支持 UART 唤醒模式
• 支持软件流控和硬件流控
值得注意的是ESP32的三路串口中串口0不支持引脚的修改默认是RGIO1作为RX,GPIO3作为TX,配置的时候需要注意下,串口0默认使用作为下载程序使用和ESP_LOG的输出。UART1默认引脚是GPIO9用作U1RXD,GPIO10用作U1TXD,但是这两个引脚也是用于外接flash的,因此在使用UART1的时候需要设置其他引脚,UART2默认引脚是GPIO16用作U2RXD,GPIO17用作U2TXD。
485通讯规定为2线,半双工,多点通信的标准。
RS485特点:
• 接口电平低,不易损坏芯片。
• 传输速率高,10 米时, RS485 的数据最高传输速率可达 35Mbps,在 1200m 时,传输速度可达 100Kbps。
• 抗干扰能力强,RS485 接口是采用平衡驱动器和差分接收器的组合,抗共模干扰能力增强,即抗噪声干扰性好。、
• 传输距离远,支持节点多, RS485 总线最长可以传输 1200m 以上(速率≤100Kbps)一般最大支持 32 个节点,如果使用特制的 485 芯片,可以达到 128 个或者 256 个节点,最大的可以支持到 400 个节点。
二、硬件设计
这里的硬件设置就是使用的是M5Stack的硬件来实现串口通讯协议实验演示的。这里使用串口0作为485通讯实验的测试,实际并没有接入485芯片。

三、实现代码
初始化流程

初始化代码如下
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "driver/uart.h"
#include "freertos/queue.h"
#include "esp_log.h"
#include "sdkconfig.h"
#define TAG "RS485_ECHO_APP"
// 串口回声虫我理解的含义就是接收到数据给原数据沿路发送出去
// 注意:目标芯片上的某些引脚不能分配给 UART 通信。
// 请参阅所选板和目标的文档以使用 Kconfig 配置引脚。
#define ECHO_TEST_TXD (CONFIG_ECHO_UART_TXD) //发送引脚
#define ECHO_TEST_RXD (CONFIG_ECHO_UART_RXD) //接收引脚
#define ECHO_TEST_RTS (CONFIG_ECHO_UART_RTS) //RS485 半双工模式的 RTS 管理 DE/~RE
#define ECHO_TEST_CTS (UART_PIN_NO_CHANGE) //RS485 半双工模式下不使用 CTS
#define BUF_SIZE (127) //buf大小
#define BAUD_RATE (CONFIG_ECHO_UART_BAUD_RATE) //波特率大小
#define PACKET_READ_TICS (100 / portTICK_RATE_MS) //读包超时时间
#define ECHO_TASK_STACK_SIZE (2048) //回声虫堆栽大小
#define ECHO_TASK_PRIO (10) //任务优先级
#define ECHO_UART_PORT (CONFIG_ECHO_UART_PORT_NUM) //串口回声虫波特率
// UART 的超时阈值 = 接收引脚上状态不变的符号数(~10 次)
#define ECHO_READ_TOUT (3) // 3.5T * 8 = 28 ticks, TOUT=3 -> ~24..33 ticks
//回声虫发送函数
static void echo_send(const int port, const char* str, uint8_t length)
{
if (uart_write_bytes(port, str, length) != length) {
//发送数据
ESP_LOGE(TAG, "Send data critical failure.");
// 在此处添加处理发送失败的代码
abort();
}
}
// 在UART上使用硬件流控制进行回声测试的示例
static void echo_task(void *arg)
{
const int uart_num = ECHO_UART_PORT; //串口编号
uart_config_t uart_config = {
.baud_rate = BAUD_RATE, //串口波特率
.data_bits = UART_DATA_8_BITS, //数据位
.parity = UART_PARITY_DISABLE, //奇偶校验
.stop_bits = UART_STOP_BITS_1, //停止为
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE, //硬件流孔控制
.rx_flow_ctrl_thresh = 122, //UART硬件RTS阈值
.source_clk = UART_SCLK_APB, //串口时钟
};
// Set UART log level
esp_log_level_set(TAG, ESP_LOG_INFO); //设置log打印等级
ESP_LOGI(TAG, "Start RS485 application test and configure UART.");
// 安装 UART 驱动(这里我们不需要事件队列)
// 在这个例子中,我们甚至不使用缓冲区来发送数据。
// 安装串口驱动 串口编号、接收buf、发送buf、事件队列、分配中断的标志
ESP_ERROR_CHECK(uart_driver_install(uart_num, BUF_SIZE * 2, 0, 0, NULL, 0));
// 配置串口参数 串口编号、配置结构体参数
ESP_ERROR_CHECK(uart_param_config(uart_num, &uart_config));
ESP_LOGI(TAG, "UART set pins, mode and install driver.");
// 设置串口引脚 串口编号、接收引脚、发送引脚、rts引脚、cts引脚
ESP_ERROR_CHECK(uart_set_pin(uart_num, ECHO_TEST_TXD, ECHO_TEST_RXD, ECHO_TEST_RTS, ECHO_TEST_CTS));
// 设置串口模式 485半双工通讯模式
ESP_ERROR_CHECK(uart_set_mode(uart_num, UART_MODE_RS485_HALF_DUPLEX));
// 设置UART TOUT功能的读取超时
ESP_ERROR_CHECK(uart_set_rx_timeout(uart_num, ECHO_READ_TOUT));
// 申请动态内存
uint8_t* data = (uint8_t*) malloc(BUF_SIZE);
ESP_LOGI(TAG,</



被折叠的 条评论
为什么被折叠?



