[应用相关] STM32-CANOpen报文类型

[复制链接]
2897|3
 楼主| dingbo95 发表于 2018-7-15 19:18 | 显示全部楼层 |阅读模式
CANOpen应用层协议细化了CAN总线协议中关于标识符的定义。定义标准报文的11比特标识符中高4比特为功能码,后7比特为节点号,重命名为通讯对象标识符(COB-ID)。
功能码将所有的报文分为7个优先级,按照优先级从高至低依次为:网络命令报文(NMT)、同步报文(SYNC)、紧急报文(EMERGENCY)、时间戳(TIME)、过程数据对象(PDO)、服务数据对象(SDO)、节点状态报文(NMT Err Control)

7位的节点号则表明CANOpen网络最多可支持127个节点共存(0号节点为主站),下表给出了各报文的COB-ID范围。


 楼主| dingbo95 发表于 2018-7-15 19:19 | 显示全部楼层
20170115223041645.png

MNT命令为最高优先级报文,由CANOpen主站发出,用以更改从节点的运行状态。

SYNC报文定期由CANOpen主站发出,所有的同步PDO根据SYNC报文发送。

EMERGENCY报文由出现紧急状态的从节点发出,任何具备紧急事件监控与处理能力的节点会接收并处理紧急报文。

TIME报文由CANOpen主站发出,用于同步所有从站的内部时钟。

PDO分为4对发送和接收PDO,每一个节点默认拥有4对发送PDO和接收PDO,用于过程数据传递。

SDO分为发送SDO和接收SDO,用于读写对象字典。

MT Error Control报文由从节点发出,用以监视从节点的运行状态。


 楼主| dingbo95 发表于 2018-7-15 19:20 | 显示全部楼层
在def.h中用代码表述了各种报文的功能码
  1. #define NMT                0x0        //网络命令报文
  2. #define SYNC                0x1        //同步报文
  3. #define TIME_STAMP        0x2        //时间报文
  4. #define PDO1tx                0x3        //过程数据对象1发送报文
  5. #define PDO1rx                0x4        //过程数据对象1接收报文
  6. #define PDO2tx                0x5        //过程数据对象2发送报文
  7. #define PDO2rx                0x6        //过程数据对象2接收报文
  8. #define PDO3tx                0x7        //过程数据对象3发送报文
  9. #define PDO3rx                0x8        //过程数据对象3接收报文
  10. #define PDO4tx                0x9        //过程数据对象4发送报文
  11. #define PDO4rx                0xA        //过程数据对象4接收报文
  12. #define SDOtx                0xB        //服务数据对象接收报文
  13. #define SDOrx                0xC        //服务数据对象发送报文
  14. #define NODE_GUARD        0xE        //节点守护报文
  15. #define LSS                    0xF        //层配置服务报文


 楼主| dingbo95 发表于 2018-7-15 19:21 | 显示全部楼层
在移植CANOpen时,CAN总线接收到报文后要调用CANOpen提供的接口canDispatch根据功能码进行报文处理,在states.c中定义了canDispatch函数
  1. <code class="language-cpp">/* 定时事件触发处理函数 */  
  2. void canDispatch(CO_Data *d, Message *m)  
  3. {  
  4.     /* 取出cob_id */  
  5.     UNS16 cob_id = UNS16_LE(m->cob_id);  
  6.   
  7.     /* 判断报文类型 */  
  8.     switch(cob_id >> 7)  
  9.     {  
  10.         /* 同步/紧急报文 */  
  11.         case SYNC:  
  12.             /* 同步报文COB-ID为0x80 */  
  13.             if(cob_id == 0x080)  
  14.             {  
  15.                 /* 当前状态下允许同步报文,则进行处理 */  
  16.                 if(d->CurrentCommunicationState.csSYNC)  
  17.                     proceedSYNC(d);  
  18.             }   
  19.             /* 紧急报文COB-ID为0x81-0xFF */  
  20.             else  
  21.             {  
  22.                 /* 当前状态下允许紧急报文,则进行处理 */  
  23.                 if(d->CurrentCommunicationState.csEmergency)  
  24.                     proceedEMCY(d,m);  
  25.             }  
  26.             break;  
  27.   
  28.         /* 时间报文 */  
  29.         /* case TIME_STAMP: */  
  30.               
  31.         /* PDO报文 */  
  32.         case PDO1tx:  
  33.         case PDO1rx:  
  34.         case PDO2tx:  
  35.         case PDO2rx:  
  36.         case PDO3tx:  
  37.         case PDO3rx:  
  38.         case PDO4tx:  
  39.         case PDO4rx:  
  40.             /* 当前状态下允许PDO报文,则进行处理 */  
  41.             if(d->CurrentCommunicationState.csPDO)  
  42.                 proceedPDO(d,m);  
  43.             break;  
  44.               
  45.         /* SDO报文 */  
  46.         case SDOtx:  
  47.         case SDOrx:  
  48.             /* 当前状态下允许SDO报文,则进行处理 */  
  49.             if(d->CurrentCommunicationState.csSDO)  
  50.                 proceedSDO(d,m);  
  51.             break;  
  52.               
  53.         /* 心跳/节点守护报文 */  
  54.         case NODE_GUARD:  
  55.             /* 当前状态下允许心跳/节点守护报文,则进行处理 */  
  56.             if(d->CurrentCommunicationState.csLifeGuard)  
  57.                 proceedNODE_GUARD(d,m);  
  58.             break;  
  59.          
  60.         /* 改变节点状态报文 */  
  61.         case NMT:  
  62.             /* 用于主站改变从站状态,所以从站才会收到 */  
  63.             if(*(d->iam_a_slave))  
  64.             {  
  65.                 proceedNMTstateChange(d,m);  
  66.             }  
  67.             break;  
  68.               
  69. #ifdef CO_ENABLE_LSS  
  70.         /* 层设置服务报文 */  
  71.         case LSS:  
  72.             if(!d->CurrentCommunicationState.csLSS)  
  73.                 break;  
  74.   
  75.             if((*(d->iam_a_slave)) && cob_id==MLSS_ADRESS)  
  76.             {  
  77.                 proceedLSS_Slave(d,m);  
  78.             }  
  79.             else if(!(*(d->iam_a_slave)) && cob_id==SLSS_ADRESS)  
  80.             {  
  81.                 proceedLSS_Master(d,m);  
  82.             }  
  83.             break;  
  84. #endif  
  85.     }  
  86. }  
  87. </code>  


您需要登录后才可以回帖 登录 | 注册

本版积分规则

52

主题

1197

帖子

5

粉丝
快速回复 在线客服 返回列表 返回顶部