Modbus RTU 程序范例 (modbus_comm_load)

Modbus

简介

Modbus RTU 程序范例 (modbus_comm_load) 展示如何使用 RTU 协议与 Modbus 从设备进行通信。本范例包括一个主设备和一个从设备的源代码。

设置

要运行本范例,您需要:一台支持 Modbus RTU 的主设备一台支持 Modbus RTU 的从设备一根连接主设备和从设备的 RS-485 电缆

源代码

主设备源代码位于 `/examples/modbus/modbus_comm_load/main.c`。```cinclude "esp_log.h"include "esp_system.h"include "esp_sleep.h"include "soc/uart_struct.h"include "driver/uart.h"include "driver/gpio.h"include "modbus_parser.h"include "sdkconfig.h"static const char TAG = "Modbus_Comm";// RS-485 引脚定义define UART_NUM UART_NUM_1define TXD_PIN GPIO_NUM_2define RXD_PIN GPIO_NUM_3define RTS_PIN GPIO_NUM_5define CTS_PIN GPIO_NUM_4// 接收缓冲区大小define RX_BUF_SIZE 256// 传输寄存器地址define MODBUS_REG_ADDR 0// 主设备 IDdefine ESP_SLAVE_ID 1typedef struct { uint8_t buffer[RX_BUF_SIZE];uint16_t buffer_length;} rx_buffer_t;static rx_buffer_t rx;void send_request(uint8_t slave_addr, uint16_t length);bool send_data(uint8_t data, size_t size);bool receive_data(uint8_t buf, size_t length);void app_main(void){// 初始化 UART 引脚uart_config_t uart_config = {.baud_rate = 115200,.data_bits = UART_DATA_8_BITS,.parity = UART_PARITY_DISABLE,.stop_bits = UART_STOP_BITS_1,.flow_ctrl = UART_HW_FLOWCTRL_RTS_CTS};uart_param_config(UART_NUM, &uart_config);uart_set_pin(UART_NUM, TXD_PIN, RXD_PIN, RTS_PIN, CTS_PIN);// 初始化 Modbusmodbus_parser_init();uint8_t request_pdu = modbus_create_request(MODBUS_FUNC_READ_HOLDING_REGISTERS, ESP_SLAVE_ID, MODBUS_REG_ADDR, 2);size_t request_length = request_pdu[MB_PDU_LEN_POS] + MB_PDU_SIZE_MIN;// 发送请求send_request(ESP_SLAVE_ID, request_length);send_data(request_pdu, request_length);// 接收响应if (receive_data(rx.buffer, RX_BUF_SIZE)) {// 解析响应esp_err_t err = modbus_parse_response(rx.buffer, rx.buffer_length);if (err != ESP_OK) {ESP_LOGE(TAG, "Modbus 解析响应错误: %d", err);} else { ESP_LOGI(TAG, "Modbus 响应解析成功");}} else {ESP_LOGE(TAG, "Modbus 未收到响应");}}void send_request(uint8_t slave_addr, uint16_t length){uint8_t data[4];data[0] = slave_addr;data[1] = 0x03;data[2] = (uint8_t)(length >> 8);data[3] = (uint8_t)length;send_data(data, 4);}bool send_data(uint8_t data, size_t size){if (!data || size == 0) {return false;}uart_write_bytes(UART_NUM, (const char )data, size);return true;}bool receive_data(uint8_t buf, size_t length){if (!buf || length == 0) {return false;}uart_flush(UART_NUM);rx.buffer_length = 0;while (rx.buffer_length < length) {size_t length_to_read = length - rx.buffer_length;int len = uart_read_bytes(UART_NUM, rx.buffer + rx.buffer_length, length_to_read, 100 / portTICK_RATE_MS);if (len > 0) {rx.buffer_length += len;} else {return false;}}return true;}```从设备源代码位于 `/examples/modbus/modbus_comm_load/slave.c`。```cinclude "esp_log.h"include "soc/uart_struct.h"include "driver/uart.h"include "driver/gpio.h"include "modbus_parser.h"include "sdkconfig.h"static const char TAG = "Modbus_Slave";// RS-485 引脚定义define UART_NUM UART_NUM_1 define TXD_PIN GPIO_NUM_2define RXD_PIN GPIO_NUM_3define RTS_PIN GPIO_NUM_5define CTS_PIN GPIO_NUM_4// 接收缓冲区大小define RX_BUF_SIZE 256// 从设备 IDdefine ESP_SLAVE_ID 1// 从设备寄存器uint16_t slave_registers[1000] = {0};typedef struct {uint8_t buffer[RX_BUF_SIZE];uint16_t buffer_length;} rx_buffer_t;static rx_buffer_t rx;bool send_data(uint8_t data, size_t size);bool receive_data(uint8_t buf, size_t length);void app_main(void){// 初始化 UART 引脚uart_config_t uart_config = {.baud_rate = 115200,.data_bits = UART_DATA_8_BITS,.parity = UART_PARITY_DISABLE,.stop_bits = UART_STOP_BITS_1,.flow_ctrl = UART_HW_FLOWCTRL_RTS_CTS};uart_param_config(UART_NUM, &uart_config);uart_set_pin(UART_NUM, TXD_PIN, RXD_PIN, RTS_PIN, CTS_PIN);// 初始化 Modbusmodbus_parser_init();while (true) {// 接收请求if (receive_data(rx.buffer, RX_BUF_SIZE)) {// 解析请求esp_err_t err = modbus_parse_request(rx.buffer, rx.buffer_length);if (err != ESP_OK) {ESP_LOGE(TAG, "Modbus 解析请求错误: %d", err);} else {ESP_LOGI(TAG, "Modbus请求解析成功");// 准备响应uint8_t response_pdu = modbus_create_response(ESP_SLAVE_ID, modbus_get_func_code

本文原创来源:电气TV网,欢迎收藏本网址,收藏不迷路哦!

相关阅读

添加新评论