详细的问题描述和源代码见这个帖子
http://bbs.csdn.net/topics/390977511?page=1#post-398941257用VB6做开发和仪表通讯,现在读参数时仪表显示小于65535的数可以正常读取,只要仪表上大于65535这个数,通讯返回的帧数据就是8000h,转成十进制就都是32768。在写参数时写小于32767的数可以正常修改仪表上的数据,但写大于32767的数仪表就返回一个03的错误响应码,无法修改。也问了好多地方了,很多人都说类型定义可能有问题,什么Integer改Long,好像不是这个问题,没办法自己看了下通讯手册,其中有一处地方翻译过来感觉和我这个问题有点问题,手册上说一个参数是16位,所以下段好像是说超过16位的怎么读写的办法,但是自己翻译了一下也不是很理解到底要怎么办,现在发出来大家看下帮忙分析下我的问题是否和手册这章节说的有关,具体要怎么处理?十分感谢!7. CHAPTER 7 Modbus and EI Bisynch
ADVANCED TOPICS
7.1. ACCESS TO FULL RESOLUTION FLOATING POINT AND
TIMING DATA (MODBUS ONLY)One of the main limitations of Modbus is that only 16 bit integer representations of data can
normally be transferred. In most cases, this does not cause a problem, since appropriate
scaling can be applied to the values without losing precision. Indeed all values displayable on
the 4 digit Series 2000 front panel may be transferred in this way. However this has the
significant drawback that the scaling factor to be applied needs to be known at both ends of
the communications link.One further problem is that certain ‘time’ parameters, notably those used for the programmer
function are always returned over the communications link in seconds. It is possible for long
durations to overflow the 16 bit Modbus limit.
To overcome these problems, a sub protocol has been defined, using the upper portion of the
Modbus address space (8000h and upwards), allowing full 32 bit resolution floating point
and timer parameters. The upper area is known as the IEEE region.
This sub-protocol provides two consecutive Modbus addresses for all parameters. The base
address for any given parameter in the IEEE region can easily be calculated by taking its
normal Modbus address, doubling it, and adding 8000h. For example, the address in the
IEEE region of the Target Setpoint (Modbus address 2) is simply
2 x 2 + 8000h = 8004h = 32772 decimal
This calculation applies to any parameter that has a Modbus address.
Access to the IEEE area is made via block reads (Functions 3 & 4) and writes (Function 16
Attempts to use the ‘Write a Word’ (Function 6) operation will be rejected with an error
response. Furthermore, block reads and writes using the IEEE region should only be
performed at even addresses, although no damage to the instrument will result in attempting
access at odd addresses. In general, the ‘number of words’ field, in the Modbus frame,
should be set to 2 times what it would have been for ‘normal’ Modbus.
The rules governing how the data in the two consecutive Modbus addresses are organised
depending on the ‘data type’ of the parameter.

解决方案 »

  1.   

    这段文章说的是,一般的设备他都用16位的数据来表示了,也就是从0~65535,然后比如除以个10什么的来换算出数值来
    如果需要更高精度的数据,需要从Modbus 8000H以上的地址区去读,那个用的是32位的浮点数
    那你比如原来那个贴子里的
    需要发送 02 03 81 42 00 02 XX XX  [XX XX 是校验码,我懒得算了]
      

  2.   


    嗯我看大概意思结合其他对方发帖问,也有人说读2个字发送02 03  81 42 00 02 4C 10
    接收02 03  04 00 00 00 01 08 F3  我尝试读了,按我目前的代码读出来结果是0,我软件内部是拿返回帧前面的0000来转十进制显示的
    是换算方式也有问题么?如果按这样接收回来的00 00 00 01怎么做换算?
    实际上我手上的仪表现在想读的这个参数值是8453.4
    (正确的我想应该是读出来(十进制数)84534这个数,软件内部再去做除10显示结果)我现在就是看手册里这段话不是很理解,你算的8142怎么算出来的?
    就好像我另外帖子里面那个例子,我要读的参数地址是00A1(十六进制的) ,十进制是161
    而手册中说一个normal Modbus address应该指的是这个参数的地址,是拿00A1还是161去参与计算?
    手册中例子:2 x 2 + 8000h = 8004h = 32772 decimal
    那落实到我这个参数
    161x2+ 8000h =8322h
    00A1x2+ 8000h =?? 这样要怎么计算?
      

  3.   

    00A1H=161
    00A1H*2=161*2=322
    322=142H
    161 和 322 都是十进制数
    8000H 00A1H 都是十六进制数(注意,他们最后都有个字母h)
    8000H+142H=8142H00 00 00 01的结果我没法理解了,IEEE浮点数的话换算结果是  1.401298E-45 
    如果是 8453.4转成浮点数应该是 159A4604 或者 4604159A
      

  4.   


    现在要读的仪表上参数的实际值是8453.4
    我尝试了下读地址8332读两个字发送02 03  83 32 00 02 4C 73
    接收02 03  04 FF FF 80 00 A8 D7先假设说8332这个地址是对的
    那么接收的值就应该是FF FF 80 00
    这个数据怎么处理?算一个值还是两个值?
    FFFF十进制是65535 ,80 00是32768
    豪无头绪啊!!
      

  5.   

    8332 肯定错的,问题他返回的不像是IEEE浮点数
      

  6.   


    现在要读的仪表上参数的实际值是8453.4
    我尝试了下读地址8332读两个字发送02 03  83 32 00 02 4C 73
    接收02 03  04 FF FF 80 00 A8 D7先假设说8332这个地址是对的
    那么接收的值就应该是FF FF 80 00
    这个数据怎么处理?算一个值还是两个值?
    FFFF十进制是65535 ,80 00是32768
    豪无头绪啊!!按你的算法那么8332这个就是算错的地址
    可以请教你一个概念么,就还拿那个参数来说
    00A1这个地址是我从仪表一个系列通用通讯手册中查到的
    而在我手上的仪表对应的工程师手册中有部分的通讯说明
    里面有说道一个SCADA addressChapter 30 MODBUS SCADA TABLE
    The SCADA table provides fixed single register Modbus values for use with Third Party Modbus
    masters in SCADA packages or plcs. If parameters are not available in this table they can be added
    from an indirection table using their Modbus addresses. Scaling of the parameters has to be
    configured – the Modbus master scaling has to match the 3500 parameter resolution to ensure the
    decimal point is in the correct position.从这里查到的这个参数的地址应该是1450h,
    就是用00A1h和1450h都可以访问到这个参数,仪表上这个参数小于6553.5都可以正常读出
    这个SCADA是什么的缩写?有接触过么?
    如果说地址是1450h话怎么计算?
    1450*2h+8000h=10900h
    还是说1450h换算成十进制数5200
    5200*2=10400 再转成十六进制28A0h
    然后28A0h+8000h=???这个怎么算不好意思本人编程比较菜,可能算法和思路有点好笑
      

  7.   


    嗯我有怀疑我代码的问题,所以我刚才换了一个从网络上下载的RTU测试软件
    结果是一样的,我看下能否把其他软件测试的结果图发上来
      

  8.   

    SCADA百度一下就有了
    http://baike.baidu.com/link?url=sF9kfuZszTrPrB6akqRrcXUADDmRqBOQPKcsGNnvuj-2rI3j_bXf3WUauUCUpS4bLLrKkCOenRvwP4opxMZpawhUaI_dHFrn9-AdyMzhtHe28A0h+8000h=A8A0h(你用windows自带的计算器,直接用十六进制计算就好了)部分手册上可能会把modbus地址写成这样子
    400A1 或者 40161 最前面的4指的是区域,一般这样写的地址是1起点的,需要减一,但16进制还是10进制含糊不清的,要自己去试
      

  9.   

    ModScan32 专门调试modbus设备用的,他的地址就是从1起的,所以你的00A1在他那里要写成162
      

  10.   


    嗯,谢谢
    我测试了A8A0地址读两位
    结果是一样的,还是用网络上下载的测试工具
    我怀疑是不是CRC校验的问题?
    我的代码一直都是采用的CRC16函数计算的,这个不是读写16位的么?
    如果现在读写2个字32位的,是不是要换CRC32函数来计算?
    只是我个人猜测,有没有这个可能?
    不过好像又不对,我之前有用我自己软件的代码读过3个字的
    即02 03 XXXX(地址 )00 03 XXXX(CRC)好像可以正确读出仪表内的三个不同数据
      

  11.   

    国内代理商那边问了,他们没有做软件开发的
    仪表是英国的,本人英文有点菜,有发了几封电子邮件给他们有帮我解决一个问题了
    但是这个问题那个收电子邮件的人说他也不是很明白方便留个QQ么?或是你加我QQ15374420
    我下载了你说的那个ModScan32软件不会用
    顺便请教下