PLCとPCの通信
using System;
using System.Windows.Forms;
using Microsoft.Win32; // for the registry table
using System.Runtime.InteropServices; // for the P/Invoke
namespace WindowsApplication1
{
public partial class Form1 : Form
{
private IntPtr _hDmtDll; // handle of a loaded DLL
private delegate void DelegateClose(int connNum); // function pointer for disconnection
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr LoadLibrary(string dllPath);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool FreeLibrary(IntPtr hDll);
//
[DllImport("DMT.dll", CharSet = CharSet.Auto)]
private static extern int RequestData(int commType, int connNum, int slaveAddr, int funcCode, byte[] sendbuf, int sendlen);
[DllImport("DMT.dll", CharSet = CharSet.Auto)]
private static extern int ResponseData(int commType, int connNum, ref int slaveAddr, ref int funcCode, byte[] recvbuf);
//
[DllImport("DMT.dll", CharSet = CharSet.Auto)]
private static extern int OpenModbusSerial(int connNum, int baudRate, int dataLen, char parity, int stopBits, int modbusMode);
[DllImport("DMT.dll", CharSet = CharSet.Auto)]
private static extern void CloseSerial(int connNum);
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string path = Environment.CurrentDirectory;
path = path.Remove(path.Length - 9);
path = path.Replace("\\", "\\\\");
path = path.Insert(path.Length, "DMT.dll"); // obtain the relative path where the DMT.dll resides
_hDmtDll = LoadLibrary(path); // explicitly link to DMT.dll
var myRegKey = Registry.LocalMachine.OpenSubKey("HARDWARE\\DEVICEMAP\\SERIALCOMM");
if (myRegKey == null) return;
foreach (var valueName in myRegKey.GetValueNames())
{
ComPort.Items.Add(myRegKey.GetValue(valueName)
.ToString());
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
FreeLibrary(_hDmtDll);
}
private void button1_Click_1(object sender, EventArgs e)
{
string strReq = "";
string strRes = "";
ActStatus.Text = "";
int baud_rate = 9600;
int data_len = 7;
char parity = 'E';
int stop_bits = 1;
int modbus_mode = 1; // ASCII
int comm_type = 0; // RS-232
var connNum = Convert.ToInt32(ComPort.Text.Replace("COM", ""));
DelegateClose closeModbus = CloseSerial;
var status = OpenModbusSerial(connNum, baud_rate, data_len, parity, stop_bits, modbus_mode);
if (status == -1)
{
ActStatus.Text = @" ";
}
byte[] sendbuf = new byte[1024];
byte[] recvbuf = new byte[1024];
int modbusAddr = 0;
int modbusFunc = 0;
int modbusAddrRet = 0;
int modbusFuncRet = 0;
int sendlen = 0;
int i;
strReq = ReqData.Text;
const string strValid = "0123456789ABCDEF";
if (strReq.Length < 4)
{
ActStatus.Text = @" ";
closeModbus(connNum);
return;
}
if (strReq.Length % 2 != 0)
{
ActStatus.Text = @" ";
closeModbus(connNum);
return;
}
for (i = 0; i < strReq.Length; i++)
{
if (strValid.IndexOf(strReq.ToUpper()[i]) == -1)
{
ActStatus.Text = @" ";
closeModbus(connNum);
return;
}
}
for (i = 0; i <= strReq.Length - 2; i += 2) //
{
string strConvert = strReq[i] + strReq[i + 1].ToString();
if (i == 0)
modbusAddr = Convert.ToByte(strConvert, 16);
else if (i == 2)
modbusFunc = Convert.ToByte(strConvert, 16);
else
{
sendbuf[sendlen] = Convert.ToByte(strConvert, 16);
sendlen++;
}
}
//
int req = RequestData(comm_type, connNum, modbusAddr, modbusFunc, sendbuf, sendlen); // modbus request
if (req == -1)
{
ActStatus.Text = @" ";
closeModbus(connNum);
return;
}
//
int res = ResponseData(comm_type, connNum, ref modbusAddrRet, ref modbusFuncRet, recvbuf); // modbus response
if (res > 0)
{
strRes += modbusAddrRet.ToString("X2");
strRes += modbusFuncRet.ToString("X2");
switch (modbusFuncRet)
{
case 0x01:
case 0x02:
case 0x03:
case 0x04:
case 0x11:
case 0x17:
strRes += res.ToString("X2");
break;
}
for (i = 0; i < res; i++) // recover a string from recvbuf
{
strRes += recvbuf[i].ToString("X2");
}
ActStatus.Text = @" ";
ResData.Text = strRes;
}
else
{
ActStatus.Text = @" ";
ResData.Text = "";
}
closeModbus(connNum);
}
}
}
転載先:https://www.cnblogs.com/LicwStack/p/8974179.html