| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- /**
- * @Author: 李建
- * @Date: 2025/8/21 10:45
- * Description: MODBUS 从站
- * Copyright: Copyright (©) 2025 永续绿建. All rights reserved.
- */
- #include <esp_attr.h>
- #include "modbus_slave.h"
- #include "esp_modbus_common.h"
- #include "esp_modbus_slave.h"
- #include "mb_endianness_utils.h"
- #include "lvgl_port.h"
- #define MB_PAR_INFO_GET_TOUT (10)
- #define MB_READ_MASK (MB_EVENT_INPUT_REG_RD \
- | MB_EVENT_HOLDING_REG_RD \
- | MB_EVENT_DISCRETE_RD \
- | MB_EVENT_COILS_RD)
- #define MB_WRITE_MASK (MB_EVENT_HOLDING_REG_WR \
- | MB_EVENT_COILS_WR)
- #define MB_READ_WRITE_MASK (MB_READ_MASK | MB_WRITE_MASK)
- #define MB_READ_WRITE_MASK (MB_READ_MASK | MB_WRITE_MASK)
- static uint16_t holding_reg_area[MB_REG_HOLD_CNT] = {0};
- #define MB_SLAVE_ADDR (1)
- static const char *TAG = "MODBUS_SLAVE";
- mb_param_info_t reg_info;
- static void *mbc_slave_handle = NULL;
- static uint8_t communication_status = 0; // 通讯状态累加值
- static void setup_modbus_regs() {
- holding_reg_area[SLAVE_FAN_LEVEL_REG_ADDRESS] = 2;
- }
- IRAM_ATTR static esp_err_t slave_init() {
- mb_register_area_descriptor_t reg_area = {0};
- // Initialize Modbus controller
- mb_communication_info_t comm_config = {
- .ser_opts.port = MB_PORT_NUM,
- .ser_opts.mode = MB_RTU,
- .ser_opts.baudrate = MB_DEV_SPEED,
- .ser_opts.parity = MB_PARITY_NONE,
- .ser_opts.uid = system_setting.inner_addr,
- .ser_opts.data_bits = UART_DATA_8_BITS,
- .ser_opts.stop_bits = UART_STOP_BITS_1
- };
- ESP_LOGI(TAG, "Modbus controller initialized...");
- esp_err_t err = mbc_slave_create_serial(&comm_config, &mbc_slave_handle); // Initialization of Modbus controller
- MB_RETURN_ON_FALSE((mbc_slave_handle != NULL), ESP_ERR_INVALID_STATE, TAG,
- "mb controller initialization fail.");
- MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG,
- "mb controller initialization fail, returns(0x%x).", (int) err);
- reg_area.type = MB_PARAM_HOLDING; // Set type of register area
- reg_area.start_offset = MB_REG_HOLDING_START_AREA0; // Offset of register area in Modbus protocol
- reg_area.address = (void *) &holding_reg_area[0]; // Set pointer to storage instance
- reg_area.size = sizeof(holding_reg_area) << 1; // Set the size of register storage area in bytes
- err = mbc_slave_set_descriptor(mbc_slave_handle, reg_area);
- // setup modbus regs
- setup_modbus_regs();
- // Set UART pin numbers
- err = uart_set_pin(MB_PORT_NUM, MB_GPIO_TX, MB_GPIO_RX,
- UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
- MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG,
- "mb serial set pin failure, uart_set_pin() returned (0x%x).", (int) err);
- // Set driver mode to Half Duplex
- err = uart_set_mode(MB_PORT_NUM, UART_MODE_UART);
- MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG,
- "mb serial set mode failure, uart_set_mode() returned (0x%x).", (int) err);
- vTaskDelay(5);
- err = mbc_slave_start(mbc_slave_handle);
- MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG,
- "mb controller start fail, returned (0x%x).", (int) err);
- ESP_LOGI(TAG, "Modbus slave stack initialized...");
- return err;
- }
- void modbus_slave_task(void *pv) {
- for (;;) {
- (void) mbc_slave_check_event(mbc_slave_handle, MB_READ_WRITE_MASK);
- ESP_ERROR_CHECK(mbc_slave_get_param_info(mbc_slave_handle, ®_info, MB_PAR_INFO_GET_TOUT));
- const char *rw_str = (reg_info.type & MB_READ_MASK) ? "READ" : "WRITE";
- if (reg_info.type & MB_EVENT_HOLDING_REG_RD) {
- communication_status = 0;
- (void) mbc_slave_lock(mbc_slave_handle);
- holding_reg_area[SLAVE_COMMUNICATION_STATUS_REG_ADDRESS] = 1;
- (void) mbc_slave_unlock(mbc_slave_handle);
- }
- }
- }
- static void communication_status_check_task(void *pv) {
- for (;;) {
- if (communication_status == 0 && guider_ui.screen_main) {
- lvgl_port_lock(0);
- lv_obj_remove_flag(guider_ui.screen_main_label_xf_conn, LV_OBJ_FLAG_HIDDEN);
- system_setting.xf_have=1;
- lvgl_port_unlock();
- }
- communication_status++;
- if (communication_status > 30) {
- communication_status = 30;
- }
- if (communication_status >= 30) {
- holding_reg_area[SLAVE_COMMUNICATION_STATUS_REG_ADDRESS] = 0;
- lvgl_port_lock(0);
- lv_obj_add_flag(guider_ui.screen_main_label_xf_conn, LV_OBJ_FLAG_HIDDEN);
- system_setting.xf_have=0;
- lvgl_port_unlock();
- }
- vTaskDelay(pdTICKS_TO_MS(1000));
- }
- }
- void modbus_slave_init() {
- ESP_LOGI(TAG, "Modbus slave init...");
- ESP_ERROR_CHECK(slave_init());
- vTaskDelay(10);
- xTaskCreate(modbus_slave_task, "modbus_slave_task", 4 * 1024, NULL, 5, NULL);
- xTaskCreate(communication_status_check_task, "check_task", 2 * 1024, NULL, 5, NULL);
- }
- uint16_t modbus_get_reg(uint16_t address) {
- uint16_t value = 0;
- if (address < MB_REG_HOLD_CNT) {
- // ESP_LOGE(TAG, "Modbus slave address %d\n",address);
- value = holding_reg_area[address];
- }
- return value;
- }
- void modbus_set_reg(uint16_t address, uint16_t value) {
- if (address < MB_REG_HOLD_CNT) {
- holding_reg_area[address] = value;
- }
- }
|