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

文章目录

  • 一、ESP32串口介绍
  • 二、硬件设计
  • 三、实现代码
  • 四、串口实验演示结果
  • 五、ESP32串口函数API
    • 5.1、uart_types.h文件中的内容的API
    • 5.2、在uart.h文件中的内容的API

一、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 levelesp_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, "UART start recieve loop.\r\n");echo_send(uart_num, "Start RS485 UART test.\r\n", 24);while(1) {//读取串口数据int len = uart_read_bytes(uart_num, data, BUF_SIZE, PACKET_READ_TICS);//发送数据if (len > 0) {echo_send(uart_num, "\r\n", 2);                     //发送回车换行char prefix[] = "RS485 Received: [";echo_send(uart_num, prefix, (sizeof(prefix) - 1));  //发送数据ESP_LOGI(TAG, "Received %u bytes:", len);printf("[ ");for (int i = 0; i < len; i++) {printf("0x%.2X ", (uint8_t)data[i]);            //打印16进制数据echo_send(uart_num, (const char*)&data[i], 1);  //发送数据// 如果您从粘贴中获得返回字符,请添加换行符(粘贴测试多字节收据/缓冲区)if (data[i] == '\r') {echo_send(uart_num, "\n", 1);}}printf("] \n");echo_send(uart_num, "]\r\n", 3);} else {// 回声一个“.” 在等待输入时表明程序还活着echo_send(uart_num, ".", 1);ESP_ERROR_CHECK(uart_wait_tx_done(uart_num, 10));}}vTaskDelete(NULL);
}
void app_main(void)
{//没有事件队列的 uart 读/写示例;xTaskCreate(echo_task, "uart_echo_task", ECHO_TASK_STACK_SIZE, NULL, ECHO_TASK_PRIO, NULL);
}

四、串口实验演示结果

五、ESP32串口函数API

5.1、uart_types.h文件中的内容的API

  uart_types.h文件中的内容基本上实现的是一些串口协议的设置结构体

// UART端口号,取值为UART_NUM_0 ~ (UART_NUM_MAX -1)。
typedef int  uart_port_t;// UART模式选择
typedef enum {UART_MODE_UART = 0x00,                     /*!< mode:普通UART模式*/UART_MODE_RS485_HALF_DUPLEX = 0x01,        /*!< mode:由RTS引脚控制的半双工RS485 UART模式*/UART_MODE_IRDA = 0x02,                     /*!< mode:IRDA UART模式*/UART_MODE_RS485_COLLISION_DETECT = 0x03,   /*!< mode:RS485碰撞检测UART模式(用于测试目的)*/uart_mod_rs485_app_ctrl = 0x04,            /*!< mode:应用控制RS485 UART模式(用于测试目的)*/
} uart_mode_t;//UART字长常量
typedef enum {UART_DATA_5_BITS = 0x0,    /*!< 5个字节长度 */UART_DATA_6_BITS = 0x1,    /*!< 6个字节长度 */UART_DATA_7_BITS = 0x2,    /*!< 7个字节长度 */UART_DATA_8_BITS = 0x3,    /*!< 8个字节长度 */UART_DATA_BITS_MAX = 0x4,
} uart_word_length_t;//UART停止位数
typedef enum {UART_STOP_BITS_1   = 0x1,   /*!< 1个字节停止位 */UART_STOP_BITS_1_5 = 0x2,   /*!< 1.5个字节停止位 */UART_STOP_BITS_2   = 0x3,   /*!< 2个字节停止位 */UART_STOP_BITS_MAX = 0x4,
} uart_stop_bits_t;//UART奇偶校验常数
typedef enum {UART_PARITY_DISABLE = 0x0,  /*!<禁用UART奇偶校验*/UART_PARITY_EVEN    = 0x2,  /*!<启用UART偶校验*/UART_PARITY_ODD     = 0x3    /*!<启用UART奇偶校验*/
} uart_parity_t;//UART硬件流控制模式
typedef enum {UART_HW_FLOWCTRL_DISABLE = 0x0,/*!<禁用硬件流控制*/UART_HW_FLOWCTRL_RTS = 0x1,    /*!<启用RX硬件流控制(rts)*/UART_HW_FLOWCTRL_CTS = 0x2,    /*!<enable TX硬件流控制(cts)*/UART_HW_FLOWCTRL_CTS_RTS = 0x3,/*!<启用硬件流控制*/UART_HW_FLOWCTRL_MAX = 0 x4,
} uart_hw_flowcontrol_t;//UART信号位图
typedef enum {Uart_signal_inv_disable = 0,           /*!<禁用UART信号逆*/UART_SIGNAL_IRDA_TX_INV = (0x1 << 0),  /*!<反UART irda_tx信号*/UART_SIGNAL_IRDA_RX_INV = (0x1 << 1),  /*!<逆UART irda_rx信号*/UART_SIGNAL_RXD_INV = (0x1 << 2),      /*!<逆UART rxd信号*/UART_SIGNAL_CTS_INV = (0x1 << 3),      /*!<反转UART cts信号*/UART_SIGNAL_DSR_INV = (0x1 << 4),      /*!<反转UART dsr信号*/UART_SIGNAL_TXD_INV = (0x1 << 5),      /*!<逆UART txd信号*/UART_SIGNAL_RTS_INV = (0x1 << 6),      /*!<反转UART rts信号*/UART_SIGNAL_DTR_INV = (0x1 << 7),      /*!<反转UART dtr信号*/
} uart_signal_inv_t;//UART源时钟
typedef enum {UART_SCLK_APB = 0x0,       /*!<来自APB的UART源时钟*/
#if SOC_UART_SUPPORT_RTC_CLKUART_SCLK_RTC = 0x1,       /*!< UART源时钟来自RTC*/
# endif
#if SOC_UART_SUPPORT_XTAL_CLKUART_SCLK_XTAL = 0x2,      /*!< UART源时钟来自XTAL*/
# endif
#if SOC_UART_SUPPORT_REF_TICKUART_SCLK_REF_TICK = 0x3,  /*!< UART源时钟来自REF_TICK*/
# endif
} uart_sclk_t;/*
* @brief 串口AT指令字符配置参数
* 注意此功能在不同芯片上可能不同。请在配置时参考TRM。
*/
typedef struct {uint8_t  cmd_char;      /* !< UART AT命令字符配置参数 */uint8_t  char_num;      /* !< UART AT命令字符重复编号 */uint32_t gap_tout;      /* !< AT命令字符之间的间隔时间(波特率) */uint32_t pre_idle;      /* !< 非AT字符和第一个AT字符之间的空闲时间(波特率) */uint32_t post_idle;     /* !< 最后一个AT字符和无AT字符之间的空闲时间(波特率) */
} uart_at_cmd_t;/**
* @brief UART软件流量控制配置参数
*/
typedef struct {uint8_t xon_char;       /* !< Xon流控制字符*/uint8_t xoff_char;      /* !< Xoff流控制字符*/uint8_t xon_thrd;       /* !<如果启用了软件流控制,并且rxfifo中的数据量小于xon_thrd,则发送一个xon_char */uint8_t xoff_thrd;      /* !<如果使能了软件流控制,并且rxfifo中的数据量大于xoff_thrd,则发送一个xoff_char */
} uart_sw_flowctrl_t;/**
* @brief uart_param_config函数的UART配置参数
*/
typedef struct {int  baud_rate;                 /* !< UART波特率*/uart_word_length_t data_bits;   /* !< UART字节大小*/uart_parity_t parity;           /* !< UART校验模式*/uart_stop_bits_t stop_bits;     /* !< UART停止位*/uart_hw_flowcontrol_t flow_ctrl;/* !< UART HW流量控制模式(cts/rts)*/uint8_t rx_flow_ctrl_thresh;    /* !< UART HW RTS阈值*/union{uart_sclk_t source_clk;     /* !< UART源时钟选择*/bool use_ref_tick __attribute__((deprecated));  /* !已弃用方法来选择ref tick clock source,将source_clk字段改为*/};
} uart_config_t;

5.2、在uart.h文件中的内容的API

  在uart.h文件中的内容就多一些,主要是ESP32串口的配置参数的架构体以及初始化函数和配置函数,还包括了串口事件等参数和函数API。温馨提示:可以给这些API复制到文本编辑器中,例如Vscode中,然后可以快速查找定位即可知道函数功能以及函数参数的含义。

//有效的UART端口号
#define UART_NUM_0 (0)              /*!< UART端口0 */
#define UART_NUM_1 (1)              /*!< UART端口1 */
#if SOC_UART_NUM > 2
#define UART_NUM_2 (2)              /*!< UART端口2 */
# endif
#define UART_NUM_MAX (SOC_UART_NUM) /*!< UART端口max *//* @brief当调用' uart_set_pin ',而不是GPIO number, ' UART_PIN_NO_CHANGE '
*可提供保持当前分配的引脚。*/
#define UART_PIN_NO_CHANGE (1)SOC_UART_FIFO_LEN       //< UART 硬件FIFO的长度
SOC_UART_BITRATE_MAX    //<可配置的最大比特率//UART中断配置参数uart_intr_config函数
typedef struct {uint32_t intr_enable_mask;          /* !< UART中断启用掩码,选择uart_xxxx_int _ena_reg (i)下的UART_XXXX_int _ENA_M,连接位或操作符*/uint8_t rx_timeout_thresh;          /* !< UART超时中断阈值(单位:发送一个字节的时间)*/uint8_t txfifo_empty_intr_thresh;   /* !< UART TX空中断阈值。*/uint8_t rxfifo_full_thresh;         /* !< UART RX全中断阈值。*/
} uart_intr_config_t;//UART事件类型在循环缓冲区中使用
typedef enum {UART_DATA ,                         /*!< UART数据事件*/UART_BREAK ,                        /*!< UART中断事件*/UART_BUFFER_FULL ,                  /*!< UART RX缓冲区完整事件*/UART_FIFO_OVF ,                     /*!< UART FIFO溢出事件*/UART_FRAME_ERR ,                    /*!< UART RX帧错误事件*/UART_PARITY_ERR ,                   /*!< UART RX奇偶校验事件*/UART_DATA_BREAK ,                   /*!< UART TX数据和中断事件*/UART_PATTERN_DET ,                  /*!< 检测到UART模式*/UART_EVENT_MAX ,                    /*!< UART事件最大索引*/
} uart_event_type_t;            //事件结构用于UART事件队列
typedef struct {uart_event_type_t type; /* !< UART事件类型*/size_t size;            /* !< UART_DATA事件的UART数据大小*/bool timeout_flag;      /* !< UART数据读取超时标志UART_DATA事件(在配置RX TOUT期间没有收到新数据)*//* !<如果事件是由FIFO-full中断引起的,那么在下一个字节到来之前将没有带有超时标志的事件*/
} uart_event_t;typedef intr_handle_t uart_isr_handle_t;/*
* @brief安装UART驱动程序并设置UART为默认配置。
* UART ISR处理器将被附加到这个函数运行的同一CPU核心上。
* Rx_buffer_size应该大于UART_FIFO_LEN。Tx_buffer_size应该为零或大于UART_FIFO_LEN。
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @param rx_buffer_size UART RX环缓冲区大小。
* @param tx_buffer_size UART TX环缓冲区大小。
* 如果设置为0,驱动程序将不会使用TX缓冲区,TX函数将阻塞任务,直到所有数据被发送出去。
* @param queue_size UART事件队列大小/深度。
* @param uart_queue UART事件队列句柄。一旦成功,将在这里编写一个新的队列句柄来提供
* 访问UART事件。如果设置为NULL,驱动程序将不会使用事件队列。
* @param intr_alloc_flags用于分配中断的标志。一个或多个(ORred)
* ESP_intr_FLAG_ *值。更多信息请参见esp_intr_alloc.h。这里没有设置ESP_intr_FLAG_IRAM
* (驱动程序的ISR处理程序不在IRAM中)
* @return
* - ESP_OK成功
* - ESP_FAIL参数错误
*/
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);/*
* @brief卸载UART驱动。
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @return
* - ESP_OK成功
* - ESP_FAIL参数错误
*/
esp_err_t uart_driver_delete (uart_port_t uart_num);/**
* @brief检查驱动是否安装
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @return
* -真正的驱动程序已安装
* -错误的驱动程序没有安装
*/
bool uart_is_driver_installed (uart_port_t uart_num);/**
* 设置UART数据位。
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @param data_bit UART数据位
* @return
* - ESP_OK成功
* - ESP_FAIL参数错误
*/
esp_err_t uart_set_word_length(uart_port_t uart_num, uart_word_length_t data_bit);/*
* 获取UART数据位配置。
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @param data_bit接收UART数据位值的指针。
* @return
* - ESP_FAIL参数错误
* - ESP_OK Success, result将被放入(*data_bit)
*/
esp_err_t uart_get_word_length(uart_port_t uart_num, uart_word_length_t* data_bit);/**
* 获取UART数据位配置。
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @param data_bit接收UART数据位值的指针。
* @return
* - ESP_FAIL参数错误
* - ESP_OK Success, result将被放入(*data_bit)
*/
esp_err_t uart_get_word_length(uart_port_t uart_num, uart_word_length_t* data_bit);/**
* 设置UART停止位。
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @param stop_bits UART停止位
* @return
* - ESP_OK成功
* - ESP_FAIL失败
*/
esp_err_t uart_set_stop_bits(uart_port_t uart_num, uart_stop_bits_t stop_bits);/**
* 获取UART停止位配置。
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @param stop_bits接受UART停止位值的指针。
* @return
* - ESP_FAIL参数错误
* - ESP_OK Success,结果将被放入(*stop_bit)
*/
esp_err_t uart_get_stop_bits(uart_port_t uart_num, uart_stop_bits_t* stop_bits);/**
* @brief设置UART校验模式。
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @param parity_mode uart奇偶校验配置的enum
* @return
* - ESP_FAIL参数错误
* - ESP_OK成功
*/
esp_err_t uart_set_parity(uart_port_t uart_num, uart_parity_t parity_mode);/**
* 获取UART奇偶校验模式配置。
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @param parity_mode接受UART奇偶校验模式值的指针。
* @return
* - ESP_FAIL参数错误
* - ESP_OK Success,结果将被放入(*parity_mode)
*/
esp_err_t uart_get_parity(uart_port_t uart_num, uart_parity_t* parity_mode);/**
* 设置UART波特率。
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @param baudrate UART波特率。
* @return
* - ESP_FAIL参数错误
* - ESP_OK成功
*/
esp_err_t uart_set_baudrate(uart_port_t uart_num, uint32_t baudrate);/**
* 获取UART波特率配置。
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @param baudrate接受UART波特率值的指针
* @return
* - ESP_FAIL参数错误
* - ESP_OK Success,结果将被输入(*baudrate)
*/
esp_err_t uart_get_baudrate(uart_port_t uart_num, uint32_t* baudrate);/**
* @brief设置UART线反向模式
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @param inverse_mask选择需要反转的连线。使用' uart_signal_inv_t '的ORred掩码
* @return
* - ESP_OK成功
* - ESP_FAIL参数错误
*/
esp_err_t uart_set_line_inverse(uart_port_t uart_num, uint32_t inverse_mask);/**
* @brief设置硬件流控制。
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @param flow_ctrl硬件流控制模式
* @param rx_thresh硬件RX流量控制阈值(0 ~ UART_FIFO_LEN)。
* 只有当UART_HW_FLOWCTRL_RTS设置时,rx_threshresh值才会被设置。
* @return
* - ESP_OK成功
* - ESP_FAIL参数错误
*/
esp_err_t uart_set_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t flow_ctrl, uint8_t rx_thresh);/**
* @brief设置软件流量控制。
* @param uart_num UART_NUM_0, UART_NUM_1或UART_NUM_2
* @param开启或关闭开关
* @param rx_thresh_xon低水位标记
* @param rx_thresh_xoff高水位
* @return
* - ESP_OK成功
* - ESP_FAIL参数错误
*/
esp_err_t uart_set_sw_flow_ctrl(uart_port_t uart_num, bool enable, uint8_t rx_thresh_xon, uint8_t rx_thresh_xoff);/**
* 获取UART硬件流控制配置。
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @param flow_ctrl选项用于不同的流控制模式。
* @return
* - ESP_FAIL参数错误
* - ESP_OK Success,结果将被放入(*flow_ctrl)
*/
esp_err_t uart_get_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t* flow_ctrl);/**
* @brief清除UART中断状态
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @param clr_mask需要清除的中断状态的位掩码。
* @return
* - ESP_OK成功
* - ESP_FAIL参数错误
*/
esp_err_t uart_clear_in t_status(uart_port_t uart_num, uint32_t clr_mask);/**
* 设置UART中断使能
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @param enable_mask启用位掩码。
* @return
* - ESP_OK成功
* - ESP_FAIL参数错误
*/
esp_err_t uart_enable_intr_mask(uart_port_t uart_num, uint32_t enable_mask);/*
* @brief清除UART中断启用位
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @param disable_mask禁用位的位掩码。
* @return
* - ESP_OK成功
* - ESP_FAIL参数错误
*/
esp_err_t uart_disable_intr_mask(uart_port_t uart_num, uint32_t disable_mask);/*
* 启用UART RX中断(RX_FULL和RX_TIMEOUT中断)
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @return
* - ESP_OK成功
* - ESP_FAIL参数错误
*/
esp_err_t uart_enable_rx_intr (uart_port_t uart_num);/*
* 关闭UART RX中断(RX_FULL和RX_TIMEOUT中断)
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @return
* - ESP_OK成功
* - ESP_FAIL参数错误
*/
esp_err_t uart_disable_rx_intr (uart_port_t uart_num);/*
* @brief关闭UART TX中断(TXFIFO_EMPTY中断)
* @param uart_num UART端口号
* @return
* - ESP_OK成功
* - ESP_FAIL参数错误
*/
esp_err_t uart_disable_tx_intr (uart_port_t uart_num);/*
打开UART TX中断(TXFIFO_EMPTY中断)
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @param启用1:启用;0:禁用
* @param thresh TX中断阈值,0 ~ UART_FIFO_LEN
* @return
* - ESP_OK成功
* - ESP_FAIL参数错误
*/
esp_err_t uart_enable_tx_intr(uart_port_t uart_num, int  enable, int  thresh);/*
* 注册UART中断处理器(ISR)。
* @note UART ISR处理器将被附加到这个函数运行的同一CPU核心上。
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @param fn中断处理函数。
* @param参数参数的处理程序的功能
* @param intr_alloc_flags用于分配中断的标志。一个或多个(ORred)
* ESP_intr_FLAG_ *值。更多信息请参见esp_intr_alloc.h。
* 返回句柄的指针。如果非null,则中断句柄将
* 在这里返回。
* @return
* - ESP_OK成功
* - ESP_FAIL参数错误
*/
esp_err_t uart_isr_register(uart_port_t uart_num, void (*fn)(void*), void* arg, int  intr_alloc_flags, uart_isr_handle_t *handle);/*
* 免费的UART中断处理程序注册的uart_isr_register。必须在同一个核心调用
* uart_isr_register被调用。
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @return
* - ESP_OK成功
* - ESP_FAIL参数错误
*/
esp_err_t uart_isr_free (uart_port_t uart_num);/*
* 将UART外设的信号分配给GPIO管脚
* 如果为UART信号配置的GPIO号匹配其中一个
* IOMUX信号为该GPIO,信号将直接连接
* 通过IOMUX。否则GPIO与信号将通过
* GPIO矩阵。例如ESP32通话
* ' uart_set_pin(0,1,3, -1, -1) '被执行,因为GPIO1是UART0的
* 默认的TX引脚和GPIO3是UART0的默认RX引脚,两者都是
* 通过IOMUX分别连接U0TXD和U0RXD,共绕过GPIO矩阵。
* 检查是在每针的基础上执行。因此,有可能
* RX引脚通过GPIO矩阵绑定到GPIO上,而TX是绑定的
* 通过IOMUX连接到GPIO。
* @note内部信号可以输出到多个GPIO板。
* 输入信号只能连接一个GPIO板。
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @param tx_io_num UART TX引脚GPIO编号。
* @param rx_io_num UART RX引脚GPIO编号。
* @param rts_io_num UART RTS引脚GPIO编号。
* @param cts_io_num UART CTS引脚GPIO编号。
* @return
* - ESP_OK成功
* - ESP_FAIL参数错误
*/
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);/*
* @brief手动设置UART RTS引脚级别。
* 注意UART必须配置为禁用硬件流控制。
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @param 1级:RTS输出低(活跃);0: RTS输出高(块)
* @return
* - ESP_OK成功
* - ESP_FAIL参数错误
*/
esp_err_t uart_set_rts(uart_port_t uart_num, int  level);/*
* 手动设置UART DTR引脚级别。
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @param level 1: DTR输出低;0: DTR输出高
* @return
* - ESP_OK成功
* - ESP_FAIL参数错误
*/
esp_err_t uart_set_dtr(uart_port_t uart_num, int  level);/*
* @brief设置UART空闲间隔后tx FIFO是空的
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @param idle_num tx FIFO后的空闲间隔为空(单位:发送一个比特所需的时间)
* 在当前波特率下)
* @return
* - ESP_OK成功
* - ESP_FAIL参数错误
*/
esp_err_t uart_set_tx_idle_num(uart_port_t uart_num, uint 16_t idle_num);/*
* @brief UART配置参数。
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @param uart_config UART参数设置
* @return
* - ESP_OK成功
* - ESP_FAIL参数错误
*/
esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_config)/**
* 配置UART中断。
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @param intr_conf UART中断设置
* @return
* - ESP_OK成功
* - ESP_FAIL参数错误
*/
esp_err_t uart_intr_config(uart_port_t uart_num, const uart_intr_config_t *intr_conf);/*
* @brief等待直到UART TX FIFO是空的。
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @param ticks_to_wait超时时间,以RTOS计时计数
* @return
* - ESP_OK成功
* - ESP_FAIL参数错误
* - ESP_ERR_TIMEOUT超时时间
*/
esp_err_t uart_wait_tx_done(uart_port_t uart_num, TickType_t ticks_to_wait);/*
* 从给定的缓冲区和长度发送数据到UART端口。
* 这个函数将不会等待足够的空间在TX FIFO。它将填充可用的TX FIFO,并在FIFO满时返回。
* @注意此函数只应在UART TX缓冲区未启用时使用。
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @param缓冲区数据缓冲区地址
* @param len发送的数据长度
* @return
* -(-1)参数错误
* - OTHERS(>=0)发送到TX FIFO的字节数
*/
int  uart_tx_chars(uart_port_t uart_num, const char* buffer, uint32_t len);/**
* 从给定的缓冲区和长度发送数据到UART端口,
* 如果UART驱动程序的参数tx_buffer_size设置为零:
* 这个函数将不会返回,直到所有的数据已经被发送出去,或至少推入TX FIFO。
* 否则,如果'tx_buffer_size' > 0,这个函数将返回所有的数据复制到tx环缓冲区,
* 然后UART ISR将数据从环形缓冲区逐渐移动到TX FIFO。
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @param SRC数据缓冲区地址
* @param size发送的数据长度
* @return
* -(-1)参数错误
* - OTHERS(>=0)发送到TX FIFO的字节数
*/
int  uart_write_bytes(uart_port_t uart_num, const void* src, size_t size);/**
* 从给定的缓冲区和长度发送数据到UART端口,
* 如果UART驱动程序的参数tx_buffer_size设置为零:
* 此函数将不会返回,直到所有数据和中断信号已被发送。
* 所有数据发送完毕后,发送中断信号。
* 否则,如果'tx_buffer_size' > 0,这个函数将返回所有的数据复制到tx环缓冲区,
* 然后UART ISR将数据从环形缓冲区逐渐移动到TX FIFO。
* 所有数据发送完毕后,发送中断信号。
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @param SRC数据缓冲区地址
* @param size发送的数据长度
* @param brk_len中断信号持续时间(单位:在当前波特率下发送一个比特所需的时间)
* @return
* -(-1)参数错误
* - OTHERS(>=0)发送到TX FIFO的字节数
*/
int  uart_write_bytes_with_break(uart_port_t uart_num, const void* src, size_t size, int  brk_len);/*
* @brief UART从UART buffer中读取字节
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @param buf指针指向缓冲区。
* @param length数据长度
* @param ticks_to_wait超时时间,以RTOS计时
* @return
* -(-1)错误
* - OTHERS(>=0)从UART FIFO读取的字节数
*/
int  uart_read_bytes(uart_port_t uart_num, void* buf, uint32_t length, TickType_t ticks_to_wait);/*
* @brief uart_flush_input的别名。
* UART环缓冲区冲洗。这将丢弃UART RX缓冲区中的所有数据。
* @note不是等待数据发送,这个函数将清除UART rx缓冲区。
* 为了发送所有的数据在tx FIFO,我们可以使用uart_wait_tx_done函数。
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @return
* - ESP_OK成功
* - ESP_FAIL参数错误
*/
esp_err_t uart_flush (uart_port_t uart_num);/*
* @brief清除输入缓冲区,丢弃所有环缓冲区中的数据。
* 为了在tx FIFO中发送所有的数据,我们可以使用uart_wait_tx_done函数。
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @return
* - ESP_OK成功
* - ESP_FAIL参数错误
*/
esp_err_t uart_flush_input (uart_port_t uart_num);/*
* @brief UART获取RX环缓冲区缓存的数据长度
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @param size size_t的指针,用于接受缓存数据的长度
* @return
* - ESP_OK成功
* - ESP_FAIL参数错误
*/
esp_err_t uart_get_buffered_data_len(uart_port_t uart_num, size_t* size);/*
* @brief UART禁用模式检测功能。
* 专为应用程序如“AT命令”。
* 当硬件检测到一系列相同的字符时,将触发中断。
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @return
* - ESP_OK成功
* - ESP_FAIL参数错误
*/
esp_err_t uart_disable_pattern_det_intr (uart_port_t uart_num);#if CONFIG_IDF_TARGET_ESP32
/*
* @brief UART启用模式检测功能。
* 专为应用程序如“AT命令”。
* 当硬件检测到一系列相同的字符时,将触发中断。
* @注意此函数仅适用于esp32。此函数已弃用,请使用
* uart_enable_pattern_det_baud_intr代替。
* @param uart_num UART端口号。
* @param pattern_chr模式字符。
* @param chr_num字符数,8位值。
* @param chr_tout每个模式字符之间的间隔超时,24位值,单位是APB (80Mhz)时钟周期。
* 当持续时间小于这个值,它将不接受这个数据作为at_cmd字符。
* @param post_idle最后一个模式字符后的空闲时间,24位值,单位是APB (80Mhz)时钟周期。
* 当持续时间小于这个值,它将不接受前一个数据作为最后一个at_cmd字符
* @param pre_idle第一个模式字符前的空闲时间,24位值,单位是APB (80Mhz)时钟周期。
* 当持续时间小于这个值,它将不接受这个数据作为第一个at_cmd字符。
* @return
* - ESP_OK成功
* - ESP_FAIL参数错误
*/
esp_err_t uart_enable_pattern_det_intr(uart_port_t uart_num, char pattern_chr, uint8_t chr_num, int  chr_tout, int  post_idle, int  pre_idle) __attribute__((deprecated));
# endif/*
* @brief UART启用模式检测功能。
* 专为应用程序如“AT命令”。
* 当硬件检测到一系列相同的字符时,将触发中断。
* @param uart_num UART端口号。
* @param pattern_chr模式字符。
* @param chr_num字符数,8位值。
* @param chr_tout每个模式字符之间的间隔超时时间,16位值,单位是您配置的波特率周期。
* 当持续时间大于这个值,它将不接受这个数据为at_cmd字符。
* @param post_idle最后一个模式字符后的空闲时间,16位值,单位是您配置的波特率周期。
* 当持续时间小于这个值,它将不接受前一个数据作为最后一个at_cmd字符
* @param pre_idle第一个模式字符前的空闲时间,16位值,单位是您配置的波特率周期。
* 当持续时间小于这个值,它将不接受这个数据作为第一个at_cmd字符。
* @return
* - ESP_OK成功
* - ESP_FAIL参数错误
*/
esp_err_t uart_enable_pattern_det_baud_intr(uart_port_t uart_num, char pattern_chr, uint8_t chr_num, int  chr_tout, int  post_idle, int  pre_idle);/*
* 返回在缓冲区中最近的检测到的模式位置。
* 检测到的图案的位置保存在一个队列中,
* 这个函数将退出第一个模式位置,并将指针移动到下一个模式位置。
* 如果RX缓冲区已满且流控制未启用,
* 由于溢出,检测到的模式可能无法在rx缓冲区中找到。
* 以下api将修改模式位置信息:
* uart_flush_input, uart_read_bytes, uart_driver_delete, uart_pop_pattern_pos
* 确保对模式队列和rx数据缓冲区的原子访问是应用程序的责任
* 当使用模式检测特征。
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @return
* -(-1)没有找到当前索引或参数错误的模式
* -其他的模式位置在rx缓冲区。
*/
int  uart_pattern_pop_pos (uart_port_t uart_num);/*
* 返回在缓冲区中最近的检测到的模式位置。
* 检测到的图案的位置保存在一个队列中,
* 这个函数对队列不做任何操作。
* 如果RX缓冲区已满且流控制未启用,
* 由于溢出,检测到的模式可能无法在rx缓冲区中找到。
* 以下api将修改模式位置信息:
* uart_flush_input, uart_read_bytes, uart_driver_delete, uart_pop_pattern_pos
* 确保对模式队列和rx数据缓冲区的原子访问是应用程序的责任
* 当使用模式检测特征。
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @return
* -(-1)没有找到当前索引或参数错误的模式
* -其他的模式位置在rx缓冲区。
*/
int  uart_pattern_get_pos (uart_port_t uart_num);/*
* 分配一个给定长度的新内存来保存rx缓冲区中检测到的模式位置。
* @param uart_num UART端口号,最大端口号为(UART_NUM_MAX -1)。
* @param queue_length检测到的模式的最大队列长度。
* 如果队列长度不够大,一些模式位置可能会丢失。
* 设置此值为数据缓冲区可同时保存模式的最大数量。
* @return
* - ESP_ERR_NO_MEM内存不足
* -未安装ESP_ERR_INVALID_STATE驱动程序
* - ESP_FAIL参数错误
* - ESP_OK成功
*/
esp_err_t uart_pattern_queue_reset(uart_port_t uart_num, int  queue_length);/*
* @brief UART设置通信模式
* @note这个函数必须在uart_driver_install()之后,当驱动对象初始化时执行。
* @param uart_num要配置的Uart编号,最大端口号为(UART_NUM_MAX -1)。
* @param mode UART UART模式设置
* @return
* - ESP_OK成功
* - ESP_ERR_INVALID_ARG参数错误
*/
esp_err_t uart_set_mode(uart_port_t uart_num, uart_mode_t mode);/*
* @brief设置RX fifo满的uart阈值
* @note如果应用程序使用更高的波特率,它是观察字节
* 在硬件RX fifo被覆盖,然后这个阈值可以减少
* @param uart_num UART_NUM_0, UART_NUM_1或UART_NUM_2
* @param threshold RX fifo全中断的阈值
* @return
* - ESP_OK成功
* - ESP_ERR_INVALID_ARG参数错误
* -未安装ESP_ERR_INVALID_STATE驱动程序
*/
esp_err_t uart_set_rx_full_threshold(uart_port_t uart_num, int  threshold);/*
* @brief设置uart阈值为空的fifo
* @param uart_num UART_NUM_0, UART_NUM_1或UART_NUM_2
* @param threshold TX fifo空中断产生的阈值
* @return
* - ESP_OK成功
* - ESP_ERR_INVALID_ARG参数错误
* -未安装ESP_ERR_INVALID_STATE驱动程序
*/
esp_err_t uart_set_tx_empty_threshold(uart_port_t uart_num, int  threshold);/**
* @brief UART为TOUT特性设置阈值超时
* @param uart_num要配置的Uart编号,最大端口号为(UART_NUM_MAX -1)。
* @param tout_thresh以uart符号周期定义超时阈值。阈值的最大值为126。
* tout_thresh = 1,定义了TOUT中断超时,等于当前波特率下一个符号(~11位)的传输时间。
* 时间过了会触发UART_RXFIFO_TOUT_int 中断。如果tout_thresh == 0,
* 禁用TOUT功能。
* @return
* - ESP_OK成功
* - ESP_ERR_INVALID_ARG参数错误
* -未安装ESP_ERR_INVALID_STATE驱动程序
*/
esp_err_t uart_set_rx_timeout(uart_port_t uart_num, const uint8_t tout_thresh);/**
* @brief为RS485模式返回碰撞检测标志
* 函数返回碰撞检测标志到collision_flag指向的变量。
* *collision_flag = true,如果检测到碰撞,否则它等于false。
* 这个函数应该在实际传输完成时执行(在uart_write_bytes()之后)。
* @param uart_num配置的最大端口号为(UART_NUM_MAX -1)。
* @param collision_flag bool类型变量的指针,返回碰撞标志。
* @return
* - ESP_OK成功
* - ESP_ERR_INVALID_ARG参数错误
*/
esp_err_t uart_get_collision_flag(uart_port_t uart_num, bool* collision_flag);/**
* 设置RX引脚信号边缘的数量,用于灯光休眠唤醒
* UART可以用来唤醒系统从轻度睡眠。这个特性很有用
* 通过计数RX引脚上的正边的数量,并将计数与
* 阈值。当计数超过阈值时,系统将被唤醒
* 光睡觉。提供阈值设置功能。
* 停止位和奇偶校验位(如果启用)也会影响边缘的数量。
* 例如,ASCII码97的字母“a”在网络上被编码为0100001101
* (与8n1配置),包括启动和停止位。这个序列有3个
* 正边缘(从0过渡到1)。因此,唤醒系统
* 当'a'被发送时,设置wakeup_threshold=3。
* 触发唤醒的字符没有被UART接收(即它不能
* 从UART FIFO获得)。根据波特率,几个字符
* 后即不受理。请注意,当芯片进入和退出
* 轻睡眠模式,APB频率将会改变。确保UART有
* 始终正确的波特率,选择REF_TICK作为UART时钟源,
* 将uart_config_t中的use_ref_tick字段设置为true。
* @note在ESP32中,唤醒信号只能通过IO_MUX(即IO_MUX)输入。
* GPIO3应该配置为function_1来唤醒UART0,
* GPIO9应该配置为function_5来唤醒UART1), UART2
* 不支持轻睡眠唤醒功能。
* @param uart_num UART编号,最大端口号为(UART_NUM_MAX -1)。
* @param wakeup_threshold RX边缘的数量,为轻睡眠唤醒,值为3 ..0 x3ff。
* @return
* - ESP_OK表示成功
* - uart_num不正确或wakeup_threshold不正确时为ESP_ERR_INVALID_ARG
* 在[3,0x3ff]范围之外。
*/
esp_err_t uart_set_wakeup_threshold(uart_port_t uart_num, int  wakeup_threshold);/**
* 获取RX引脚信号边缘的数量为轻睡眠唤醒。
* 关于UART的解释请参见uart_set_wakeup_threshold的描述
* 唤醒功能。
* @param uart_num UART编号,最大端口号为(UART_NUM_MAX -1)。
* @param[out] out_wakeup_threshold输出,设置为wakeup的当前值
* 给定UART的阈值。
* @return
* - ESP_OK表示成功
* -如果out_wakeup_threshold为NULL,则ESP_ERR_INVALID_ARG
*/
esp_err_t uart_get_wakeup_threshold(uart_port_t uart_num, int * out_wakeup_threshold);/**
* @brief等待直到UART tx内存空和最后一个字符发送ok(轮询模式)。
* @param uart_num UART编号
* * @return
* - ESP_OK表示成功
* - ESP_ERR_INVALID_ARG参数错误
* -未安装ESP_FAIL驱动
*/
esp_err_t uart_wait_tx_idle_polling (uart_port_t uart_num);/**
* 配置TX信号回RX模块,仅供测试使用。
* @param uart_num UART编号
* @param loop_back_en设置为true以启用回循环函数,否则设置为false。
* * @return
* - ESP_OK表示成功
* - ESP_ERR_INVALID_ARG参数错误
* -未安装ESP_FAIL驱动
*/
esp_err_t uart_set_loop_back(uart_port_t uart_num, bool loop_back_en);/**
* 配置UART RX超时中断的行为。
* 当always_rx_timeout为true时,即使FIFO已满也会触发超时中断。
* 这个函数可以导致额外的超时中断触发只发送超时事件。
* 只有当你想确保超时中断总是发生在字节流之后,才调用这个函数。
* @param uart_num UART编号
* @param always_rx_timeout_en设置为false启用超时中断的默认行为,
*设置为true总是触发超时中断。
*/
Void uart_set_always_rx_timeout(uart_port_t uart_num, bool always_rx_timeout_en);

ESP32 (UART 485通讯)-串口之485通讯(3)相关推荐

  1. ESP32 (UART 接收发送)-串口之接收发送通讯(4)

    提示:本博客作为学习笔记,有错误的地方希望指正 文章目录 一.ESP32串口介绍 二.硬件设计 三.实现代码 四.串口实验演示结果 五.ESP32串口函数API 5.1.uart_types.h文件中 ...

  2. 西门子1200PLC模板通讯程序,包含多种通讯Modbus-RTU(485),S7通讯

    西门子1200PLC模板通讯程序,包含多种通讯Modbus-RTU(485),S7通讯,Modbus-TCP,TCP/IP等,简单明了 编号:54112654376937554tbNick_mtjdq

  3. 串口RS232/485/UART转CANbus总线转换器网关CSM100模块CANCOM

    串口RS232/485/UART转CANbus总线转换器网关CSM100模块CANCOM CANUART-100T系列智能双向UART转CAN模块具有一路TTL UART串口通道和一路CAN通道,实现 ...

  4. 三菱FX1N PLC 485与三菱变频器modbus通讯

    三菱FX1N PLC 485与三菱变频器modbus通讯可直接拿来实用了,三菱FX PLC与三菱变频器通讯 采用器件:三菱FX1N PLC,FX1N485BD板,1台三菱E740变频器,三菱FX2N ...

  5. 三菱FX1N PLC 485与三菱变频器modbus通讯 对变频器进行频率设定,加减速时间设置,正反转,启停控制

    三菱FX1N PLC 485与三菱变频器modbus通讯可直接拿来实用了,三菱FX PLC与三菱变频器通讯 采用器件:三菱FX1N PLC,FX1N485BD板,1台三菱E740变频器,三菱FX2N ...

  6. 三菱FX1N PLC 485与三菱变频器modbus通讯可直接拿来实用了,三菱FX PLC与三菱变频器通讯

    三菱FX1N PLC 485与三菱变频器modbus通讯可直接拿来实用了,三菱FX PLC与三菱变频器通讯 采用器件:三菱FX1N PLC,FX1N485BD板,1台三菱E740变频器,三菱FX2N ...

  7. 多个485串联_RS-485接口器件通讯无故障偏置电路的原理和设计

    RS-485接口通信在某些情况下,例如当一个驱动器释放总线给另一个驱动器时,会出现短时间总线上没有驱动电流的情况.此时,两端的匹配电阻会将差分总线电压放至0V,这对于许多RS-485接收器来说是一个未 ...

  8. ESP32 (UART EVENT)-串口事件学习(1)

    提示:本博客作为学习笔记,有错误的地方希望指正 文章目录 一.ESP32串口介绍 二.硬件设计 三.实现代码 四.串口实验演示结果 五.ESP32串口函数API 5.1.uart_types.h文件中 ...

  9. 串口232,485转以太网模块 串口232,485转以太网模块 TCP/IP 串口协议转换模块

    串口232,485转以太网模块 串口232,485转以太网模块 TCP/IP 串口协议转换模块                                                      ...

最新文章

  1. 报告:AI岗年薪下降8.9%,收入不及2018年
  2. matlab如何求指标的权向量_层次分析模型(AHP)及其MATLAB实现
  3. python写一个聊天程序_python实现一个简单的网络聊天程序
  4. (十)Spring 与 MVC 框架整合
  5. 《金色梦乡》金句摘抄(五)
  6. 从PeopleEditor控件中取出多用户并更新到列表
  7. PaddleOCR和ChineseOCR的对比
  8. java获取年的第一天和最后一天_java中如何获取当前年份的第一天和最后一天
  9. linux条件变量唤醒丢失,多线程编程精髓(三)
  10. 梭织布印染后整理瑕疵最全解读
  11. mysql 自定义函数 找不到表,mysql判断表记录是否存在,不存在则插入新纪录
  12. oracle查询时使用case,Oracle查询语句中Casewhen的使用
  13. html使用iframe包含pdf文件,HTMLiframe用法总结收藏.pdf
  14. 小学-知识与能力【7】
  15. 华为程序员频交 Linux 内核补丁遭质疑,管理员后续回应:承认贡献,但请不要琐碎提交
  16. Scala学习笔记(2)-基础语法
  17. V2X和D2D的链路级sidelink上的区别
  18. CCF公布国家集训队50进15名单!5月确定IOI2019选手!
  19. 会议或期刊是否被EI
  20. 1.23 定语从句 感叹句

热门文章

  1. Linux 安装宝塔
  2. android GoogleMap画导航线路图 路径规划(Directions)
  3. boost:filesystem
  4. AT32 与SRAM/PSRAN/NOR FLASH的接口简介
  5. 等长走线 | 菊花链拓扑结构
  6. bootstrapValidator验证 表单验证通过但无法提交form的原因
  7. Java之校验qq号
  8. 安装Mathtype7.4之后显示,在Word文档中粘贴东西时显示:运行时错误‘53’,文件未找到:MathPage.WLL
  9. 积分可以当钱用,阿里推出个人「碳账户」
  10. top1 top5错误率概念