打印
[应用相关]

STM32 CANOPEN 调试答疑:

[复制链接]
5691|36
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
问题1:用usbcan监测不到can口的报文
属于接线问题
CANopen程序总使用的是can1 对应的接下口在J1的1和2口,而其接口排序是从外向里排序,故最外面的为1号接口,由于接线时,按照左边的顺序来数的(左右接口排序对称),把can1H接到了can2L上,can1L接到了can2H上。最后通过用万用表测can收发器的引脚与接口的通断找到了对应的接口。

沙发
東南博士|  楼主 | 2018-8-22 10:18 | 只看该作者
问题2:还是收不到报文  

此时注意到用于can收发的定时器TIM4的配置没更改过来

使用特权

评论回复
板凳
東南博士|  楼主 | 2018-8-22 10:18 | 只看该作者
当读数据的时候  while循环可以退出,但当写数据的时候 while循环不能退出

在解决前两个问题时,把定时器设置好了,但是在设置定时器时,最后一个还是没改成TIM4,就是虽然吧TIM4配置好了,但最后还是没打开,导致TIM4的中断还是没开启

而读数据的循环之所以能够退出是因为他的退出条件是

while (getReadResultNetworkDict (&ObjDict1_Data, 0x04, &rdata, &size,&abortCode) == SDO_UPLOAD_IN_PROGRESS);

而getReadResultNetworkDict函数可以返回值有3种情况

使用特权

评论回复
地板
東南博士|  楼主 | 2018-8-22 10:21 | 只看该作者
截图如下:

使用特权

评论回复
5
東南博士|  楼主 | 2018-8-22 10:23 | 只看该作者
可以返回 SDO_TINISHED 这种情况是SDO处理过程完全正确

            d->transfers[line].state  这个值通常返回的是SDO_UPLOAD_IN_PROGRESS,所以又会返回来循环执行

            SDO_ABORTED_INTERNAL  这个属于中断退出  

实际上根据while的条件,退出while循环的可能有两种,一种是正常处理完毕 一种是中断退出

后来分析得到的结果是虽然这里退出了  但属于终断退出  

而getWriteResultNetworkDict函数可以返回值有2种情况

使用特权

评论回复
6
東南博士|  楼主 | 2018-8-22 10:23 | 只看该作者

使用特权

评论回复
7
東南博士|  楼主 | 2018-8-22 10:23 | 只看该作者
SDO_TINISHED 或者非 SDO_TINISHED

因此,当中断时,写的while循环会一直等待。

使用特权

评论回复
8
東南博士|  楼主 | 2018-8-22 10:24 | 只看该作者
问题4:  可以读到数据,但在写的时候从站返回05 04 00 00 错误码,也就是SDO协议超时

使用特权

评论回复
9
東南博士|  楼主 | 2018-8-22 10:24 | 只看该作者
最后发现是can口在配置时 没有配置滤波器参数,打开滤波器参数之后,可以写数据成功

使用特权

评论回复
10
東南博士|  楼主 | 2018-8-22 10:24 | 只看该作者
问题5:从上面发现,有些报文后面,主站还是会发出80 00 00 00 的错误码,其属于通用型的错误  而且虽然can口监测到了冲站返回的报文,但是对象字典里面并没有数据,也就是数据并没有存到对象字典中,查看while循环退出后的返回值为0x85,表明也是中断退出。

尝试几次之后发现,如果所读的对象字典的数据的长度不为4个字节(小于4),则会返回错误码  如果数据长度为4个字节,则不会返回错误码,如果数据长度大于4个字节,则while循环不会退出。推测这个可能是SDO读取数据没完成,因为跟踪readNetworkDict函数发现 里面有件SDO数据的长度固定为8个字节

使用特权

评论回复
11
東南博士|  楼主 | 2018-8-22 10:28 | 只看该作者
CANOpen学习指南
对于初学者,相对于其他总线的资料来说,在国内CANOpen的资料并不多。而且并不是所有资料都适合初学者看的。这里给出一些建议,对CANOpen感兴趣的,可以参考一下学习的顺序。

前提:需要对CAN总线有所了解,可以看CAN2.0总线的资料。
当然,对计算机系统、单片机以及编程也需要有一定的基础。

使用特权

评论回复
12
木木guainv| | 2018-8-22 10:28 | 只看该作者
太详细啦  谢谢啊

使用特权

评论回复
13
東南博士|  楼主 | 2018-8-22 10:28 | 只看该作者
第一步:CANOpen Standard 301,这个是一切的基础,最然并不一定马上就要对所有的细节了如指掌,但至少对CANOpen总线以及各种传输控制方式以及其作用需要有一定的了解(比如:NMT、SDO、PDO、HeartBeat等等)。这里不推荐看ZLG的文档,ZLG的文档只是从301文档中,抽出的一些章节中的内容,我相信如果直接看ZLG的文档的话,大部分人是看不懂的。

第二步:最后有一个可以玩的硬件(最好是已经移植好CANOpen协议栈的),否则所有的协议只是资料中的数据格式以及操作方式而已。这样就需要有一个开发板和CAN逻辑分析仪工具。还好我在3年前就已经自己做过一块低成本的CAN的开发板(基于AT90CAN32),并且在这个开发板上实现了基于串口的CAN适配器(可以用于发送各种CAN数据),同时,也在这块板上实现了CANOpen。目前taobao上也有很多种类的CAN开发板和适配器。
在这个硬件上,测试各种CANOpen报文,包括NMT、SDO、PDO,可以远程设置HeartBeat频率,看看收到的HeartBeat报文等。这步完成后,对于CANOpen就有了一定的认识了。对于各种报文,这里要推荐一下ZLG的文档,最后部分对CANOpen的各种报文的格式做了一个总结,查看起来非常方便。

第三步:找个CANOpen的协议栈源码看看,从代码层次来理解CANOpen的各种操作的步骤以及实现方式。当然,目前协议栈也有不少了,有些是免费的,有些是收费的(估计价格还都不便宜)。

第四步:301文档只是描述了CANOpen有那些工具可以使用,但没有任何关于一个模块如何利用这些功能的信息。这样就要看一下CANOpen的各个模块的文档,比如401--I/O模块。不过,并不是所有的这些文档都是免费公开的,可能有些是需要$$才能得到的。

使用特权

评论回复
14
xiaoqizi| | 2018-8-22 10:30 | 只看该作者
我正好用的上  

使用特权

评论回复
15
東南博士|  楼主 | 2018-8-22 10:30 | 只看该作者
CANOpen的几种操作以及数据

1.心跳
CANOpen节点会以一个固定的频率发送心跳报文。用于告诉主机,偶还活着。。。心跳报文的格式很简单,COB-ID为0x700+Node_ID,数据为一字节的状态数据:图中,ID为706,表示06号节点的心跳,状态是0x7F,表示Pre-Operational状态(节点初始化完成后,进入Pre-Operational状态)。查看时间,每个心跳报文时间间隔大概1秒。

使用特权

评论回复
16
東南博士|  楼主 | 2018-8-22 10:30 | 只看该作者
2.NMT
NMT是管理报文,用于实现一些管理操作,比如,节点重启、进入Operational状态等等。NMT报文格式很简单,ID为000,数据为一字节命令+一节节点号(0表示广播)。

使用特权

评论回复
17
東南博士|  楼主 | 2018-8-22 10:31 | 只看该作者
第2号报文就是让06号节点,进入Operational状态,运行完成后,节点心跳报文中的节点状态也变为Operational状态

使用特权

评论回复
18
東南博士|  楼主 | 2018-8-22 10:31 | 只看该作者
同上,发送stop remote node命令,进入Stopped状态,当然,心跳还是有的,只是节点不干活了

这个是reset node命令,用于让节点复位。复位之后,会首先进入Initializing状态(对于于心跳报文中的0x00),初始化完成后,进入Pre-Operational状态(对应心跳报文中的0x7F)。

964375b7ccb001c115.png (95.99 KB )

964375b7ccb001c115.png

使用特权

评论回复
19
東南博士|  楼主 | 2018-8-22 10:32 | 只看该作者
SDO
SDO 主要用来访问节点的对象字典(OD),CANOpen的节点至少需要支持SDO_Server。对象字典是CANOpen节点的数据组织形式,包含了 CANOpen节点的各个参数和数据,比如,心跳报文的发送频率、系统启动次数、节点的通信参数等等等等。可以说,SDO是用来设置CANOpen节点的各个运行参数的。

使用特权

评论回复
20
東南博士|  楼主 | 2018-8-22 10:32 | 只看该作者
图中,1号报文0606: 40 17 10 00 00 00 00 00就是一个SDO_Read报文,告诉节点,要读取的OD索引和子索引,包括数据长度。然后节点会发送对应的数据(后面的那个8字节报文)。第一个字节是一些命令的设定包括参数的设定,后2个字节是OD的索引,再后面一个字节是OD的子索引,最后4个字节是数据。上图中,主机发送的是一个读取OD中 1017:00位置的数据命令,这个位置存放的是心跳频率,读取的结果是0x03EB(1000ms)。



9号报文就是SDO_Write,写OD中1017:00位置的数据,也就是修改心跳频率。收到完成应答后,心跳频率就变了(查看时间)。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

382

主题

6081

帖子

34

粉丝