ESP32 (UART 485通讯)-串口之485通讯(3)

提示:本博客作为学习笔记,有错误的地方希望指正

一、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,</
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值