发新帖本帖赏金 1.00元(功能说明)我要提问
返回列表
打印

CanOpen协议【CanFestival】移植方法 支持VC、QT、STM32

[复制链接]
楼主: daboy5279
手机看帖
扫描二维码
随时随地手机跟帖
61
本帖最后由 ncutjun 于 2017-3-9 16:15 编辑

学习了学习了,不懂再来问大牛

使用特权

评论回复
62
ncutjun| | 2017-3-9 15:42 | 只看该作者
本帖最后由 ncutjun 于 2017-3-9 16:15 编辑

谢谢楼主

使用特权

评论回复
63
ncutjun| | 2017-3-9 17:14 | 只看该作者
大牛,我看了你的关于CANOPEN移植的帖子,正在试着自己移植;期待你整理的关于SDO PDO EDS文件装载等相关知识。谢谢啦

使用特权

评论回复
64
yangsmithcool| | 2017-4-11 09:44 | 只看该作者
学习了,感谢楼主

使用特权

评论回复
65
yongwong99| | 2017-4-19 22:26 | 只看该作者
mark!

使用特权

评论回复
66
superzfy| | 2017-5-1 14:44 | 只看该作者
谢谢

使用特权

评论回复
67
woshizhengjie89| | 2017-5-8 14:04 | 只看该作者
楼主,CAN不是物理层的吗?  CANOPEN 移植到VC,QT上 难道是在 嵌入式系统(WINCE,LINUX)上使用吗?

使用特权

评论回复
68
yansideyu| | 2017-5-16 17:04 | 只看该作者
你们移植canopen的时候,PDO的传输类型254 255遇到过问题吗?我的不按照EventTimer去触发

使用特权

评论回复
69
lby147612| | 2017-7-21 10:05 | 只看该作者
楼主辛苦了,看看也研究一下!!

使用特权

评论回复
70
qin552011373| | 2017-8-6 20:45 | 只看该作者
woshizhengjie89 发表于 2017-5-8 14:04
楼主,CAN不是物理层的吗?  CANOPEN 移植到VC,QT上 难道是在 嵌入式系统(WINCE,LINUX)上使用吗? ...

CANopen像是tcpip,只是个协议栈

使用特权

评论回复
71
liujianbao| | 2017-10-18 15:56 | 只看该作者
多谢啦,好多东西都是靠这个帖子搞定的

使用特权

评论回复
72
liujianbao| | 2017-10-20 15:37 | 只看该作者
心跳报文,改了宏定义之后,心跳报文正常100ms,一旦发送sdo之后变成20ms,80ms交替的,这个是怎么回事啊

使用特权

评论回复
73
liujianbao| | 2017-10-20 15:41 | 只看该作者
xumin383838 发表于 2016-7-13 08:24
#define MS_TO_TIMEVAL(ms) ((ms) * 1)//((ms) * 125)           //,我更改了这个值,心跳正常了,但是很奇怪,我 ...

你搞定没,我这个也没弄好

使用特权

评论回复
74
whj4674672| | 2017-11-16 14:34 | 只看该作者
谢谢楼主了。

使用特权

评论回复
75
whj4674672| | 2017-12-2 17:56 | 只看该作者
yansideyu 发表于 2017-5-16 17:04
你们移植canopen的时候,PDO的传输类型254 255遇到过问题吗?我的不按照EventTimer去触发 ...

遇到同样问题了,知道你解决了没有

使用特权

评论回复
76
PippenWang| | 2018-1-3 14:12 | 只看该作者
本帖最后由 PippenWang 于 2018-1-5 15:39 编辑

参照楼主的移植方法,目前基本解决了心跳的问题(可以通过修改对象字典中参数0x1017的值设置producer心跳),心跳问题也困扰了我好几天。由于也没有深究,仅仅分享一下经验。心跳不准可以尝试以下内容:

1. 确定定时器调用时间,即确定 timerForCan(void) 函数多长时间调用一次。这个主要与硬件定时器的配置有关,楼主在1楼建议说的是:"另外还要开一个1毫秒的定时器,每1毫秒调用一下 timerForCan(void) 这个函数”。canFestival是用一个定时器A模拟多个浮动定时器B,我们在移植canFestival到不同平台上时,所实现的“每1毫秒调用一下 timerForCan(void)”的硬件定时器即定时器A。

2. 定时器A与定时器B的时间转换,主要与#define MS_TO_TIMEVAL(ms) 的宏定义有关。MS_TO_TIMEVAL(ms)的定义在canFestival协议栈的“timerscfg.h”文件中,含义为:定时器A的1ms转换成浮动定时器B的1ms所对应的时间值。如上述1中,硬件定时器时间间隔为1ms,则#define MS_TO_TIMEVAL(ms) ((ms) * 1);从协议栈MS_TO_TIMEVAL的注释“// The timer is incrementing every 8 us.”来看,协议栈中的原硬件定时器A的时间间隔为8us,所以协议栈中的宏定义为#define MS_TO_TIMEVAL(ms) ((ms) * 125)。

3.“timerscfg.h”文件中还要注意#define TIMEVAL_MAX这个宏定义值,这个值表示硬件定时器的最大值,16位定时器对应 #define TIMEVAL_MAX 0xFFFF;32位定时器则对应 #define TIMEVAL_MAX 0xFFFFFFFF。上述2.3两点内容具体可参考作者softwind在帖子中的说明。

4. 楼主在1楼中,定义了unsigned int TIMER_MAX_COUNT = 70000; //最大时间计数。 这个值在 timerForCan(void)函数中,作为变量TimeCNT计数的判断条件,当超过TIMER_MAX_COUNT的值,TimeCNT的计数值归零。由于我使用的是32位定时器,当我把硬件定时器A的时间间隔设为8us时,TIMER_MAX_COUNT = 70000在心跳值很大时不够用,从而导致心跳值不准确。因此可根据使用要求将TIMER_MAX_COUNT 定义值相应增大(如定时器A时间间隔为8us,设心跳时间为1s,此时TIMER_MAX_COUNT 最小需为125*1000)。

5. 函数TIMEVAL getElapsedTime(void) 的实现。getElapsedTime()在TimeDispatch()函数中被调用,用来获取自上次心跳以来经过的时间。将1楼中getElapsedTime()函数替换如下:TIMEVAL getElapsedTime(void) {
        int ret = 0;
        ret = TimeCNT >= last_time_set ?
                        TimeCNT - last_time_set : TimeCNT + TIMEVAL_MAX - last_time_set;
        last_time_set = TimeCNT;
        return ret;
},72楼所述“心跳报文,改了宏定义之后,心跳报文正常100ms,一旦发送sdo之后变成20ms,80ms交替的”应该是跟这个函数有关。

6. 参数0x1017所设置的心跳时间,是在协议栈中heartbeatInit()函数中,赋给ProducerHeartBeatTime这个变量的,然后再通过调用SetAlarm()函数,赋给浮动定时器B(当0x1017为0时,不发送心跳帧)。

7.若以上仍未能解决心跳不准的问题,建议静下心来找一找,再分享给大家。

目前我这边PDO,SDO通讯还没有完全调通,欢迎大家分享这方面的经验。

最后感谢楼主和softwind。

使用特权

评论回复
77
PippenWang| | 2018-1-3 14:18 | 只看该作者
本帖最后由 PippenWang 于 2018-1-3 14:21 编辑
PippenWang 发表于 2018-1-3 14:12
参照楼主的移植方法,目前基本解决了心跳的问题(可以通过修改对象字典中参数0x1017的值设置producer心跳), ...

第3点链接发不了,搜这个吧:“菜鸟也想出把力 RT-Thread + STM32 + CanOpen(开源的CanFestival)”

捕获.PNG (53.18 KB )

捕获.PNG

使用特权

评论回复
78
PippenWang| | 2018-1-4 15:30 | 只看该作者
本帖最后由 PippenWang 于 2018-1-5 15:39 编辑
PippenWang 发表于 2018-1-3 14:12
参照楼主的移植方法,目前基本解决了心跳的问题(可以通过修改对象字典中参数0x1017的值设置producer心跳), ...

再补充一点:

8. 通过SDO通讯写0x1017参数值,来动态修改心跳时间。还需要在0x1017参数被修改之后,将几个计时的变量设为初始值:包括(1)TimeCNT = 0; //时间计数;(2)NextTime = 0; //下一次触发时间计数;(3)last_time_set = TIMEVAL_MAX; //上一次的时间计数; (4)total_sleep_time = TIMEVAL_MAX,total_sleep_time 这个变量在协议栈文件“timer.c”中。这个设初始值的函数我目前是放在SetAlarm()函数中。

捕获2.PNG (31.86 KB )

捕获2.PNG

使用特权

评论回复
79
xiefengxiyu| | 2018-4-2 11:27 | 只看该作者
本帖最后由 xiefengxiyu 于 2018-4-10 14:18 编辑

....

使用特权

评论回复
80
xiefengxiyu| | 2018-4-3 16:17 | 只看该作者

你好 现在还在搞canopen协议嘛 想问几个问题

使用特权

评论回复
发新帖 本帖赏金 1.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则