C语言ESp32中的Modbus寄存器映射



我正在使用ESP32。我想用Modbus RTU与外部世界通信。ESP32将成为奴隶。如何用c语言创建一些modbus寄存器。知道吗?它只是一个简单的C表?非常感谢

我做了你想做的同样的事情,不是用ESP32,但它是一样的。

基本上,您将所有想要作为modbus寄存器访问的变量放在一个精确的位置,可能是一个结构。

例如

struct modbusmap_t {
uint16_t    speed;    // this has modbus address 0
unit16_t    cooler;   // ...and this address 1
...
} modbusregs;

您的设备是从设备,因此您将实现一个接收modbus命令的服务器。当请求写入寄存器"0"时;N〃;收到时,您可以简单地使用访问该寄存器

*((uint16_t *) &modbusregs + N) = requestvalue;

对于阅读,同样适用:

uint16result = *((uint16_t *) &modbusregs + N);

还有其他方法可以做到这一点,例如通过工会。

总之,关键是将所有可作为modbus寄存器访问的变量放在一个已知的有序位置,并使用指针或数组来读取/写入它们。对于bit(modbus线圈(来说,需要更多的技巧,但想法是一样的。

在这个例子中;modbus寄存器0〃;映射到变量";速度";在您的来源中。Modbus没有符号的概念,但您可以使用2-完成或添加偏移(32000表示0速度,32010表示速度10,31990表示速度-10,依此类推(来管理它。

您可以使用这个简单的代码并根据需要进行扩展我从esp32 idf源代码推迟

#include <math.h>
#include <stdio.h>
#include <time.h>
#include <stdint.h>
typedef struct
{
float holding_data0;
float holding_data1;
float holding_data2;
float holding_data3;
uint16_t test_regs[150];
float holding_data4;
float holding_data5;
float holding_data6;
float holding_data7;
} holding_reg_params_t;
extern holding_reg_params_t holding_reg_params;
#define HOLD_OFFSET(field) ((uint16_t)(offsetof(holding_reg_params_t, field) >> 1))
#define MB_REG_HOLDING_START_AREA0 (HOLD_OFFSET(holding_data0))
#define MB_REG_HOLDING_START_AREA1 (HOLD_OFFSET(holding_data4))
/**
* @brief Type of Modbus parameter
*/
typedef enum
{
MB_PARAM_HOLDING = 0x00, /*!< Modbus Holding register. */
MB_PARAM_INPUT,          /*!< Modbus Input register. */
MB_PARAM_COIL,           /*!< Modbus Coils. */
MB_PARAM_DISCRETE,       /*!< Modbus Discrete bits. */
MB_PARAM_COUNT,
MB_PARAM_UNKNOWN = 0xFF
} mb_param_type_t;
/**
* @brief Parameter storage area descriptor
*/
typedef struct
{
uint16_t start_offset; /*!< Modbus start address for area descriptor */
mb_param_type_t type;  /*!< Type of storage area descriptor */
void *address;         /*!< Instance address for storage area descriptor */
size_t size;           /*!< Instance size for area descriptor (bytes) */
} mb_register_area_descriptor_t;
mb_register_area_descriptor_t reg_area; // Modbus register area descriptor structure
int main()
{
holding_reg_params_t holding_reg_params = {0};
mb_register_area_descriptor_t reg_area; // Modbus register area descriptor structure
holding_reg_params.holding_data0 = 1.34;
holding_reg_params.holding_data1 = 2.56;
holding_reg_params.holding_data2 = 3.78;
holding_reg_params.holding_data3 = 4.90;
holding_reg_params.holding_data4 = 5.67;
holding_reg_params.holding_data5 = 6.78;
holding_reg_params.holding_data6 = 7.79;
holding_reg_params.holding_data7 = 8.80;
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_params.holding_data0; // Set pointer to storage instance
// Set the size of register storage instance = 150 holding registers
reg_area.size = (size_t)(HOLD_OFFSET(holding_data4) - HOLD_OFFSET(test_regs));
*((float *)reg_area.address + reg_area.start_offset + 0) = 100;
*((float *)reg_area.address + reg_area.start_offset + 1) = 200;
*((float *)reg_area.address + reg_area.start_offset + 2) = 300;
*((float *)reg_area.address + reg_area.start_offset + 3) = 400;
*((uint16_t *)reg_area.address + reg_area.start_offset + 4) = 500;// be careful its wrong!
// ESP_ERROR_CHECK(mbc_slave_set_descriptor(reg_area));
reg_area.type = MB_PARAM_HOLDING;                             // Set type of register area
reg_area.start_offset = MB_REG_HOLDING_START_AREA1;           // Offset of register area in Modbus protocol
reg_area.address = (void *)&holding_reg_params.holding_data4; // Set pointer to storage instance
reg_area.size = sizeof(float) << 2;                           // Set the size of register storage instance
// ESP_ERROR_CHECK(mbc_slave_set_descriptor(reg_area));
// getchar();
}

最新更新