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 - );
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 = ;
int data_len = ;
char parity = 'E';
int stop_bits = ;
int modbus_mode = ; // ASCII
int comm_type = ; // 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 == -)
{
ActStatus.Text = @"串口打开失败";
}
byte[] sendbuf = new byte[];
byte[] recvbuf = new byte[];
int modbusAddr = ;
int modbusFunc = ;
int modbusAddrRet = ;
int modbusFuncRet = ;
int sendlen = ;
int i; strReq = ReqData.Text; const string strValid = "0123456789ABCDEF"; if (strReq.Length < )
{
ActStatus.Text = @"长度不够";
closeModbus(connNum);
return;
} if (strReq.Length % != )
{
ActStatus.Text = @"发送数据必须为偶数位";
closeModbus(connNum);
return;
} for (i = ; i < strReq.Length; i++)
{
if (strValid.IndexOf(strReq.ToUpper()[i]) == -)
{
ActStatus.Text = @"包含无效数据";
closeModbus(connNum);
return;
}
} for (i = ; i <= strReq.Length - ; i += ) // 将发送数据放入缓冲区
{
string strConvert = strReq[i] + strReq[i + ].ToString();
if (i == )
modbusAddr = Convert.ToByte(strConvert, );
else if (i == )
modbusFunc = Convert.ToByte(strConvert, );
else
{
sendbuf[sendlen] = Convert.ToByte(strConvert, );
sendlen++;
}
} // 发送数据
int req = RequestData(comm_type, connNum, modbusAddr, modbusFunc, sendbuf, sendlen); // modbus request
if (req == -)
{
ActStatus.Text = @"数据发送失败";
closeModbus(connNum);
return;
} // 接收数据
int res = ResponseData(comm_type, connNum, ref modbusAddrRet, ref modbusFuncRet, recvbuf); // modbus response
if (res > )
{
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 = ; 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);
}
}
}

PLC与PC通讯的更多相关文章

  1. PC高级语言与施耐德、罗克韦尔、台达等PLC的Modbus通讯源代码(ModbusTCP.DLL/ModbusRTU.DLL)

    1.0  通讯组件概述 该类通讯组件适用于基于PC高级语言的工业自动化控制系统,用于PC与可编程控制器(PLC).智能仪表等进行数据通讯.组件采用动态链接库文件(*.DLL)的形式,在PC系统的项目工 ...

  2. PC-1500与PC通讯

    目录 第1章说明    2 第2章音频通讯    3 2.1 下载    3 2.2 上传    8 2.2.1 操作    8 2.2.2 音量    8 2.3 直接将BASIC代码转换为wav文 ...

  3. Android 手机应用开发经验 之 通过Socket(TCP/IP)与PC通讯

    Android 是一个开源的手机操作系统平台,已经被非常多的开发者视作未来最有潜力的智能手机操作系统.而且,在很短的时间内就在Android Market上出现大量的第三方应用程序,供用户下载与使用, ...

  4. c#上位机与三菱PLC(FX3U)串口通讯

    项目中会经常用到上位机与PLC之间的串口通信,本文介绍一下C#如何编写上位机代码 与三菱FX3U进行通讯 1. 第一种方法是自己写代码实现,主要代码如下: //对PLC的Y7进行置1 byte[] Y ...

  5. (原创)理解主机设备(PLC,PC机)之间的以太网通信

    主机设备:PC机,PLC 网络设备:家用路由器 局域网包括了有线局域网和无线局域网(WIFI).怎么去使用2者? 网络设备的职责最终目的为了帮助2台主机的数据传输.路由器,交换机范围不同,目的相同.在 ...

  6. 台达PLC开发笔记(二):台达PLC设置主机通讯参数为RTU并成功通讯

    前言   前面使用485和网口与台达成功建立通讯,但是485是使用用的ASICC模式,多数情况下是使用RTU模式提升通讯效率.   下载安装台达ISPSoft软件   官网下载地址:https://d ...

  7. C#与西门子PLC通讯

    1.0  通讯组件概述 通讯组件用于PC与可编程控制器(PLC).智能仪表等进行数据通讯,适用于基于PC高级语言的工业自动化控制系统.组件采用动态链接库文件(*.DLL)的形式,在PC系统的项目工程里 ...

  8. Arcgis for Js之加载wms服务

    概述:本节讲述Arcgis for Js加载ArcgisServer和GeoServer发布的wms服务. 1.定义resourceInfo var resourceInfo = { extent: ...

  9. Quartz动态添加,修改,删除任务(暂停,任务状态,恢复,最近触发时间)

    首页 博客 学院 下载 图文课 论坛 APP 问答 商城 VIP会员 活动 招聘 ITeye GitChat 写博客 小程序 消息 登录注册 关闭 quartz_Cron表达式一分钟教程 09-05 ...

随机推荐

  1. Spring @Import注解 —— 导入资源

    在应用中,有时没有把某个类注入到IOC容器中,但在运用的时候需要获取该类对应的bean,此时就需要用到@Import注解.示例如下: 先创建两个类,不用注解注入到IOC容器中,在应用的时候在导入到当前 ...

  2. Makefile 书写规则

    1.1 Makefile的规则 在讲述这个Makefile之前,还是让我们先来粗略地看一看Makefile的规则. target ... : prerequisites ...   command   ...

  3. GitHub从小白到熟悉<四>

    GitHub issue 使用教程 创建 一个issue  (显示所有bug 或者 说 交流的 问题列表)

  4. HTML5网页文档结构

    2.1     Web标准 Web标准,使得Web开发更加容易.Web标准由万维网联盟(W3C)制定. 2.1.1          Web标准概述 Web标准的最终目的就是保证每个人都有权力访问相同 ...

  5. 解决WordPress百度分享图标不显示问题

    最近在帮朋友维护博客时,发现他的百度分享居然不能使用了,首先很多人会认为,百度分享挂在那里就是一种摆设,又没有几个人去分享,有什么含义呢?其实挂百度分享的含义是非常重要的,网站增加一个百度分享是可以增 ...

  6. 使用git保存管理代码

    1.git是个代码版本管理软件,类似SVN github是个网站,提供git服务,我们只需要注册个账号,就可以使用它的git服务,不需要自己部署git系统 git需要先在电脑端安装,安装完成后,讲产生 ...

  7. C#中的编译为什么不叫Compile而叫build

    是因为Build包含了compile,build既compile了你自己的代码,又把你compile的Assembly和引用别人的Assembly放在一起buiid.

  8. 客户端相关知识学习(一)之混合开发,为什么要在App中使用H5页面以及应用场景、注意事项

    混合开发 随着移动互联网的高速发展,常规的开发速度已经渐渐不能满足市场需求.原生H5混合开发应运而生,目前,市场上许多主流应用都有用到混合开发,例如支付宝.美团等.下面,结合我本人的开发经验,简单谈一 ...

  9. scala新版本学习(3)

    1.REPL:读取->求值->打印->循环.Scala程序将输入的内容快速的编译成为字节码,然后字节码文件交给Java虚拟机进行执行. 2.val是值不可变,var值可变.在变量声明 ...

  10. 10 Scrapy框架持久化存储

    一.基于终端指令的持久化存储 保证parse方法中有可迭代类型对象(通常为列表or字典)的返回,该返回值可以通过终端指令的形式写入指定格式的文件中进行持久化操作. 执行输出指定格式进行存储:将爬取到的 ...