请选择 进入手机版 | 继续访问电脑版

你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【STM32H7体验】+CANopen协议之NMT

[复制链接]
305765986@qq.co 发布时间:2022-5-28 15:15

3 w' n; W& @3 S% ?) _! k" q
1、心跳帧的格式

' ]; T5 k* f) Z- a: J
ID=0X700+NodeID
其中,数据区为1个字节的节点状态,不同的值对应的含义如下:
例如:节点5处于pre-operational模式,那么它就会定时发送:705 7F

$ D6 o) h' W' i" _$ D$ K
2、对象字典的设置
  1. 1.        /* NMT-heartbeat */\  
    6 O# r3 H) f9 d8 }1 f3 l
  2. 2.            & NODE_PREFIX ## _highestSubIndex_obj1016, /* ConsumerHeartbeatCount */\  
    & p0 z$ }* j5 m, C% r( ?/ ]" Q: ~, ]! d3 b
  3. 3.            NODE_PREFIX ## _obj1016,                   /* ConsumerHeartbeatEntries */\  " C3 G1 T$ G0 s/ m' l( V4 c
  4. 4.            NODE_PREFIX ## _heartBeatTimers,           /* ConsumerHeartBeatTimers  */\  
    / V4 q  W' r; T; |2 M9 f
  5. 5.            & NODE_PREFIX ## _obj1017,                 /* ProducerHeartBeatTime */\  
    1 ^/ {" y  M7 v. d
  6. 6.            TIMER_NONE,                                /* ProducerHeartBeatTimer */\
复制代码
STM32F103作为心跳生产者(配置索引1017)
STM32H7A3作为心跳消费者(配置索引1016)
3、生产者
心跳生产者发送心跳帧的周期由对象字典0x1017ProducerHeartbeat Time的值确定,单位为1ms。
设定发送心跳的定时器:
其中,*d->ProducerHeartBeatTime的值即对象字典0x1017的值。
     每当定时器超时后,将调用ProducerHearbeatAlarm()发送心跳帧:
  1. 1.        /*! The Producer Timer Callback 9 z$ G1 n. M3 I1 u' g
  2. 2.        **
    8 F3 P8 r; b# L9 Y, @
  3. 3.        **
    * b8 r0 ]$ z' _7 {
  4. 4.        ** @param d , a5 w0 W/ ^: v; s2 ~! {0 N; ?
  5. 5.        ** @param id
    & K- X+ I; |0 X
  6. 6.         * @ingroup heartbeato
    4 p6 S( J! b, m, u+ E# K" O
  7. 7.        **/  
    - a  m  {% e2 h  y8 s3 n( o' g! Z
  8. 8.        void ProducerHeartbeatAlarm(CO_Data* d, UNS32 id)    L' _2 r4 |" t' e' `" P
  9. 9.        {  
    ; j. Z% h  N/ [1 p+ N# A
  10. 10.          (void)id;  , {2 W$ I: o$ H: s0 \* ]# q0 Z
  11. 11.          if(*d->ProducerHeartBeatTime)  ' k. D# E( A7 P; V9 Y1 j
  12. 12.            {  
    6 h; m$ I, e/ e, E- Q& A/ t, r" {
  13. 13.              Message msg;  
    % _  H$ `) X, i
  14. 14.              /* Time expired, the heartbeat must be sent immediately
    0 b1 f) Q5 D  w) ^: _0 M
  15. 15.              ** generate the correct node-id: this is done by the offset 1792 ( ?' Y6 Y$ Z4 ]
  16. 16.              ** (decimal) and additionaly 4 W/ y3 U: `0 P! q, _- t$ Q
  17. 17.              ** the node-id of this device.
    & y# l9 ^8 F% {6 L% I
  18. 18.              */  - c$ W1 j% R* q* g0 e$ `3 ]  a
  19. 19.              UNS16 tmp = *d->bDeviceNodeId + 0x700;  7 z" m  J& }3 A0 W
  20. 20.              msg.cob_id = UNS16_LE(tmp);  
    3 @4 T/ M3 `6 S
  21. 21.              msg.len = (UNS8)0x01;  1 Z5 a4 G0 `7 J" n& x  y+ g$ H/ z2 u
  22. 22.              msg.rtr = 0;  
    " d9 k  _1 Q5 |# g& j2 b
  23. 23.              msg.data[0] = d->nodeState; /* No toggle for heartbeat !*/  . N: m  H/ x$ ^5 K! I) `
  24. 24.              /* send the heartbeat */  ( d4 ?9 M* ?$ ?' Y) ~+ l3 a' m+ t
  25. 25.              MSG_WAR(0x3130, "Producing heartbeat: ", d->nodeState);  
    ( m4 }, d' y! p# A
  26. 26.              canSend(d->canHandle,&msg );  % ^! q. |$ `: Y3 W8 S' I
  27. 27.         
    3 i& @8 E) w6 A7 S* R3 y. h
  28. 28.            }else{  . N6 v: |0 t3 W6 I9 o5 l& e+ ^
  29. 29.              d->ProducerHeartBeatTimer = DelAlarm(d->ProducerHeartBeatTimer);  
    1 ^1 u" q1 K/ I
  30. 30.            }  
    ' N: L* j! E" @3 b$ [2 j$ A
  31. 31.        }  9 X  k) v& H0 j0 F6 a5 E8 B
复制代码
' j4 e7 n1 `9 p
4、消费者
       心跳消费者发送心跳帧的周期由对象字典0x1016Consumer HeartbeatTime的值确定,单位为1ms
! `' @# i3 b! ^+ d6 c$ ~  T" z' [
设定接收心跳的定时器:
     每当定时器超时后,将调用ConsumerHeartbeatAlarm()接收心跳帧:
  1. 1.        /*!  
    2 v' D2 U# Q: }$ l! T9 C$ ^
  2. 2.        ** The Consumer Timer Callback 0 u+ b3 D6 {- a( N! Q
  3. 3.        ** % c$ J; L* `9 u& D7 `8 L
  4. 4.        ** @param d + v+ k# I8 s) l
  5. 5.        ** @param id
    ( A: C# i8 ?6 p4 G* {% J2 ]3 v
  6. 6.         * @ingroup heartbeato : p2 _$ H9 m, q$ F
  7. 7.        **/  $ @# ~" \% p' g
  8. 8.        void ConsumerHeartbeatAlarm(CO_Data* d, UNS32 id)  9 o' g. {% B( T. H3 y0 s
  9. 9.        {  - Y" s( U1 ?" K" T; h# r/ F
  10. 10.          UNS8 nodeId = (UNS8)(((d->ConsumerHeartbeatEntries[id]) & (UNS32)0x00FF0000) >> (UNS8)16);  
    + R2 ?% o  {& }! n5 \
  11. 11.          /*MSG_WAR(0x00, "ConsumerHearbeatAlarm", 0x00);*/  + A, d8 z, H1 J
  12. 12.         
    . K5 {# g" K$ j! e1 Q+ U
  13. 13.          /* timer have been notified and is now free (non periodic)*/  
    7 P/ p( |1 }$ f( r5 A/ I1 `4 s
  14. 14.          /* -> avoid deleting re-assigned timer if message is received too late*/    w: E$ {! f; r8 w: |2 {
  15. 15.          d->ConsumerHeartBeatTimers[id]=TIMER_NONE;  7 M  i0 Y) _9 \6 {: H( Y
  16. 16.            
    " ]9 ]) ^  j5 L1 S
  17. 17.          /* set node state */  ' q! T0 r" \( b4 ^( B6 W8 r
  18. 18.          d->NMTable[nodeId] = Disconnected;  9 h! U, @/ X" Y& Z# N- h- |
  19. 19.          /*! call heartbeat error with NodeId */  
    % P  J, r! ^5 [* L7 E! \
  20. 20.          (*d->heartbeatError)(d, nodeId);  & i0 R5 d3 k: n* [: E
  21. 21.        }  
    " q" L9 N5 O1 S, K9 z0 \' N+ c
复制代码

( w- z- k: R* G9 ]

; r6 P1 U" @6 E; c+ @2 l1 @
* k7 y8 g1 f+ b5 d! g4 C, S8 g1 S3 k
5 R' ^& l* d  P/ ?; h
5、测试结果
利用PCAN监控CAN总线网络报文数据。可以看到主节点、从节点的心跳生产者报文701、704。

# d. c1 Y7 m8 p$ G) {) E

; e5 u# k/ ]5 x7 r8 V) x/ F" r
/ k: I, Z! b8 k1 R" K
9 P1 e% }# S1 R# x* G2 Y( K3 Z6 T! @
. x( T4 }5 A* U9 ?( M8 c7 c

. _# c0 `( X4 p- M
" F% _+ t( U) Y' L9 h$ o& p. e
收藏 评论0 发布时间:2022-5-28 15:15

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版