netlink怎么读_如何使用VB访问NETLINK并读写S7300 PLC数据

一、概述

Hilscher NETLINK用于将西门子MPI协议转换为以太网TCP/IP协议,并提供公开的无需授权的驱动函数库。

NETLINK有三种应用:

1、对于仅仅需要STEP7编程监控和WINCC监控,安装IBHNET127驱动即可,该驱动安装后将在控制面板的Set PG/PC Interface中添加IBHNet MPI/PPI/Profibus三个驱动连接;将STEP7(S7 ONLINE)和WINCC(MPI)的访问点指向以上驱动连接即可。

2、对于第三方组态软件(如KingView、iFix等)通过NETLINK访问PLC,选择我公司开发的OPCServer。

3、对于VB或者VC++(6.0以上版本)的自行开发界面,有两种方法实现通讯:

l调用Hilscher提供的IP Driver驱动函数库进行通讯;

l使用winsock控件进行通讯;

本文对在VB6.0中通过Hilscher IP Driver驱动库读写S7300/400 PLC数据的基本开发步骤作简要描述,具体资料可以参考NETLINK光盘netDEVICE System Software中的Nlmpi_pie.pdf和Drv_Ip.pdf文件,该光盘可到 http://www.gkong.com/co/beichen-automation/index_downloadbbbb 页面中下载。

二、平台和配置

1、平台:bbbbbb2000+SP4,Microsoft VB6.0;

2、软件和驱动安装:Hilscher SYCON软件和IP Driver;

3、硬件要求:NETLINK电缆一根,西门子S7300 CPU一台(如CPU314),以太网交换机一台(如TP-bbbb),以太网电缆;

4、系统配置:如下图所示

三、NETLINK参数配置

如上图所示,将计算机网卡的IP地址配置为192.168.1.10,将NETLINK的RJ45端口链接到交换机端口上,另一端插入CPU314的MPI通讯口,NETLINK是由CPU314的MPI口供电的。如果CPU上已经连接了其他监控设备如触摸屏,则可以选用西门子带编程口的网络插头。

在NETLINK链接到MPI端口后的三分钟内(上电三分钟内)运行[开始]-[程序]-[Hilscher IP Driver]-[NetIdent Demo Program],点击[Start Poll]按钮自动查找网络上的NETLINK,找到后将会显示NETLINK信息,NETLINK出厂默认IP地址为0.0.0.0,选择显示的NETLINK并点击[Set IP]按钮,设置IP地址为192.168.1.88;如果软件找不到NETLINK,请用PING命令检查网络是否链接正确。

注意1:通过NetIdent设定的IP地址是临时的,在NETLINK再次上电后将自动恢复到原来的IP地址;

注意2:NETLINK上电的三分钟内允许通过NetIdent设定其IP地址,三分钟后设定将被拒绝;

设定好NETLINK的IP地址后运行[开始]-[程序]-[SyCon System Configurator],新建项目并添加NETLINK设备,双击NETLINK并设定网络参数,IP地址设为192.168.1.88,选择自动检测接口和自动速率识别,NETLINK的MPI地址设定为1(注意不要和MPI网络上其他站点地址冲突);设定好参数后将其下载到NETLINK。(具体可以参考《NetLINK和IBHNet驱动在SIEMENS STEP7 WINCC中的使用说明.doc》中的描述)

注意3:通过SYCON软件设定的IP地址是永久固定的,在NETLINK再次上电后不会改变;

四、IP Driver参数配置

运行[开始]-[程序]-[Hilscher IP Driver]-[IP Driver Setup],在Connection 0中输入NETLINK的IP地址:192.168.1.88、1099、TCP、Client、5000;

运行[开始]-[程序]-[Hilscher IP Driver]-[IP Driver Test],在菜单[Connection select]中选择Connection 0,连接后进行其他菜单的测试,如[Driver Info]等,如果测试正常说明IP Driver已连接到NETLINK。

五、VB应用

应用举例:

1、按下[循环启动]按钮后周期性读取MW0的数值(间隔100ms),直到按下[停止]按钮。

2、按下[写入新值]按钮命令将新值写入MW0。

3、[复位NETLINK]按钮初始化NETLINK。

演示界面如下图所示:

开发步骤:

1、新建VB EXE工程,将NETLINK光盘中Api\Demo\VBASIC32\CIFUSER.BAS模板文件复制到VB工程中并取消只读属性;然后添加到工程中,打开CIFUSER.BAS模板,加入以下常数申明:

'新增常数

Public Const TASK_TDT_UINT8 = 5

Public Const TASK_TFC_READ = 1

Public Const TASK_TFC_WRITE = 2

2、新建模块Module1,添加以下公共变量和API函数:

Public Const usSize = 288'消息长度常数=288

Public SndMsgRead As MSG_STRUC'读取MW0数据的消息

Public SndMsgWrite As MSG_STRUC'写MWO数据的消息

Public SndMsgReset As MSG_STRUC'复位NETLINK的消息

Public RcvMsg As MSG_STRUC'接收消息

'内存拷贝API

Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

3、在bbbb1代码窗口中添加读写控制变量、三个消息初始化函数、NETLINK链接和读写函数(请参考Nlmpi_pie.pdf文件):

Dim bNetLink_Connected As Boolean'NETLINK链接标记

Dim bStartRead As Boolean'开始循环读取标记

Dim bWrite As Boolean'写数据标记

'初始化读MW0数据的消息

Private Function Initial_SndMsgRead()

SndMsgRead.rx = 3'接收号=3

SndMsgRead.tx = 255'发送号=255

SndMsgRead.ln = 8'读数据长度=8

SndMsgRead.nr = 0'消息号

SndMsgRead.a = 0'应答号=0

SndMsgRead.f = 0'错误号=0

SndMsgRead.b = 0'命令码=16#33(M区数据)

SndMsgRead.e = 0'扩展号=0

SndMsgRead.data(0) = 2'S7300 CPU的MPI地址=2

SndMsgRead.data(1) = 0'数据区=0

SndMsgRead.data(2) = 0'M区起始地址=0(起始地址 MOD 256)

SndMsgRead.data(3) = 0'M区起始地址=0(起始地址 / 256)

SndMsgRead.data(4) = 0'数据索引=0(仅用于DB区)

SndMsgRead.data(5) = 2'读取的字节数=2 (MW0)

SndMsgRead.data(6) = TASK_TDT_UINT8'数据类型=TASK_TDT_UINT8(字节)

SndMsgRead.data(7) = TASK_TFC_READ'功能号=TASK_TFC_READ(读数据)

End Function

'初始化写MW0数据的消息

Private Function Initial_SndMsgWrite()

SndMsgWrite.rx = 3'接收号

SndMsgWrite.tx = 255'发送号

SndMsgWrite.ln = 10'写数据长度=10

SndMsgWrite.nr = 0'消息号

SndMsgWrite.a = 0'应答号=0

SndMsgWrite.f = 0'错误号=0

SndMsgWrite.b = 0'命令码=16#33(M区数据)

SndMsgWrite.e = 0'扩展号=0

SndMsgWrite.data(0) = 2'S7300 CPU的MPI地址=2

SndMsgWrite.data(1) = 0'数据区=0

SndMsgWrite.data(2) = 0'M区起始地址=0(起始地址 MOD 256)

SndMsgWrite.data(3) = 0'M区起始地址=0(起始地址 / 256)

SndMsgWrite.data(4) = 0'数据索引=0(仅用于DB区)

SndMsgWrite.data(5) = 0'要写的字节数=2 (MW0)

SndMsgWrite.data(6) = TASK_TDT_UINT8'TASK_TDT_UINT8

SndMsgWrite.data(7) = TASK_TFC_WRITE'TASK_TFC_WRITE

SndMsgWrite.data(8) = 0'待写数据低字节=0

SndMsgWrite.data(9) = 0'待写数据高字节=0

End Function

'初始化复位NETLINK消息

Private Function Initial_SndMsgReset()

SndMsgReset.rx = 0'接收号=0(NETLINK 系统)

SndMsgReset.tx = 255'发送号

SndMsgReset.ln = 1'数据长度

SndMsgReset.nr = 1'消息号

SndMsgReset.a = 0'应答号=0

SndMsgReset.f = 0'错误号=0

SndMsgReset.b = 1'命令码=1

SndMsgReset.e = 0'扩展号=0

SndMsgReset.data(0) = 1'=1

End Function

'NETLINK链接

Private Function NetLINK_Connect()

Dim sRet As Integer

sRet = DevOpenDriver(0)'打开驱动

If sRet = DRV_NO_ERROR Then

sRet = DevInitBoard(0, 0)               '初始化板卡

If sRet = DRV_NO_ERROR Then

bNetLink_Connected = True           '设置NETLINK链接标记

Else

MsgBox "找不到NETLINK!", vbCritical + vbOKOnly, "错误"

DevExitBoard 0                      '退出板卡

DevCloseDriver 0                    '关闭驱动

End If

Else

MsgBox "找不到NETLINK驱动!", vbCritical + vbOKOnly, "错误"

DevExitBoard 0

DevCloseDriver 0

End If

End Function

'读MW0数据

Private Function ReadValue()

Dim sRet As Integer, RcvData(0 To 1) As Byte, Val_INT16 As Integer

sRet = DevPutMessage(0, SndMsgRead, 500)'发送读取数据的消息

If sRet = DRV_NO_ERROR Then'如果发送消息无错误

sRet = DevGetMessage(0, usSize, RcvMsg, 500)    '接收返回消息

'如果接收无错误且消息无错误且功能号为读取消息则接收消息中的MW0数据

If sRet = DRV_NO_ERROR And RcvMsg.f = 0 And RcvMsg.data(7) = TASK_TFC_READ Then

RcvData(0) = RcvMsg.data(9)         '注意高低字节的颠到

RcvData(1) = RcvMsg.data(8)

CopyMemory Val_INT16, RcvData(0), 2

Text_Value.Text = Val_INT16

End If

End If

End Function

'写MW0数据

Private Function WriteValue()

Dim sRet As Integer, SndData(0 To 1) As Byte, Val_INT16 As Integer

Val_INT16 = Int(Text_Setting.Text)

CopyMemory SndData(0), Val_INT16, 2

SndMsgWrite.data(8) = SndData(1)'注意高低字节的颠到

SndMsgWrite.data(9) = SndData(0)

sRet = DevPutMessage(0, SndMsgWrite, 500)'发送写数据的消息

If sRet = DRV_NO_ERROR Then'如果发送消息无错误

sRet = DevGetMessage(0, usSize, RcvMsg, 500)    '接收返回消息

End If

bWrite = False'复位写值标志

End Function

4、在bbbb1添加定时器Timer1,设定周期为100ms;在Timer1的执行事件中添加以下代码:

'定时器1的执行代码

Private Sub Timer1_Timer()

If bNetLink_Connected = False Then '如果NetLink没有链接则退出定时器执行

Exit Sub

End If

If bWrite = True Then'如果有写值请求

WriteValue                      '写MW0值

ElseIf bStartRead = True Then'否则检查是否启动了读循环

ReadValue                       '读MW0值

End If

End Sub

5、添加[循环读取]、[停止]、[写入新值]、[复位NETLINK]按钮的动作

'循环读取按钮

Private Sub Command_read_Click()

If bNetLink_Connected = False Then '如果NETLINK未链接

NetLINK_Connect                 '链接NETLINK

End If

If bNetLink_Connected = True Then'如果已链接

bStartRead = True               '启动循环读

End If

End Sub

'停止按钮

Private Sub Command_stop_Click()

bStartRead = False

End Sub

'写入新值按钮

Private Sub Command_set_Click()

If IsNumeric(Text_Setting.Text) Then

bWrite = True

Else

MsgBox "设定值错误,范围:-32768至32767", vbExclamation + vbOKOnly, "格式错误"

End If

End Sub

'复位NETLINK按钮

Private Sub Command_reset_Click()

Dim sRet As Integer

If bStartRead = True Then

MsgBox "复位NETLINK前请先停止循环读取。", vbInformation + vbOKOnly, "提示"

Else

sRet = DevPutMessage(0, SndMsgReset, 500)       '发送复位NETLINK的消息

End If

End Sub

6、在bbbb1的Load事件中添加初始化代码:

'bbbb1装载

Private Sub bbbb_Load()

bStartRead = False

bWrite = False

bNetLink_Connected = False

Text_Value.Text = 0

Text_Setting.Text = 0

Initial_SndMsgRead'初始化读取数据消息

Initial_SndMsgWrite'初始化写值消息

Initial_SndMsgReset'初始化复位消息

NetLINK_Connect'链接NETLINK

End Sub

六、注意事项

1、注意发送消息中的数据起始地址的高低字节颠到和接收消息中数据区的高低字节颠到;

2、定时器事件在操作系统繁忙时容易被中断执行,可以适当提高进程和线程的优先级来保证数据的更新速率,在bbbb_Load()中添加以下代码:

Dim hThread As Long, hProcess As Long

hThread = GetCurrentThread

hProcess = GetCurrentProcess

SetThreadPriority hThread, THREAD_PRIORITY_HIGHEST

SetPriorityClass hProcess, HIGH_PRIORITY_CLASS

在Module1中添加以下声明:

Public Const THREAD_BASE_PRIORITY_IDLE = -15

Public Const THREAD_BASE_PRIORITY_LOWRT = 15

Public Const THREAD_BASE_PRIORITY_MIN = -2

Public Const THREAD_BASE_PRIORITY_MAX = 2

Public Const THREAD_PRIORITY_LOWEST = THREAD_BASE_PRIORITY_MIN

Public Const THREAD_PRIORITY_HIGHEST = THREAD_BASE_PRIORITY_MAX

Public Const THREAD_PRIORITY_BELOW_NORMAL = (THREAD_PRIORITY_LOWEST + 1)

Public Const THREAD_PRIORITY_ABOVE_NORMAL = (THREAD_PRIORITY_HIGHEST - 1)

Public Const THREAD_PRIORITY_IDLE = THREAD_BASE_PRIORITY_IDLE

Public Const THREAD_PRIORITY_NORMAL = 0

Public Const THREAD_PRIORITY_TIME_CRITICAL = THREAD_BASE_PRIORITY_LOWRT

Public Const HIGH_PRIORITY_CLASS = &H80

Public Const IDLE_PRIORITY_CLASS = &H40

Public Const NORMAL_PRIORITY_CLASS = &H20

Public Const REALTIME_PRIORITY_CLASS = &H100

Public Declare Function SetThreadPriority Lib "kernel32" (ByVal hThread As Long, ByVal nPriority As Long) As Long

Public Declare Function SetPriorityClass Lib "kernel32" (ByVal hProcess As Long, ByVal dwPriorityClass As Long) As Long

3、无论是读取数据还是写数据,发送和接收消息函数必须成对出现;

4、在实际的通讯中如果网络中断(譬如交换机断电,插拔网络插头)将会导致发送和接收消息函数出错,其返回值sRet大于等于10000(网络错误),此时需要主动发出NETLINK复位消息;发出复位消息后一般需要等待5秒钟后再次进行链接;

5、在每次尝试NETLINK链接前为了避免找不到NETLINK导致的驱动函数超时返回,可以先采用NetIdent协议(参考Ni_pie.pdf文件,使用Winsock控件)广播网络上的NETLINK,找到NETLINK后再尝试链接,这样可以提高通讯效率;

6、一次读取地址连续的数据包(不要超过240个字节)比多次读取单个数据的效率要高的多;

7、发送和返回的响应消息的消息号Nr是对应的,可以用Nr来判断多个读写任务的响应消息;

8、如果一台计算机需要同时访问多个NETLINK通讯,建议采用VC++6.0开发,采用多线程技术.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值