三菱PLC FX系列编程口通信的若干问题

[复制链接]
查看2198 | 回复1 | 2007-1-20 13:02:00 | 显示全部楼层 |阅读模式

----最近一段时间,由于工作上的原因,接触到了PC机与PLC编程口通信方面的开发。开发过程也走过不少的弯路,由于编程口通信协议未被三菱公司公开,所以很难找到一个系统的教材,在网上搜集了许多这方面的资料。最开始在VB上调试的时候非常顺利,按照其通信协议发送了一个字符串"ABCD1234" ,然后在PLC中收到。 当时以为向嵌入式Linux移植会很顺利,但是在定义了数据结构后,往端口发送数据PLC没有收到。对此进行了比较系统的分析。
----首先想到的是VB字符串与C字符串的差别。VB中运行时每一个英文字符都是双字节的Unicode字符,通过Lenb(ch* ar)=2可以看出是双字节。然后就转而去研究Unicode编码问题,对字符进行Unicode编码还是不行。后来查到了VB串行口通信编码方面的资料,才知道VB中运行时字符会自动转换为Unicode,但是在输出时却又转为ASCII(指英文字符),VB真是个大骗子,上了一次大当。既然不是编码问题的话那肯定就是端口设置问题,或者就是别的什么未知问题。然后就去检查各个设置参数。VB里面打开COM1采用 Open "COM1:9600:N:1"的方式来打开串口,打开超级终端监视器,发现无论怎么调节其中的打开参数,都可以正确接收!至少在这里可以说明VB中指定的参数设置也是骗人的。然后就检查Linux程序里关于端口的设置并和通信协议进行比较,突然发现奇偶校验不对,其编程口为偶校验。修改完以后,运行程序,PLC指示灯亮了!
---- 通过以上的经历,总结了以下的经验:
1.VB中的字符编码是在内部自动转换的,所以不要在VB内部去测试其发送的数据。可以采用COM1,2端口用连线跳接的方式直接捕获其二进制值,这样才能清晰的看到VB发送了什么数据。(如果你还没有应用成功,处于调试阶段)
2.要保证每一个端口初始化参数的正确性,任何一个和编程口的设置不一样都不能成功通信。

如下是我的代码
Dim keyin$
Dim SXD$
Dim RXD$

Private Sub Command1_Click()
keyin$ = InputBox$("输入通信命令)", "输入对话框", "")
MsgBox keyin$
If keyin$ = "" Then GoTo null_keyin
ENQ$ = c h *r$(5)
T$ = keyin$
Sum$ = chksum(T$)
SXD$ = ENQ$ + T$ + Sum$
Text1.Text = SXD$
RXD$ = send_recieve(SXD$)
Text2.Text =RXD$
Text3.Text = Sum$
null_keyin:
End Sub

Sub Option1_Click()
MSComm1.PortOpen = True
End Sub

Private Sub delay(delay_N%)
For i% = 1 To delay_N%
For J% = 1 To 30
xa! = 10 * Sin(10 * J% / 20)
Next J%
Next i%
End Sub

Private Function chksum$(T$)
L = Len(T$)
a = 0
For J = 1 To L
a = Asc(m i* d$(T$, J, 1)) + a
Next J
Sum$ = Hex$(a)
If Len(Sum$) = 1 Then Sum$ = "0" + Sum$
chksum$ = Right$(Sum$, 2)
End Function

Private Function resp_length%(SXD$)
comx$ = m i* d$(SXD$, 2, 1)
bytelenth% = CInt(m i* d$(SXD$, 8, 1))
If CInt(comx$) = 0 Then L% = bytelenth% * 2 + 4
If CInt(comx$) = 1 Then L% = 1
If CInt(comx$) = 7 Then L% = 1
If CInt(comx$) = 8 Then L% = 1
resp_length% = L%
End Function

Private Sub Form_Load()
Form1.Caption = "FX2 VB"
Text1.Text = "": Text2.Text = ""
MSComm1.CommPort = 1
MSComm1.Settings = "9600,e,7,1"
MSComm1.RTSEnable = True
Option1.Value = True
End Sub

Private Sub Option2_Click()
MSComm1.PortOpen = False
End Sub

Private Function send_recieve(SXD$)
MSComm1.Output = SXD$
Call delay(1000)
resp_len% = resp_length%(SXD$)
MSComm1.InputLen = resp_len%
RXD$ = MSComm1.Input
send_recieve = RXD$
End Function
wj14378 | 2007-1-28 05:07:00 | 显示全部楼层
您需要登录后才可以回帖 登录 | 注册哦

本版积分规则