NModbus的主站开发
1.开发环境要求:PC端作为主站,控制器作为从站
2.PC端初始化代码:
serialPort = new SerialPort();
serialPort.PortName = "COM1";
serialPort.BaudRate = 9600;
serialPort.DataBits = 8;
serialPort.StopBits = StopBits.One;
serialPort.Parity = Parity.Even;
master = ModbusSerialMaster.CreateRtu(serialPort);
master.Transport.ReadTimeout = 2000;
master.Transport.Retries = 10;
master.Transport.WriteTimeout = 2000;
serialPort.Open();
3.PC端读写代码:(slaveNum:从站Slave ID,addrNum:读取寄存器起始地址,len:读取寄存器长度)功能码03
ushort[] recv = master.ReadHoldingRegisters((byte)slaveNum, (ushort)addrNum, (byte)len);
4.控制器收到指令格式:
如0A 03 9C 47 00 01 1B 34
0A-SlaveID
03-功能码
9C-寄存器地址高位
47 -寄存器地址低位
00 -读取长度高位
01-读取长度低位
1B 34-校验位
5.Modbus Slave工具测试
Modbus的从站开发
1.开发环境要求:PC作为从站,控制器作为主站,从站启动监听,触发事件,更新数据库至DataStore
2.PC端初始化代码:
comPort.PortName = "COM1";
comPort.BaudRate = 9600;
comPort.DataBits = 8;
comPort.Parity = Parity.Even;
comPort.StopBits = StopBits.One;
comPort.Open();
slave = ModbusSerialSlave.CreateRtu(slaveID, comPort);
slave.ModbusSlaveRequestReceived += new EventHandler(Modbus_Request_Event);
slave.DataStore = Modbus.Data.DataStoreFactory.CreateDefaultDataStore();
slave.DataStore.DataStoreWrittenTo += new EventHandler(Modbus_DataStoreWriteTo);
slave.Listen();
主站触发请求事件代码:
private void Modbus_Request_Event(object sender, Modbus.Device.ModbusSlaveRequestEventArgs e)
{
try
{
//request from master
byte fc = e.Message.FunctionCode;
byte[] data = e.Message.MessageFrame;
byte[] byteStartAddress = new byte[] { data[3], data[2] };
byte[] byteNum = new byte[] { data[5], data[4] };
Int16 StartAddress = BitConverter.ToInt16(byteStartAddress, 0);
Int16 NumOfPoint = BitConverter.ToInt16(byteNum, 0);
BOOL = true;
FCNUM = fc.ToString();
/*
if (fc.ToString() == "6")
{
//AO
slave.DataStore.HoldingRegisters[StartAddress] = 16;
slave.DataStore.HoldingRegisters[StartAddress + 1] = 17;
}
*/
Console.WriteLine(fc.ToString() + "," + StartAddress.ToString() + "," + NumOfPoint.ToString());
}
catch (Exception exc)
{
FormMainUn.runStatusFile.WriteString("", "readReg", "3");
FormMainUn.runStatusFile.WriteString("","readRegErrorMsg",exc.Message);
MessageBox.Show(exc.ToString());
}
}
写DataStore事件代码:
private void Modbus_DataStoreWriteTo(object sender, Modbus.Data.DataStoreEventArgs e)
{
//this.Text = "DataType=" + e.ModbusDataType.ToString() + " StartAdress=" + e.StartAddress;
int iAddress = e.StartAddress;//e.StartAddress;
switch (e.ModbusDataType)
{
case ModbusDataType.HoldingRegister:
for (int i = 0; i < e.Data.B.Count; i++)
{
//Set AO
slave.DataStore.HoldingRegisters[e.StartAddress + i + 1] = e.Data.B[i];
//e.Data.B[i] already write to slave.DataStore.HoldingRegisters[e.StartAddress + i + 1]
//e.StartAddress starts from 0
//You can set AO value to hardware here
//DoAOUpdate(iAddress, e.Data.B[i].ToString());
iAddress++;
}
break;
case ModbusDataType.Coil:
for (int i = 0; i < e.Data.A.Count; i++)
{
//Set DO
slave.DataStore.CoilDiscretes[e.StartAddress + i + 1] = e.Data.A[i];
//e.Data.A[i] already write to slave.DataStore.CoilDiscretes[e.StartAddress + i + 1]
//e.StartAddress starts from 0
//You can set DO value to hardware here
//DoDOUpdate(iAddress, e.Data.A[i]);
iAddress++;
if (e.Data.A.Count == 1)
{
break;
}
}
break;
}
}
3.PC读数据代码:
public void PCReadDatafromPC(ushort RAddress, out int data)
{
int AOAddress;
RAddresstoAOAddress(RAddress, out AOAddress);
ushort data1 = slave.DataStore.HoldingRegisters[AOAddress];
ushort data2 = slave.DataStore.HoldingRegisters[AOAddress + 1];
ConcatNum(data1, data2, out data);
}
4.寄存器的数据都存储在PC端的DataStore中
5.Modbus Poll工具测试
需安装vspd虚拟串口工具。通过工具添加COM1和COM2两个端口,进行以上测试
测试工具:https://download.csdn.net/download/lx_Angel/12981954