FreeModbus库介绍

FreeModbus是一个简单易用的Modbus RTU库,它允许同时运行多个独立的Modbus RTU从机。这个库的特点在于它直接使用0xxxx-4xxxx寄存器空间,无需手动处理寄存器映射等繁琐问题,并且可以限制使用的最大寄存器数量。它提供了定时器接口和串口收发接口,可以根据硬件需求进行配置,非常符合常规使用Modbus通信的思路。

FreeModbus库介绍及Modbus变量地址解释插图1

使用说明

以下是使用FreeModbus库的基本步骤:

  1. 搭建从机 1.1 引入库:将FreeModbus库添加到你的工程中,并引入头文件#include “mdrtuslave.h”。 1.2 创建Modbus RTU从机:
   #include "mdrtuslave.h"

   #define SLAVE_ID 5
   #define BUAD_RATE 9600
   static ModbusRTUSlaveHandler mdhandler;

   static mdVOID popchar(ModbusRTUSlaveHandler handler, mdU8 c)
   {
      // 此处添加串口发送代码
   }

   static void ModbusInit()
   {
      struct ModbusRTUSlaveRegisterInfo info;
      info.slaveId = SLAVE_ID;
      info.usartBaudRate = BUAD_RATE;
      info.mdRTUPopChar = popchar;
      mdCreateModbusRTUSlave(&mdhandler, info);
   }

   ModbusInit();

1.3 调用心跳函数:

   #define TIMER_UTIME  100  //定时器周期为100us

   static void timer_handler(void)  //100us定时器回调函数
   {
      mdhandler->portRTUTimerTick(mdhandler, TIMER_UTIME);
   }

1.4 从串口接收数据:

   static void usart_rec_handler(char *buf, size_t len)   //串口接收中断函数
   {
      for (size_t i = 0; i < len; i++)
      {
         mdhandler->portRTUPushChar(mdhandler, buf[i]);
      }
   }
  1. 写入和读取从机寄存器 2.1 读取输入线圈:
   mdBit bit;
   mdU32 addr = 0;
   mdSTATUS ret;
   ret = mdhandler->registerPool->mdReadInputCoil(mdhandler->registerPool, addr, &bit);   //读取输入线圈,设备地址为10001
   if (ret == mdFALSE)
   {
      printf("读取失败\n");
   }

2.2 读取保持寄存器:

   mdU16 data;
   mdU32 addr = 0;
   mdSTATUS ret;
   ret = mdhandler->registerPool->mdReadHoldRegister(mdhandler->registerPool, addr, &data);    //读取保持寄存器,地址为40001
   if (ret == mdFALSE)
   {
      printf("读取失败\n");
   }

2.3 写入输入线圈:

   mdBit bit = mdHigh;
   mdU32 addr = 0;
   mdSTATUS ret;
   ret = mdhandler->registerPool->mdWriteInputCoil(mdhandler->registerPool, addr, bit);   //写入输入线圈,地址为10001,高电平
   if (ret == mdFALSE)
   {
      printf("写入失败\n");
   }

2.4 写入保持寄存器:

   mdU16 data = 0x1234;
   mdU32 addr = 0;
   mdSTATUS ret;
   ret = mdhandler->registerPool->mdWriteHoldRegister(mdhandler->registerPool, addr, data);  //写入保持寄存器,地址为40001,大小为0x1234
   if (ret == mdFALSE)
   {
      printf("写入失败\n");
   }

2.5 其他寄存器操作API(推荐方式):

   /*不推荐*/
    mdSTATUS (*mdReadBit)(RegisterPoolHandle handler,mdU32 addr,mdBit *bit);
    mdSTATUS (*mdWriteBit)(RegisterPoolHandle handler,mdU32 addr,mdBit bit);
    mdSTATUS (*mdReadBits)(RegisterPoolHandle handler,mdU32 addr,mdU32 len,mdBit *bits);
    mdSTATUS (*mdWriteBits)(RegisterPoolHandle handler,mdU32 addr,mdU32 len,mdBit *bits);
    mdSTATUS (*mdReadU16)(RegisterPoolHandle handler,mdU32 addr,mdU16 *data);
    mdSTATUS (*mdWriteU16)(RegisterPoolHandle handler,mdU32 addr,mdU16 data);
    mdSTATUS (*mdReadU16s)(RegisterPoolHandle handler,mdU32 addr,mdU32 len,mdU16 *data);
    mdSTATUS (*mdWriteU16s)(RegisterPoolHandle handler,mdU32 addr,mdU32 len,mdU16 *data);

   /*推荐*/
    mdSTATUS (*mdReadCoil)(RegisterPoolHandle handler, mdU32 addr, mdBit* bit);  //设备地址1~10000,addr=0 -> 设备1
    mdSTATUS (*mdReadCoils)(RegisterPoolHandle handler, mdU32 addr, mdU32 len, mdBit* bits);
    mdSTATUS (*mdWriteCoil)(RegisterPoolHandle handler, mdU32 addr, mdBit bit);
    mdSTATUS (*mdWriteCoils)(RegisterPoolHandle handler, mdU32 addr, mdU32 len, mdBit* bits);
    mdSTATUS (*mdReadInputCoil)(RegisterPoolHandle handler, mdU32 addr, mdBit* bit);   //设备地址10001~20000,addr=0 -> 设备10001
    mdSTATUS (*mdReadInputCoils)(RegisterPoolHandle handler, mdU32 addr, mdU32 len, mdBit* bits);
    mdSTATUS (*mdWriteInputCoil)(RegisterPoolHandle handler, mdU32 addr, mdBit bit);
    mdSTATUS (*mdWriteInputCoils)(RegisterPoolHandle handler, mdU32 addr, mdU32 len, mdBit* bits);
    mdSTATUS (*mdReadInputRegister)(RegisterPoolHandle handler, mdU32 addr, mdU16* data);//设备地址30001~40000,addr=0 -> 设备30001
    mdSTATUS (*mdReadInputRegisters)(RegisterPoolHandle handler, mdU32 addr, mdU32 len, mdU16* data);
    mdSTATUS (*mdWriteInputRegister)(RegisterPoolHandle handler, mdU32 addr, mdU16 data);
    mdSTATUS (*mdWriteInputRegisters)(RegisterPoolHandle handler, mdU32 addr, mdU32 len, mdU16* data);
    mdSTATUS (*mdReadHoldRegister)(RegisterPoolHandle handler, mdU32 addr, mdU16* data);//设备地址40001~50000,addr=0 -> 设备40001
    mdSTATUS (*mdReadHoldRegisters)(RegisterPoolHandle handler, mdU32 addr, mdU32 len, mdU16* data);
    mdSTATUS (*mdWriteHoldRegister)(RegisterPoolHandle handler, mdU32 addr, mdU16 data);
    mdSTATUS (*mdWriteHoldRegisters)(RegisterPoolHandle handler, mdU32 addr, mdU32 len, mdU16* data);

还有其他寄存器操作API,比如mdReadCoil、mdReadInputCoil、mdReadInputRegister等,它们更符合Modbus变量地址的规范,可以更方便地读取和写入寄存器值。

Modbus变量地址

Modbus变量地址表示了Modbus通信中不同寄存器的位置和类型。这些地址是Modbus协议的一部分,用于指定要读取或写入的寄存器。以下是常见的Modbus变量地址及其含义:

  • 0xxxx:这是线圈寄存器地址,对应Function Code 01(读取线圈)和Function Code 05(写单个线圈)。它们用于控制开关设备等,是可读写的。
  • 1xxxx:这是输入线圈寄存器地址,对应Function Code 02(读取输入线圈)。它们用于表示输入信号,通常是只读的。
  • 3xxxx:这是输入寄存器地址,对应Function Code 04(读取输入寄存器)。每个寄存器表示一个16位无符号整数,通常是只读的。
  • 4xxxx:这是保持寄存器地址,对应Function Code 03(读取保持寄存器)、Function Code 06(写单个保持寄存器)和Function Code 16(写多个保持寄存器)。它们用于存储设备参数、状态等信息,是可读写的。

这些地址类型和功能码是Modbus通信的核心部分,通过它们,你可以读取和写入设备的不同寄存器,实现对设备的监控和控制。

总之,FreeModbus库提供了方便的方式来创建Modbus RTU从机,并进行寄存器的读取和写入操作,而Modbus变量地址则定义了不同寄存器的类型和功能,帮助

相关新闻

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Comments(2)

邮箱

cloud@modbus.cn

QQ
QQ
微信
微信
SHARE
TOP