心跳的配置
配置在1000f到1fff的区间
下面看字典生成器的内容
内容是把心跳时间配置成1000=0x3e8(ms),,
配置这些后,配合上一章讲到的定时器和can发送和接收函数的配置,就可以收到1S发送上来的心跳报文。
效果:
PDO的说明
首先给出PDO的一些说明:
下面是TPDO和RPDO的cob-id定义,。
按道理说,只有4个接收对象和4个发送对象,但是可以自己加。
每个对象,都有自己的参数和映射参数(后面再讲),一开始我看的时候,老是不懂什么是对象,其实就是你可以理解为4个结构体,每个结构体都有很多自己成员参数。
注意:其实cobid是可以改的,就是可以不用按照这个来,但是,这是canopen规定了,你用了这个协议。就要用这个范围的id。
然后PDO,包括RPDO和TPDO的索引。
具体细分:
给出字典生成器的内容:
列举给出1800索引的参数,其他的可以自己下载生成器查看
1801索引的参数
pDO参数说明
目前我只用了FF,FE,FD:
子索引02h如果是FF,那么可以配合子索引为05h的定时器触发时间来使用。(我自己只用了这种方法,FFh)
FD,我是用来发送远程帧pDO,发送与相同cobid的TPDO远程帧,从机就会返回该cobid对应的映射参数。。
这个远程帧接收发送好像是不是FD,都是可以回传参数的。
FE,我用来通过RPDO来修改映射参数。
映射参数
一开始我也是一脸懵逼。
后来想明白了。其实就是指针取地址的过程
把数据都放在2000h开始的自定义区域
1A00其实就是相当于存放指针的数组
然后把2000h这个地址放到了1A00种,1A00的子索引01就是放指针2000h的,
至于为什么canfestival为什么要这么做,,可能是为了书写规范 + 方便修改把。
1800索引对应的是1A00,1A00是映射的参数
注意:接收RPDO映射的参数。要和发送方发送的数据要对应上。
RPDO的cobid要和发送方的cobid一样。不然没办法修改,而且映射的参数也要一样
意思就是。我的rpdo映射的内容是什么。你也要遵守。不然修改的值就不是你想要的。
例如,发送方的第一第二字节(映射的第一个参数)想修改速度1000,但是我的rpdo的映射的速度不是在第一第二个字节(映射的第一个参数),而是位置,那么就修改错了。
那个TPDO(远程请求)就能读取到。上一次你修改的值了
TPDO的配置和映射的说明以及实验。
发送远程帧获取相同cobid下映射的数据
1800的子索引02h配置成FDh:远程异步(后来实验发现好像不用FD(用FE也是可以的)都是可以的回传获取数据的)
然后1A00的映射的参数,
从代码可以看到除了速度,其他都是0
使用CAN分析仪作发送方来发送数据:
可以看到第一第二个字节是速度的十六进制 .
配置成FF,时间周期为0x3e8,就是1S,意思就是1S发送一个TPDO1的报文
可以看到TPDO1映射的参数每1S发送一次上来,每次8个字节。
心跳是2S一次。
接收RPDO配置以及实验,包括回调函数
配置成FE。
这里可以看到,接收的映射参数和发送的是一摸一样。
注意:
这里有个误区,不是同一个代码里的发送和接收要一样。
是接收方和发送方映射参数要一样,这里为什么要一样。是为了方便调试。
具体解释看映射参数那个章节
实验现象:
可以看到我之前的数据
修改后
这里要注意的是:
发送的cobid要和接收方的RPDO的cobid一样。才能修改。具体看映射参数那一章
回调函数:
只有接收有回调函数,而且是需要自己接入的,
什么是接入,就是要自己写。自己初始化。
字典生成器那里有回访打勾和不打勾,好像都不会在生成代码上有区别,用程序比较器比较过了。
但最好打上勾
这里是简单的回调函数。,
上面的RPDO实验,修改后会打印
对照上面的
第一个参数是两个字节的,所以是002Bh = 43
第二个参数是一个字节的,所以是15h=24
给上简单的代码
而且。…///////////////////////////////
回调函数必须要加上,
return OD_SUCCESSFUL;
不然。假如第一个参数的回调函数没有加上return OD_SUCCESSFUL;,
那么第二个参数的回调函数就不会执行。
UNS32 index0x2000_0x00_callback(CO_Data* d, const indextable *table, UNS8 bSubindex)
{
if(table->pSubindex[bSubindex].size==1)
printf("%d\r\n",*(UNS8*)(table->pSubindex[bSubindex].pObject));
else if(table->pSubindex[bSubindex].size==2)
printf("%d\r\n",*(UNS16*)(table->pSubindex[bSubindex].pObject));
else if (table->pSubindex[bSubindex].size==4)
printf("%d\r\n",*(UNS32*)(table->pSubindex[bSubindex].pObject));
//一定要加,不然该PDO对象的下一个参数就无法修改,例如 2001_00的参数
return OD_SUCCESSFUL;
}
UNS32 index0x2001_0x00_callback(CO_Data* d, const indextable *table, UNS8 bSubindex)
{
if(table->pSubindex[bSubindex].size==1)
printf("%d\r\n",*(UNS8*)(table->pSubindex[bSubindex].pObject));
else if(table->pSubindex[bSubindex].size==2)
printf("%d\r\n",*(UNS16*)(table->pSubindex[bSubindex].pObject));
else if (table->pSubindex[bSubindex].size==4)
printf("%d\r\n",*(UNS32*)(table->pSubindex[bSubindex].pObject));
return OD_SUCCESSFUL;
}
//添加回调函数
void Call_Back_Init()
{
RegisterSetODentryCallBack(&TestSlave_Data,0x2000, 0, index0x2000_0x00_callback);
RegisterSetODentryCallBack(&TestSlave_Data,0x2001, 0, index0x2001_0x00_callback);
}
canfestival 是怎么映射的
这两个结构体。写了TestSlave_objdict的各个参数与首地址的距离