XM 系列仪表通讯说明
通讯格式为8 位数据,2 个停止位,无校验位。数据包采用16 位求和校验,它的纠错能力比
奇偶校验高数万倍,可确保通讯数据的正确可靠。XM 系列仪表在上位计算机、通讯接口或
线路发生故障时,仍能保持仪表本身的正常工作。
仪表读写方式如下:
读指令: Addr+80H Addr+80H 52H 要读参数的代号 00 00 CRC 校验码
写指令: Addr+80H Addr+80H 43H 要写参数的代号 写入数低字节 写入数高字节 CRC 校验码
读指令的CRC 校验码为:52H+Addr 要读参数的代号,Addr 为仪表地址参数值范围是0~100
写指令的CRC 校验码为:43H+要写的参数值+Addr 要写的参数代号。
每2 个8 位数据代表一个16 位整型数,低位字节在前,高位字节在后,热电偶或热电阻输入时其
单位都是0.1℃。1V 或0V 等线性输入时,单位都是线性最小单位。因为传递的是16 位二进制数,所
以无法表示小数点,要求用户在上位机处理。
只要上位机发送的命令格式正确时,将返回以下数据:
XX XX XX XX XX XX XX XX XX XX
A1 A2 A3 A4 A5
每个变量由两个字节组成,前面为低字节、后面为高字节
含义如下:第一行的A1、A2、A3、A4、A5 为变量名称,第一列为仪表为各仪表的型号
仪表返回数据的CRC 校验码算法为:A5 = A1 + A2 + A3 + A4 + Addr
例1:如需接收测量值和Loc 值,且仪表的通信地址为1,则发送读指令如下:
81 81 52 00 00 00 53 00
其中 81 81 为仪表的地址代号,52 00 为读参数的指令,53 00 为CRC 校验码。
注:所有的数据读写的时候均为高位在后低位在前,十六进制。
例2:当仪表通讯地址为2,需将仪表参数地址为05H 参数改为123,则发送数据格式为:
82 82 43 05 7B 00 C0 05
123 转换为16 进制为7B。
05C0=43+7B+2+100×5 (注:此公式为16 进制的运算)
返回数据为 16 01 58 02 00 00 7B 00 EB 03
PV 测量值为278(0116H)。CRC 的计算方法为:0116+0258+0000+007B+0002=03EB
其中XMT仪表的
、仪表与上位机通讯,返回数据格式
XX XX XX XX XX XX XX XX XX XX
PV 测量值 仪表状态 对应通信地址数据 CRC 校验码
A1 A2 A3 A4 A5
每个变量由两个字节组成,前面为低字节、后面为高字节
我要用他来获取仪表显示的值,怎么能用VB编程表示出来?
通讯格式为8 位数据,2 个停止位,无校验位。数据包采用16 位求和校验,它的纠错能力比
奇偶校验高数万倍,可确保通讯数据的正确可靠。XM 系列仪表在上位计算机、通讯接口或
线路发生故障时,仍能保持仪表本身的正常工作。
仪表读写方式如下:
读指令: Addr+80H Addr+80H 52H 要读参数的代号 00 00 CRC 校验码
写指令: Addr+80H Addr+80H 43H 要写参数的代号 写入数低字节 写入数高字节 CRC 校验码
读指令的CRC 校验码为:52H+Addr 要读参数的代号,Addr 为仪表地址参数值范围是0~100
写指令的CRC 校验码为:43H+要写的参数值+Addr 要写的参数代号。
每2 个8 位数据代表一个16 位整型数,低位字节在前,高位字节在后,热电偶或热电阻输入时其
单位都是0.1℃。1V 或0V 等线性输入时,单位都是线性最小单位。因为传递的是16 位二进制数,所
以无法表示小数点,要求用户在上位机处理。
只要上位机发送的命令格式正确时,将返回以下数据:
XX XX XX XX XX XX XX XX XX XX
A1 A2 A3 A4 A5
每个变量由两个字节组成,前面为低字节、后面为高字节
含义如下:第一行的A1、A2、A3、A4、A5 为变量名称,第一列为仪表为各仪表的型号
仪表返回数据的CRC 校验码算法为:A5 = A1 + A2 + A3 + A4 + Addr
例1:如需接收测量值和Loc 值,且仪表的通信地址为1,则发送读指令如下:
81 81 52 00 00 00 53 00
其中 81 81 为仪表的地址代号,52 00 为读参数的指令,53 00 为CRC 校验码。
注:所有的数据读写的时候均为高位在后低位在前,十六进制。
例2:当仪表通讯地址为2,需将仪表参数地址为05H 参数改为123,则发送数据格式为:
82 82 43 05 7B 00 C0 05
123 转换为16 进制为7B。
05C0=43+7B+2+100×5 (注:此公式为16 进制的运算)
返回数据为 16 01 58 02 00 00 7B 00 EB 03
PV 测量值为278(0116H)。CRC 的计算方法为:0116+0258+0000+007B+0002=03EB
其中XMT仪表的
、仪表与上位机通讯,返回数据格式
XX XX XX XX XX XX XX XX XX XX
PV 测量值 仪表状态 对应通信地址数据 CRC 校验码
A1 A2 A3 A4 A5
每个变量由两个字节组成,前面为低字节、后面为高字节
我要用他来获取仪表显示的值,怎么能用VB编程表示出来?
解决方案 »
- jcButton错误:属性ToolboxBitmap在jcbutton中的文件引用无效
- 关于vb程序访问局域网共享(需要密码)文件夹的数据库的连接问题
- 如何把下面的数据转化成我所需要的数据?多谢!!
- 使用VBA调试程序时出现的奇怪问题,请指教 急!急!急!
- 关于SendMessage的一些疑问
- 现在想转学C#,请问各位有多少想转?
- 各位大侠,我快要死了啊,如想帮在下一把请进来吧。谢谢谢谢啊,缘份啊!
- 在山东金益康工作的进来报名喽
- 不好意思,没分,csdn搞错了,把分给我吃了。用vb做文件收发程序的问题?
- vb中如何将label中的动态数据存入到txt中
- =====installShield 2008 怎么生成一个Setup.exe========
- 求快速的MD5算法
MSComm1.RThreshold = 1 '当接收到一个字节时产生OnComm事件然后定义发送数据和接收数据的字节型数组.Dim CommSend() As Byte
Dim CommReceive() As Byte比如你要发送例一的数据:如下Redim CommSend(7)
CommSend(0)=&H81
CommSend(1)=&H81
CommSend(2)=&H52
CommSend(3)=&H0
CommSend(4)=&H0
CommSend(5)=&H0
CommSend(6)=&H53
CommSend(7)=&H0
MSComm1.Output=CommSend '//发送81 81 52 00 00 00 53 00 然后当有数据返回,就会产生OnComm事件.Private Sub MSComm0_OnComm()
CommReceive=MSComm1.Input
'//然后自己可以根据定义取得CommReceive中各位的值.
'//例如A2: A2=CommReceive(3)*256+CommReceive(2) 高字节CommReceive(3)和低字节CommReceive(2)组成A2
End Sub以上就是整个的思路吧,具体的比如设置波特率,打开关闭串口的就自己去完成了,按照这个思路做下来就没问题了.
Option Explicit
Dim strData As StringPrivate Sub Form_Load()
MSComm1.CommPort = 1
MSComm1.Settings = "9600,N,8,2" '假设波特率是9600
MSComm1.InBufferSize = 1024
MSComm1.OutBufferSize = 512
MSComm1.RThreshold = 1
MSComm1.InputMode = comInputModeBinary '按2进制接收
MSComm1.PortOpen = True
End SubPrivate Sub MSComm1_OnComm()
Dim BytReceived() As Byte
Dim strBuff As String
Select Case MSComm1.CommEvent
Case 2
MSComm1.InputLen = 0
strBuff = MSComm1.Input
BytReceived() = strBuff
Dim i As Integer
For i = 0 To UBound(BytReceived) '数据处理为16进制
If Len(Hex(BytReceived(i))) = 1 Then
strData = strData & "0" & Hex(BytReceived(i))
Else
strData = strData & Hex(BytReceived(i))
End If
Next
'数据处理代码
If Len(strData) = 20 Then
Cls
Text1 = strData
Dim sj(4) As String
Dim sjByte(4)
Dim j As Integer
For j = 1 To Len(strData) Step 4
sj((j - 1) \ 4) = Mid(strData, j, 4)
sj((j - 1) \ 4) = Right(sj((j - 1) \ 4), 2) & Left(sj((j - 1) \ 4), 2)
Next j
For j = 0 To 4
sjByte(j) = Val("&H" & sj(j)) '
Print sjByte(j)
Next
If 2 + sjByte(0) + sjByte(1) + sjByte(2) + sjByte(3) = sjByte(4) Then
Print "ok"
'写进入接收正确数据处理代码
End If
strData = ""
End If
End Select
End Sub
Option Explicit
Dim strData As StringPrivate Sub Form_Load()
MSComm1.CommPort = 1
MSComm1.Settings = "9600,N,8,2" '假设波特率是9600
MSComm1.InBufferSize = 1024
MSComm1.OutBufferSize = 512
MSComm1.RThreshold = 1
MSComm1.InputMode = comInputModeBinary '按2进制接收
MSComm1.PortOpen = True
End SubPrivate Sub MSComm1_OnComm()
Dim BytReceived() As Byte
Dim strBuff As String
Select Case MSComm1.CommEvent
Case 2
MSComm1.InputLen = 0'//这一步是干什么的?
strBuff = MSComm1.Input
BytReceived() = strBuff'//这一步是没必要的,直接BytReceived=MSComm1.Input就行
Dim i As Integer
For i = 0 To UBound(BytReceived) '数据处理为16进制
If Len(Hex(BytReceived(i))) = 1 Then
strData = strData & "0" & Hex(BytReceived(i))
Else
strData = strData & Hex(BytReceived(i))
End If
Next
'数据处理代码
If Len(strData) = 20 Then
Cls
Text1 = strData
Dim sj(4) As String
Dim sjByte(4)
Dim j As Integer
For j = 1 To Len(strData) Step 4
sj((j - 1) \ 4) = Mid(strData, j, 4)
sj((j - 1) \ 4) = Right(sj((j - 1) \ 4), 2) & Left(sj((j - 1) \ 4), 2)
Next j
For j = 0 To 4
sjByte(j) = Val("&H" & sj(j)) '
Print sjByte(j)
Next
If 2 + sjByte(0) + sjByte(1) + sjByte(2) + sjByte(3) = sjByte(4) Then
Print "ok"
'写进入接收正确数据处理代码
End If
strData = ""
End If
End Select
End Sub
现将发送与接收代码贴上:
Option Explicit
Dim strData As String
Dim strBin(7) As Byte
Dim addr As BytePrivate Sub CmdRead_Click()
strBin(0) = &H80 + Val(txtaddr)
strBin(1) = &H80 + Val(txtaddr)
strBin(2) = &H52
strBin(3) = &H0
strBin(4) = &H0
strBin(5) = &H0
strBin(6) = strBin(2) + Val(txtaddr)
strBin(7) = strBin(3)
MSComm1.Output = strBin
End SubPrivate Sub CmdWrite_Click()
strBin(0) = &H80 + Val(txtaddr)
strBin(1) = &H80 + Val(txtaddr)
strBin(2) = &H43
strBin(3) = Val("&H" & txtCsaddr)
strBin(4) = Val(txtSj)
Print strBin(4)
strBin(5) = &H0
Dim crcW As Integer
crcW = strBin(2) + strBin(4) + 2 + 256 * 5
Dim strcrcW As String
strcrcW = Hex(crcW)
If Len(strcrcW) = 3 Then
strcrcW = "0" & strcrcW
End If
strBin(6) = Val("&H" & Right(strcrcW, 2))
strBin(7) = Val("&H" & Left(strcrcW, 2))
MSComm1.Output = strBin
End SubPrivate Sub Form_Load()
MSComm1.CommPort = 1
MSComm1.Settings = "9600,N,8,2" '假设波特率是9600
MSComm1.InBufferSize = 1024
MSComm1.OutBufferSize = 512
MSComm1.RThreshold = 1
MSComm1.InputMode = comInputModeBinary '按2进制接收
MSComm1.PortOpen = True
Text1 = ""
txtaddr = "" '地址
txtSj = "" '写的参数值
txtCsaddr = "" '写入参数地址
End SubPrivate Sub MSComm1_OnComm()
Dim BytReceived() As Byte
Dim strBuff As String
Select Case MSComm1.CommEvent
Case 2
MSComm1.InputLen = 0
strBuff = MSComm1.Input
BytReceived() = strBuff
Dim i As Integer
For i = 0 To UBound(BytReceived) '数据处理为16进制
If Len(Hex(BytReceived(i))) = 1 Then
strData = strData & "0" & Hex(BytReceived(i))
Else
strData = strData & Hex(BytReceived(i))
End If
Next
'数据处理代码
If Len(strData) = 20 Then
Cls
Text1 = strData
Dim sj(4) As String
Dim sjByte(4)
Dim j As Integer
For j = 1 To Len(strData) Step 4
sj((j - 1) \ 4) = Mid(strData, j, 4)
sj((j - 1) \ 4) = Right(sj((j - 1) \ 4), 2) & Left(sj((j - 1) \ 4), 2)
Next j
For j = 0 To 4
sjByte(j) = Val("&H" & sj(j)) '
Print sjByte(j)
Next
If 2 + sjByte(0) + sjByte(1) + sjByte(2) + sjByte(3) = sjByte(4) Then
Print "ok"
'写进入接收正确数据处理代码
End If
strData = ""
End If
End Select
End Sub
3楼 sulipeng007问MSComm1.InputLen = 0'//这一步是干什么的?
见MSDN说明
InputLen 属性
设置并返回 Input 属性从接收缓冲区读取的字符数。
InputLen 属性的缺省值是 0。设置 InputLen 为 0 时,使用 Input 将使 MSComm 控件读取接收缓冲区中全部的内容。
从以上MSDN说明:
MSComm1.InputLen = 0
用法没错.
其次我在上面贴出的代码是经双串口机器调试,不存在任何问题.
至于sulipeng007网友所担忧的显然没有经过实际通信调试,凭猜测主观臆断所做的结论.
VB的代码编写必须经调试,而且这种调试本身就是一种寻找代码错误的手段.
建议sulipeng007网友在编写串口通信代码调试时,使用双串口机器,即使机器仅1个COM口,你可购买PCI插槽的串口扩展卡,费用不高,65元/张,那可避免不少麻烦.串口通信大量使用在工业实时控制,写好的代码如果只能在设备现场调试,将非常困难.一般我采用在单台机器做一个模拟现场装置要求的调试程序与PC机的VB应用程序调试,做到无错误后,再交付使用.
LZ的问贴其重点在算法的设计,有正确的算法才能写出符合通信协议的串口通信代码.
For i = 0 To UBound(BytReceived) '数据处理为16进制
If Len(Hex(BytReceived(i))) = 1 Then
strData = strData & "0" & Hex(BytReceived(i))
Else
strData = strData & Hex(BytReceived(i))
End If
Next这句时接受出来的数据是84FF31F8000031F8E7EF和想要得倒的8181520000005300不一样啊,不知道怎么回事,我没找出原因来