redroof 发表于 2012-6-21 14:41:43

发布一个Modbus over CAN(在CAN总线上跑Modbus)的规范

有不少人想在CAN上跑modbus,但又没有标准,大家彼此的实现都不一样,结果这些Modbus之间没办法互相通讯。
鉴于此,本人发布一个公共的Modbus over CAN 约定,只要大家都按此约定执行,则所有执行此约定的设备都可以在CAN上跑Modbus,并且保持兼容性。

本协议规范如下:
CAN的波特率默认100K(实现者可改变此波特率),此时的通讯距离有500米,已经足够
本协议使用扩展CAN帧,29bit的ID按如下定义(从高位到低位,ID是高位先发的)

[*]2bit优先级,有最高,高,中,低这4个优先级,优先级与数据内容无关,仅仅为了保证高优先级包的实时性,00是最高,11是低,任何机器对这两位不可设ID过滤器,任何优先级的帧都应该收下[*]4bit保留位,可用作多协议之间的兼容性,对本ModbusOverCAN设为全0,如果非全0则被视为其他协议,本协议不处理这个帧
[*]1bit的请求/应答标志,请求帧是0,应答帧是1
[*]8bit DA,目标站地址
[*]8bit SA,源站地址
[*]1bit的最后一帧标志,表示这是分帧的最后一帧(如只有1帧,也要置这个标志)
[*]5bit的分帧序号(0-31,因为CAN帧是8byte数据,modbus是256byte,所以最多32帧)

Modbus的数据在去掉最前面的从机地址和最后面的校验以后,其他部分直接放在CAN的数据帧里面
也就是说,存放在CAN数据帧里面的第一个字节就是功能码,注意,应答帧的功能码是原来请求帧功能码加0x80,并且应答帧要置上ID里面的请求/应答标志
这么设计的原因是为了保证两个机器可以互相给对方发请求而不冲突

另外一个需要注意的地方是,这里像modbusTCP一样,不再是主从结构,而是多主结构,任意机器都可以给其他机器发请求,只要其他机器愿意回答即可。
所以整个网络里面每个机器都有自己的站地址,并且所有的地址不同。

例如,机器A要读取机器B的寄存器,请求包里面的目标站地址就是B的地址,源站地址就是A的地址。而B返回给A的应答帧,目标站地址是A,源站地址是B,这样做的目的是方便设置CAN的ID过滤器
如果只有单主机,主机自己使用0地址即可。

Appcat 发表于 2012-6-21 15:38:32

顶一下!

redroof 发表于 2012-6-22 09:06:14

没人感兴趣吗?
自己顶一个!
这个协议比起传统Modbus的优点有:
1,使用CAN的特性实现了4个优先级(如果不需要优先级,所有的帧都设为同一优先级即可,建议使用低或中优先级)
2,整个网络不再受一问一答的限制(对485网络,主机发出请求后,从机如果延迟响应,在从机没有回答之前整个网络都被占用,任何人不能发其他数据),CAN总线上任何站点都可以同时向多个其他站点发请求,然后按照地址顺序收到应答。即使使用和485一样的波特率,整个网络的吞吐量比485模式大好几倍。当然,为了不改动485协议,每个机器在同一时刻只能向另一个机器发出1个Modbus请求,只有这个请求得到回答后,才能发下一个请求。但如果有多个从机,主机可以给第一个从机发了请求以后立刻给第二个从机发请求,然后是第三个..., 不必等从机回答。因为CAN总线有硬件的仲裁,从机只要发出了应答,在仲裁成功后主机会自动收到,不论主机现在是不是正在给其他机器发请求。
3,应用层继续保持Modbus结构,只要原有的软件中有Modbus协议,稍加改动即可让Modbus协议跑在CAN总线上面,唯一的改动是把对串口的数据收发改成了对CAN的收发。应用层的任何东西都不改变。
4,只占用了1/16的CAN ID地址空间,其他协议只要保留位不是0000就可以跟本协议一起跑在同一个网络,互不干扰(例如,可以用保留位是其他数字的帧作为CAN总线下载程序用,或者用于传输大批量的非紧急数据等等,因为保留位0000是最小的数,所以在相同的优先级下,ModbusOverCAN帧具有最高的优先级,如果其他协议想抢占总线,则需要明确的提高优先级)。

niba 发表于 2012-7-5 17:17:53

这个要顶。。以后就按着协议做485转CAN

MZMMZMMZM 发表于 2012-7-5 17:23:12

            顶一下

redroof 发表于 2012-7-5 17:38:42

niba 发表于 2012-7-5 17:17 static/image/common/back.gif
这个要顶。。以后就按着协议做485转CAN

嗯,多个Modbus485协议的设备,只要每个设备上增加一个485转CAN的转换器,就可以支持多主多从任意连接了!

不过,如果要完全不改动以前的Modbus485设备,还有一点要注意:
这个转换器自身要有个开关选择自己工作在主机模式还是从机模式。因为Modbus主机默认是没有地址的(数据帧里面只含有从机地址)。
如果转换器工作在主机模式,需要人为的给它设置一个地址,这个地址不能跟网络上的其他主机和从机冲突,
而如果转换器工作在从机模式,它的地址不能乱设,应当设为连接在它上面的485设备原来的地址。
这样就可以做485和CAN的多主多从透传了

另外,自身既能当主又能当从的设备无法用485到CAN的转换器转接。要同时支持Modbus主从,只能是原生的CAN。

qq302011 发表于 2012-7-12 12:39:02

觉得周立功的ICAN协议写的正差劲

redroof 发表于 2012-7-12 12:48:53

本帖最后由 redroof 于 2012-7-12 12:51 编辑

qq302011 发表于 2012-7-12 12:39 static/image/common/back.gif
觉得周立功的ICAN协议写的正差劲

ZLG似乎想学CanOpen和DeviceNet,所以在协议中规定了太多的东西,结果导致应用程序层被限制的很死,想做个ICAN到Modbus的协议转换器都办不到(地址空间不够)
我当时也考虑过这些,最后只好自己定义了一个基于CAN的Modbus包装器,就是这里发布的这个。
我这个因为完全兼容了Modbus的应用层,所以可以随意的造网关,可以完全透明的转到Modbus485和ModbusTCP。而且对ModbusTCP来说,也支持同一个设备既当主又当从。



qq302011 发表于 2012-7-12 15:40:12

redroof 发表于 2012-7-12 12:48 static/image/common/back.gif
ZLG似乎想学CanOpen和DeviceNet,所以在协议中规定了太多的东西,结果导致应用程序层被限制的很死,想做 ...

我现在用的是ICAN,只不过UART<----->CAN这一层使用了MOUBUS协议,发现ICAN一个不太好的地方就是:
如果发送一条控制指令出去,而节点执行了这条指令,但是没有正确返回的话,主机会再次发送,这时候节点又会再次执行这个指令,你这个应该可以考虑避免这个问题

redroof 发表于 2012-7-12 16:14:06

qq302011 发表于 2012-7-12 15:40 static/image/common/back.gif
我现在用的是ICAN,只不过UARTCAN这一层使用了MOUBUS协议,发现ICAN一个不太好的地方就是:
如果发送一条 ...

不对啊!
控制命令发完后,发送方是明确知道这个命令发送成功了的。因为CAN的物理结构,如果一帧数据没人收,那么根本就发不出去。只要成功发出了,一定代表接收方收到了,并且硬件校验是正确的。
接收方回答也是同理,除非总线故障,否则你发出的东西是由硬件保证的,根本就不会丢。

qq302011 发表于 2012-7-14 00:43:50

redroof 发表于 2012-7-12 16:14 static/image/common/back.gif
不对啊!
控制命令发完后,发送方是明确知道这个命令发送成功了的。因为CAN的物理结构,如果一帧数据没人 ...

uart转的串口,如果UART到CAN的数据转换有问题,则虽然发送成功也是错误的数据

yat 发表于 2013-1-9 13:35:30

Modbus over CAN

ljt80158015 发表于 2013-1-9 13:40:24

相当好!~

ljt80158015 发表于 2013-1-9 16:42:54

即使使用和485一样的波特率,整个网络的吞吐量比485模式大好几倍?

为什么?

redroof 发表于 2013-1-9 19:12:25

ljt80158015 发表于 2013-1-9 16:42 即使使用和485一样的波特率,整个网络的吞吐量比485模式大好几倍? 为什么? ...

多主就不说了,485做可靠的多主没几个人能做好。我们自己的grm200虽然支持多主mpi,但系统开销也非常高。
即使是主从状态,一个485网络大部分时间可能都是在等待:主机发出请求,然后就得让出总线,等到从机回答,或者超时。而大部分从机不可能收到请求就立刻回答,总要耽误一会。如果出现错误,等待的就更长。
用can,主机可以依次给多个从机发请求,然后依次收回应答。第一个从机准备数据的时候,你正在给后面的从机发请求,完全靠硬件仲裁,不浪费等待时间(当然,如果只有一个从机,还是得浪费时间,这个没办法)

boboo 发表于 2013-1-11 19:59:12

Modbus over CAN

yelingyijiu 发表于 2013-1-22 16:36:55

真厉害啊 学习一下

chxaitz 发表于 2013-2-21 11:24:59

Modbus Over CAN

jungleyang 发表于 2013-4-28 11:46:11

这个真的不错,给我很大启发!

scdyxcc 发表于 2013-7-13 01:10:18

谢谢楼主对can bus的思考和应用

xiefy21 发表于 2013-8-14 00:00:35

mark……
顶一个…

ljt80158015 发表于 2013-10-9 20:36:45

支持广播吗?

redroof 发表于 2013-10-9 21:17:15

CAN网络原本就是广播传输的啊!只要节点愿意处理广播就行。
可惜Modbus的广播意义不大(同时向所有从机写数据?或者同时从所有从机读数据?对485来说,这两种情况都是无法收到应答的!)

如果想用广播做什么特定用途,还是自己使用保留位实现一个其他协议来做吧!

fulitun 发表于 2013-10-9 21:38:25

关注ing{:victory:}

lwjsxz 发表于 2013-10-21 14:00:23

Modbus over CAN   mark

zzl290 发表于 2013-12-15 14:20:27

谢谢楼主分享。
有个问题想请教一下,
楼主提到“也就是说,存放在CAN数据帧里面的第一个字节就是功能码,注意,应答帧的功能码是原来请求帧功能码加0x80,并且应答帧要置上ID里面的请求/应答标志这么设计的原因是为了保证两个机器可以互相给对方发请求而不冲突”
请问没在应答帧要置上ID里面的请求/应答标志时互相给对方发请求为什么有冲突。请楼主不吝赐教。

redroof 发表于 2013-12-15 16:33:48

zzl290 发表于 2013-12-15 14:20
谢谢楼主分享。
有个问题想请教一下,
楼主提到“也就是说,存放在CAN数据帧里面的第一个字节就是功能码, ...

这样别人解码会麻烦啊。
注意你接收的时候只能对ID位设置过滤器,数据是不能设置过滤器的。
所以MODBUS标准使用功能码的最高位区分请求和应答对CAN并不方便。
当然你可以选择把整个功能码都放在CAN的ID里面,让别人可以硬件解码。
我的选择是在CAN的ID里面存放一个请求/应答标志

zzl290 发表于 2013-12-18 09:12:03

redroof 发表于 2013-12-15 16:33
这样别人解码会麻烦啊。
注意你接收的时候只能对ID位设置过滤器,数据是不能设置过滤器的。
所以MODBUS标 ...

谢谢楼主耐心教诲,{:handshake:}

Feco 发表于 2014-3-18 16:38:48

mark                        

baoyt 发表于 2014-4-14 18:53:49

CAN总线,mark

hyf88 发表于 2014-4-15 09:29:49

感觉就是自定义协议一样,没什么新鲜,是不?楼主,,只是个人的观点

redroof 发表于 2014-4-15 10:16:38

hyf88 发表于 2014-4-15 09:29
感觉就是自定义协议一样,没什么新鲜,是不?楼主,,只是个人的观点

协议不可能“新鲜”,也不需要“新鲜”啊!
我确实就是把我们自己的自定义协议公布出来了而已。
因为有很多人不知道怎么做一个完整的自定义协议,或者很多人的自定义协议不公开,彼此也不兼容。
所以我把我的协议公开了,如果某人想做Can上面的Modbus,可以按这个做。所有按这个做法做的Modbus彼此兼容。
这就够了。

如果您有更好的做法,也可以把协议公开出来给大家共享。

hyf88 发表于 2014-4-15 10:25:00

嗯嗯,是的,楼主的精神可贵,,支持,,

waterx3 发表于 2014-5-19 16:48:39

如果从机没有办法从硬件上设置地址,主机怎么给N个从机分别设置地址?

swap2013 发表于 2014-11-29 18:30:32

挺有意义的,支持!

w3154 发表于 2014-11-29 20:18:06

非常好,MARK

activeleo 发表于 2014-11-29 23:06:48

CAN总线本身已经非常棒了!ZLG的Ican是多此一举而已,应该把数据层搞好些!

aerguqiuhui 发表于 2018-5-16 20:53:42

Modbus over CAN 学习了

heimareed 发表于 2018-9-7 11:11:19

真心不错,多谢分享!

wkman 发表于 2018-9-7 11:25:14

{:sad:}这么多年前的帖子了,,,用得多么?{:shocked:}

redroof 发表于 2018-9-7 12:21:13

wkman 发表于 2018-9-7 11:25
这么多年前的帖子了,,,用得多么?

不知道,看起来不多。大部分人还是会选择故意不跟别人兼容,以便多卖个协议转换器啊。。。

xlian541426 发表于 2018-9-7 13:38:09

直接CAN透传就好了

unnormal 发表于 2018-9-7 21:41:28

学习一下

cnzhoujin 发表于 2018-9-15 21:16:25

没看到内容啊,文件呐

redroof 发表于 2018-9-15 21:35:34

cnzhoujin 发表于 2018-9-15 21:16
没看到内容啊,文件呐

核心内容就是主帖里面那一点文字啊。你说还需要什么?
这个规范只是描述了如何把modbus数据包装到can里面,如何分配can的29位id。只要这些信息就够了啊。
原来的modbus该怎么用还怎么用呗,跟这个can包装层没关系。

TKZXJ 发表于 2018-12-20 16:51:07

谢谢分享,学习了

Elec_Ramble 发表于 2019-3-24 15:42:41

我自己定义的和楼主思路一样,不过楼主在ID定义上考虑得更完善,赞

zzm1658 发表于 2020-7-19 16:17:29

不错,正需要呢,就按楼主的协议来

citroen988 发表于 2020-8-3 08:21:55

除非是can转modbus模块,如果不是,can协议没必要向modbus靠,完全自定义或者canopen、ican......

redroof 发表于 2020-8-3 10:15:42

citroen988 发表于 2020-8-3 08:21
除非是can转modbus模块,如果不是,can协议没必要向modbus靠,完全自定义或者canopen、ican...... ...

modbus是工业界应用最广泛的协议,没有之一。
所以如果你想做个开放的通迅协议,不知道该选什么,那么无脑选modbus总是没错的。
除了modbus以外,你自己想想那些CAN专有的协议,有几个可以跨厂家使用的?
网上去找扩展模块,你看看有几个是canopen的,几个ican的?几个devicenet的?
然后同等情况下又有多少个modbus的。看了就知道。。。。

citroen988 发表于 2020-8-3 11:11:13

redroof 发表于 2020-8-3 10:15
modbus是工业界应用最广泛的协议,没有之一。
所以如果你想做个开放的通迅协议,不知道该选什么,那么无 ...

首先自己弄一套can协议的话,没必要参考modbus。
其次不管自定义的can带不带modbus,都没法与其他厂家互通,都是自己跟自己玩。

我的意思很明确,can<-->modbus的场合你这个设计很好。

redroof 发表于 2020-8-3 12:23:12

citroen988 发表于 2020-8-3 11:11
首先自己弄一套can协议的话,没必要参考modbus。
其次不管自定义的can带不带modbus,都没法与其他厂家互 ...

除非你的系统是纯CAN,完全没串口,否则在系统内部用modbus风格都是最佳选择。各种系统的公开的扩展接口,modbus都是最好实现的,也是最多人用的
各位组态软件触摸屏什么的,当主机可以对付所有协议,但是当从机都是默认modbus,没有给你别的plc协议的选项。
所以,如果没有特别理由,那么在应用层跑modbus总是最好的

redroof 发表于 2020-8-3 12:31:55

citroen988 发表于 2020-8-3 11:11
首先自己弄一套can协议的话,没必要参考modbus。
其次不管自定义的can带不带modbus,都没法与其他厂家互 ...

modbus的这种抽象程度真的很经典。不要发明岀太多的概念,只有简单的地址和值,就够了。
想想canopen有多少种概念,有多少人能一下子做好。modbus对第三方扩展是最友好的了
简单才是美。
大家用can都是自搞一套,互不兼容,所以现在can直是只跟自己玩。只要用can的人不都来改变这一点,就永远没办法。
我也认为can底层很好,但是从应用广泛性来说却被古老的modbus485秒杀
这就是现实

redroof 发表于 2020-8-3 12:32:45

我很多年不做can了,没法做,没有开放生态

citroen988 发表于 2020-8-3 13:58:49

redroof 发表于 2020-8-3 12:31
modbus的这种抽象程度真的很经典。不要发明岀太多的概念,只有简单的地址和值,就够了。
想想canopen有多 ...

can协议现场调试没有485那么好调试,有问题不好分析,很多现场485也够用了,这就是市场的需求!

页: [1]
查看完整版本: 发布一个Modbus over CAN(在CAN总线上跑Modbus)的规范