搜索
bottom↓
回复: 54

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

  [复制链接]

出300入477汤圆

发表于 2012-6-21 14:41:43 | 显示全部楼层 |阅读模式
有不少人想在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地址即可。

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出1070入962汤圆

发表于 2012-6-21 15:38:32 | 显示全部楼层
顶一下!

出300入477汤圆

 楼主| 发表于 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帧具有最高的优先级,如果其他协议想抢占总线,则需要明确的提高优先级)。

出0入0汤圆

发表于 2012-7-5 17:17:53 | 显示全部楼层
这个要顶。。以后就按着协议做485转CAN

出0入4汤圆

发表于 2012-7-5 17:23:12 | 显示全部楼层
            顶一下

出300入477汤圆

 楼主| 发表于 2012-7-5 17:38:42 | 显示全部楼层
niba 发表于 2012-7-5 17:17
这个要顶。。以后就按着协议做485转CAN

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

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

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

出0入0汤圆

发表于 2012-7-12 12:39:02 | 显示全部楼层
觉得周立功的ICAN协议写的正差劲

出300入477汤圆

 楼主| 发表于 2012-7-12 12:48:53 | 显示全部楼层
本帖最后由 redroof 于 2012-7-12 12:51 编辑
qq302011 发表于 2012-7-12 12:39
觉得周立功的ICAN协议写的正差劲


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



出0入0汤圆

发表于 2012-7-12 15:40:12 | 显示全部楼层
redroof 发表于 2012-7-12 12:48
ZLG似乎想学CanOpen和DeviceNet,所以在协议中规定了太多的东西,结果导致应用程序层被限制的很死,想做 ...

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

出300入477汤圆

 楼主| 发表于 2012-7-12 16:14:06 | 显示全部楼层
qq302011 发表于 2012-7-12 15:40
我现在用的是ICAN,只不过UARTCAN这一层使用了MOUBUS协议,发现ICAN一个不太好的地方就是:
如果发送一条 ...

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

出0入0汤圆

发表于 2012-7-14 00:43:50 | 显示全部楼层
redroof 发表于 2012-7-12 16:14
不对啊!
控制命令发完后,发送方是明确知道这个命令发送成功了的。因为CAN的物理结构,如果一帧数据没人 ...

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

出0入0汤圆

发表于 2013-1-9 13:35:30 | 显示全部楼层
Modbus over CAN

出0入0汤圆

发表于 2013-1-9 13:40:24 | 显示全部楼层
相当好!~

出0入0汤圆

发表于 2013-1-9 16:42:54 | 显示全部楼层
即使使用和485一样的波特率,整个网络的吞吐量比485模式大好几倍?

为什么?

出300入477汤圆

 楼主| 发表于 2013-1-9 19:12:25 来自手机 | 显示全部楼层
ljt80158015 发表于 2013-1-9 16:42 即使使用和485一样的波特率,整个网络的吞吐量比485模式大好几倍? 为什么? ...

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

出0入0汤圆

发表于 2013-1-11 19:59:12 来自手机 | 显示全部楼层
Modbus over CAN

出0入0汤圆

发表于 2013-1-22 16:36:55 | 显示全部楼层
真厉害啊 学习一下

出0入0汤圆

发表于 2013-2-21 11:24:59 | 显示全部楼层
Modbus Over CAN

出0入0汤圆

发表于 2013-4-28 11:46:11 | 显示全部楼层
这个真的不错,给我很大启发!

出0入0汤圆

发表于 2013-7-13 01:10:18 | 显示全部楼层
谢谢楼主对can bus的思考和应用

出0入0汤圆

发表于 2013-8-14 00:00:35 来自手机 | 显示全部楼层
mark……
顶一个…

出0入0汤圆

发表于 2013-10-9 20:36:45 | 显示全部楼层
支持广播吗?

出300入477汤圆

 楼主| 发表于 2013-10-9 21:17:15 | 显示全部楼层
CAN网络原本就是广播传输的啊!只要节点愿意处理广播就行。
可惜Modbus的广播意义不大(同时向所有从机写数据?或者同时从所有从机读数据?对485来说,这两种情况都是无法收到应答的!)

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

出0入4汤圆

发表于 2013-10-9 21:38:25 | 显示全部楼层
关注ing

出0入0汤圆

发表于 2013-10-21 14:00:23 | 显示全部楼层
Modbus over CAN   mark

出0入0汤圆

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

出300入477汤圆

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

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

出0入0汤圆

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

谢谢楼主耐心教诲,

出0入8汤圆

发表于 2014-3-18 16:38:48 | 显示全部楼层
mark                        

出0入0汤圆

发表于 2014-4-14 18:53:49 | 显示全部楼层
CAN总线,mark

出0入0汤圆

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

出300入477汤圆

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

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

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

出0入0汤圆

发表于 2014-4-15 10:25:00 | 显示全部楼层
嗯嗯,是的,楼主的精神可贵,,支持,,

出0入12汤圆

发表于 2014-5-19 16:48:39 | 显示全部楼层
如果从机没有办法从硬件上设置地址,主机怎么给N个从机分别设置地址?

出0入0汤圆

发表于 2014-11-29 18:30:32 | 显示全部楼层
挺有意义的,支持!

出0入0汤圆

发表于 2014-11-29 20:18:06 | 显示全部楼层
非常好,MARK

出0入0汤圆

发表于 2014-11-29 23:06:48 | 显示全部楼层
CAN总线本身已经非常棒了!ZLG的Ican是多此一举而已,应该把数据层搞好些!

出0入0汤圆

发表于 2018-5-16 20:53:42 | 显示全部楼层
Modbus over CAN 学习了

出0入0汤圆

发表于 2018-9-7 11:11:19 | 显示全部楼层
真心不错,多谢分享!

出0入0汤圆

发表于 2018-9-7 11:25:14 | 显示全部楼层
这么多年前的帖子了,,,用得多么?

出300入477汤圆

 楼主| 发表于 2018-9-7 12:21:13 来自手机 | 显示全部楼层
wkman 发表于 2018-9-7 11:25
这么多年前的帖子了,,,用得多么?

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

出0入0汤圆

发表于 2018-9-7 13:38:09 | 显示全部楼层
直接CAN透传就好了

出0入0汤圆

发表于 2018-9-7 21:41:28 | 显示全部楼层
学习一下

出0入0汤圆

发表于 2018-9-15 21:16:25 | 显示全部楼层
没看到内容啊,文件呐

出300入477汤圆

 楼主| 发表于 2018-9-15 21:35:34 来自手机 | 显示全部楼层
cnzhoujin 发表于 2018-9-15 21:16
没看到内容啊,文件呐

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

出0入0汤圆

发表于 2018-12-20 16:51:07 | 显示全部楼层
谢谢分享,学习了

出0入0汤圆

发表于 2019-3-24 15:42:41 来自手机 | 显示全部楼层
我自己定义的和楼主思路一样,不过楼主在ID定义上考虑得更完善,赞

出0入0汤圆

发表于 2020-7-19 16:17:29 | 显示全部楼层
不错,正需要呢,就按楼主的协议来

出0入0汤圆

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

出300入477汤圆

 楼主| 发表于 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的。看了就知道。。。。

出0入0汤圆

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

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

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

出300入477汤圆

 楼主| 发表于 2020-8-3 12:23:12 来自手机 | 显示全部楼层
citroen988 发表于 2020-8-3 11:11
首先自己弄一套can协议的话,没必要参考modbus。
其次不管自定义的can带不带modbus,都没法与其他厂家互 ...

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

出300入477汤圆

 楼主| 发表于 2020-8-3 12:31:55 来自手机 | 显示全部楼层
citroen988 发表于 2020-8-3 11:11
首先自己弄一套can协议的话,没必要参考modbus。
其次不管自定义的can带不带modbus,都没法与其他厂家互 ...

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

出300入477汤圆

 楼主| 发表于 2020-8-3 12:32:45 来自手机 | 显示全部楼层
我很多年不做can了,没法做,没有开放生态

出0入0汤圆

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

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

回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-31 02:09

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表