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);
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/LicwStack/p/8974179.html
今日推荐