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

STM32之CAN---工作/测试模式浅析

[复制链接]
aimejia 发布时间:2018-5-28 14:50
本帖最后由 aimejia 于 2018-5-28 14:54 编辑 & G3 U" P) r. `; z9 }; Y
; N9 ?) q3 M! `, l* N2 s
1 bxCAN工作模式" F4 i/ Z3 Y) d2 ?8 k0 C
bxCAN有3个主要的工作模式:初始化模式、正常模式和睡眠模式。
2 u% K& F) y9 a8 z
- G% ?9 A  O! i$ z在硬件复位后,bxCAN工作在睡眠模式以节省电能,同时CANTX引脚的内部上拉电阻被激活。软件通过对CAN_MCR寄存器的INRQ或SLEEP位置’1’,可以请求bxCAN进入初始化或睡眠模式。一旦进入了初始化或睡眠模式,bxCAN就对CAN_MSR寄存器的INAK或SLAK位置’1’来进行确认,同时内部上拉电阻被禁用。2 S. F5 f! }* \/ j
  a+ _) \. r9 W2 Z( Y: A
当INAK和SLAK位都为’0’时,bxCAN就处于正常模式。在进入正常模式前,bxCAN必须跟CAN总线取得同步;为取得同步,bxCAN要等待CAN总线达到空闲状态,即在CANRX引脚上监测到11个连续的隐性位。. L7 o( X9 }1 ^* |# J

' f( ~/ }4 _. B# Z: O8 U+ \1.1 初始化模式软件初始化应该在硬件处于初始化模式时进行。设置CAN_MCR寄存器的INRQ位为’1’,请求bxCAN进入初始化模式,然后等待硬件对CAN_MSR寄存器的INAK位置’1’来进行确认。, n) _2 |9 \# ?) ~
    ; @% e  @$ E  H5 ~. M* O
清除CAN_MCR寄存器的INRQ位为’0’,请求bxCAN退出初始化模式,当硬件对CAN_MSR寄存器的INAK位清’0’就确认了初始化模式的退出。- Q" A# Q  D: E1 p# q5 x6 ?- ]; p3 _0 S
    , h& {7 w' ?, g1 ]8 P1 w
当bxCAN处于初始化模式时,禁止报文的接收和发送,并且CANTX引脚输出隐性位(高电平)。初始化模式的进入,不会改变配置寄存器。
0 K3 t7 U7 O7 e
/ n3 S' i3 S4 a5 i4 N! p软件对bxCAN的初始化,至少包括位时间特性(CAN_BTR)和控制(CAN_MCR)这2个寄存器。
  \5 j9 R# O8 W1 P$ o8 e  k在对bxCAN的过滤器组(模式、位宽、FIFO关联、激活和过滤器值)进行初始化前,软件要对CAN_FMR寄存器的FINIT位设置’1’。对过滤器的初始化可以在非初始化模式下进行。) ^: L: P4 N& s1 U1 h2 Z1 f
' Y5 c+ V' f4 e# z1 R# T
注: 当FINIT=1时,报文的接收被禁止。可以先对过滤器激活位清’0’(在CAN_FA1R中),然后修改相应过滤器的值。如果过滤器组没有使用,那么就应该让它处于非激活状态(保持其FACT位为清’0’状态)。
& e3 M  ~) t& I
( J2 F- r5 m& p) }2 v) j1.2 正常模式/ z' Q- Z# [" f: p/ q" F' h
在初始化完成后,软件应该让硬件进入正常模式,以便正常接收和发送报文。软件可以通过对CAN_MCR寄存器的INRQ位清’0’,来请求从初始化模式进入正常模式,然后要等待硬件对CAN_MSR寄存器的INAK位置’1’的确认。在跟CAN总线取得同步,即在CANRX引脚上监测到11个连续的隐性位(等效于总线空闲)后,bxCAN才能正常接收和发送报文。2 g2 E3 D) W4 u* |. j2 P  _

( q7 ?6 B6 T' I& z5 s: X" j不需要在初始化模式下进行过滤器初值的设置,但必须在它处在非激活状态下完成(相应的FACT位为0)。而过滤器的位宽和模式的设置,则必须在初始化模式中进入正常模式前完成。
, {9 @* H3 n7 z9 ~% G: H& b  m% h8 U' c8 L
1.3 睡眠模式(低功耗)3 M9 ^+ ]2 m, v) R9 T
bxCAN可工作在低功耗的睡眠模式。软件通过对CAN_MCR寄存器的SLEEP位置’1’,来请求进入这一模式。在该模式下,bxCAN的时钟停止了,但软件仍然可以访问邮箱寄存器。
# X# V% Y1 E- t- u) g6 T0 c0 b! }1 x! b( T+ j
当bxCAN处于睡眠模式,软件必须对CAN_MCR寄存器的INRQ位置’1’并且同时对SLEEP位清’0’,才能进入初始化模式。
7 K3 v6 ]7 D) h! Y9 |0 u有2种方式可以唤醒(退出睡眠模式)bxCAN:通过软件对SLEEP位清’1’,或硬件检测到CAN总线的活动。$ B' ~. P3 j1 p# g2 W5 D; I* _$ F
: D. a; u4 e6 x2 [7 ^8 Y
如果CAN_MCR寄存器的AWUM位为’1’,一旦检测到CAN总线的活动,硬件就自动对SLEEP位清’0’来唤醒bxCAN。如果CAN_MCR寄存器的AWUM位为’0’,软件必须在唤醒中断里对SLEEP位清’0’才能退出睡眠状态。
; @  |0 c/ w7 a# F/ z7 B0 N) d% y8 y
( T0 X  {1 p; Z$ g* x注: 如果唤醒中断被允许(CAN_IER寄存器的WKUIE位为’1’),那么一旦检测到CAN总线活动就会产生唤醒中断,而不管硬件是否会自动唤醒bxCAN。
, o' [- |7 O3 V% `# j1 l" W在对SLEEP位清’0’后,睡眠模式的退出必须与CAN总线同步,当硬件对SLAK位清’0’时,就确认了睡眠模式的退出。
( G& `) k4 Q8 B! c% A
. q, D. a" z2 K: L' m2 测试模式
) H; V8 X/ U$ S% c# e1 L通过对CAN_BTR寄存器的SILM和/或LBKM位置’1’,来选择一种测试模式。只能在初始化模式下,修改这2位。在选择了一种测试模式后,软件需要对CAN_MCR寄存器的INRQ位清’0’,来真正进入测试模式。2 H! R: V5 {  }: A5 \; L1 v' d
$ H. O; @+ Q+ T8 e( \
2.1 静默模式3 v6 d- M) A" @+ b- J
通过对CAN_BTR寄存器的SILM位置’1’,来选择静默模式。
' t9 Q7 T: K9 y- H" a
/ I. g0 e. w! J+ N在静默模式下,bxCAN可以正常地接收数据帧和远程帧,但只能发出隐性位,而不能真正发送报文。如果bxCAN需要发出显性位(确认位、过载标志、主动错误标志),那么这样的显性位在内部被接回来从而可以被CAN内核检测到,同时CAN总线不会受到影响而仍然维持在隐性位状态。因此,静默模式通常用于分析CAN总线的活动,而不会对总线造成影响-显性位(确认位、错误帧)不会真正发送到总线上。0 `8 l/ ^. G1 i& _( {
! L! Q7 _+ G% N
1.jpg
                                                                              图1                                                                                   
2.2 环回模式4 t+ @& T6 T6 x
通过对CAN_BTR寄存器的LBKM位置’1’,来选择环回模式。在环回模式下,bxCAN把发送的报文当作接收的报文并保存(如果可以通过接收过滤)在接收邮箱里。; }7 I* R* D6 J  H

, ^9 a/ }: |% \' K1 D( ~
2.jpg
                                                                                                        图2
& ]5 \5 L+ g8 q3 F  Y! ~
6 Z9 ?1 W. N! t6 F9 ~4 r) P) [2 d环回模式可用于自测试。为了避免外部的影响,在环回模式下CAN内核忽略确认错误(在数据/远程帧的确认位时刻,不检测是否有显性位)。在环回模式下,bxCAN在内部把Tx输出回馈到Rx输入上,而完全忽略CANRX引脚的实际状态。发送的报文可以在CANTX引脚上检测到。
) Z) {+ i+ s+ T+ W. e* O1 Y2 P8 Y
3 g% P% f( ?  U1 ]; o) k2.3 环回静默模式
4 o* @' Z: @: s3 u% I& x通过对CAN_BTR寄存器的LBKM和SILM位同时置’1’,可以选择环回静默模式。该模式可用于“热自测试”,即可以象环回模式那样测试bxCAN,但却不会影响CANTX和CANRX所连接的整个CAN系统。在环回静默模式下,CANRX引脚与CAN总线断开,同时CANTX引脚被驱动到隐性位状态。7 G( _; _4 o2 c7 i8 ^7 K3 ]& [
* S. I( P- h- H+ |# Y* }  l, A
3.jpg
                                                                                                        图3
3 y, \" W. ]% `$ o" q: s4 R4 U) N; f6 Z- E4 R8 x
3 如何设置工作模式/ c! b8 v( V: y# \% k) t7 P* M" d# N
固件接口如下:% h& ]  H) K( e* l0 Q1 p$ n
  1. [cpp] view plain copy
    : q0 l8 Q0 V' M7 J6 F' L! |$ `! w1 ]
  2. /**
    " j3 Z( v" t) S
  3.   * @brief  Selects the CAN Operation mode. + l1 M+ Z: g$ u
  4.   * @param  CAN_OperatingMode: CAN Operating Mode. 2 u6 b! d2 w% n  s/ n9 K( q
  5.   *         This parameter can be one of @ref CAN_OperatingMode_TypeDef enumeration. 7 ]: e) G; r) _) }* ]$ M2 Y. |
  6.   * @retval status of the requested mode which can be % |: S8 A; U' f7 X7 M, T% i
  7.   *         - CAN_ModeStatus_Failed:  CAN failed entering the specific mode / e  M; f, _1 @9 T4 S+ T
  8.   *         - CAN_ModeStatus_Success: CAN Succeed entering the specific mode
    * o' C# }: L- W, N5 G. l
  9.   */ 0 o% x2 Y) h' N6 W( t* d
  10. uint8_t CAN_OperatingModeRequest(CAN_TypeDef* CANx, uint8_t CAN_OperatingMode);
复制代码
CAN_operating_mode如下定义:
& `+ i1 O+ s: h) t
  1. [cpp] view plain copy. u  ]+ n6 P8 _2 {2 D
  2. /**
    4 o1 w& }8 c: \4 A2 R  s$ r
  3.   * @defgroup CAN_operating_mode " |" w7 r( ?6 ?* |7 Y' e# _4 f7 \
  4.   * @{ 6 A* M6 J4 j# b' |  D
  5.   */ 2 t1 b5 p/ H2 x& w7 g  u
  6. #define CAN_OperatingMode_Initialization  ((uint8_t)0x00) /*!< Initialization mode */
    + A5 Q5 B5 b2 b+ `7 x
  7. #define CAN_OperatingMode_Normal          ((uint8_t)0x01) /*!< Normal mode */
    - T; g6 J- @/ {' T+ Z: ^4 @1 W9 H% s
  8. #define CAN_OperatingMode_Sleep           ((uint8_t)0x02) /*!< sleep mode */
    ( t7 F- c3 c1 v
复制代码

' Q$ A( o4 \3 u0 ~8 m% w  \0 `4 如何设置测试模式$ P! u% u, U+ \$ ?/ S
  1. [cpp] view plain copy
    3 |5 r. G% z* j9 N0 Q
  2. /** @defgroup CAN_operating_mode / ^. Z* _  e( M( x$ D( e* @/ u$ n
  3.   * @{ . s" v# V7 L' C8 M. m
  4.   */ . z$ o# B! ~$ {" l. y3 ?* J
  5. #define CAN_Mode_Normal             ((uint8_t)0x00)  /*!< normal mode */
    5 f- w% s6 l; O, ]
  6. #define CAN_Mode_LoopBack           ((uint8_t)0x01)  /*!< loopback mode */
    . H, E0 Z$ `! ]
  7. #define CAN_Mode_Silent             ((uint8_t)0x02)  /*!< silent mode */ ) a- y- C  n9 p" n0 k0 _$ l, z  n
  8. #define CAN_Mode_Silent_LoopBack    ((uint8_t)0x03)  /*!< loopback combined with silent mode */
复制代码
在CAN初始化函数接口CAN_Init调用时,使用CAN_TypeDef类型的CAN_Mode定义了CAN的测试模式,其值如上所定义。如下所示:
- s6 s9 {& J) r8 w6 ]$ \
  1. [cpp] view plain copy3 W4 z1 @9 [- Q% U
  2. CAN_DeInit(CAN1); ( S6 p7 V- m! t4 N
  3. CAN-StructInit(&CAN_InitStructure);
    ( K0 P2 r) K0 a6 Y  h" b
  4. //... 1 [9 C- K) a4 z/ A
  5. CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;//正常模式,或者设置为测试模式 4 h4 @! h' |' u* k
  6. //... ! O3 T& T, p) U/ r+ k' p# U
  7. if (CAN_Init(CAN1,&CAN_InitStructure) == CANINITFAILED) # I. W2 e0 R/ n4 z. W
  8. { - z+ f1 @/ c& O- y1 ^
  9.     //...
    7 r$ i" g2 S5 _. g
  10. }
    , F, W0 V( q7 Q. f
  11. //...
复制代码
; N$ h7 ]) l! D+ U% `1 u& f
5 控制和状态寄存器0 Y$ u, _6 v! U% b
5.1 CAN主控制寄存器 (CAN_MCR)) |9 H$ y" @8 A2 W
地址偏移量: 0x003 I' L& N  u: a) e& _9 l+ [, n
复位值: 0x0001 0002) E7 ?, G8 n+ X+ |

% l6 X8 M! }. S# _- C: Q+ _
4.jpg
                                                                                                     图4
1 o. R4 n7 B: ~6 G4 x
7 t% j- B: }' J* L/ A) O# Q位31:16        保留,硬件强制为0。
/ _$ p5 G2 s+ w3 H, v, ^% \! o位15        RESET: bxCAN 软件复位
( K" m7 ?9 X2 y" D% Q0: 本外设正常工作;
! ~! a8 p' h% _- r& g6 O* e1: 对bxCAN进行强行复位,复位后bxCAN进入睡眠模式(FMP位和CAN_MCR寄存器被初始化为其复位值)。此后硬件自动对该位清0。
' l4 J# u5 Z5 f- o; n位14:8        保留,硬件强制为0。. k2 K9 x% k7 i7 Q( z3 {4 \' {: n) D
位7        TTCM: 时间触发通信模式. B: o+ T4 B  Y- R; M( c- N
0: 禁止时间触发通信模式;" ?: W( w, @  U  A6 W- d
1: 允许时间触发通信模式。) i/ t# V$ `6 D# n
注: 要想了解关于时间触发通信模式的更多信息,请参考21.4.2:时间触发通信模式。
/ Y3 _  F0 w( [% B位6        ABOM: 自动离线(Bus-Off)管理7 b( y- l  V7 ?' X: |8 A9 Y
该位决定CAN硬件在什么条件下可以退出离线状态。" v+ g: g1 a- Q3 S" k- c
0: 离线状态的退出是在,软件对CAN_MCR寄存器的INRQ位进行置1随后清0后,一旦硬件检测到128次11位连续的隐性位,就退出离线状态;
: T% D  g: _/ E$ r: `6 l1: 一旦硬件检测到128次11位连续的隐性位,自动退出离线状态。
8 P6 W5 l7 ~# |) `* s# `# u) ~1 u位5        AWUM: 自动唤醒模式" ~8 l# f( ~3 |( ~: Y
该位决定CAN处在睡眠模式时由硬件还是软件唤醒
5 v1 C; [. v' ]6 Q0: 睡眠模式通过清除CAN_MCR寄存器的SLEEP位,由软件唤醒;
8 l9 l& y6 W4 V6 k# @' W1: 睡眠模式通过检测CAN报文,由硬件自动唤醒。唤醒的同时,硬件自动对CAN_MSR寄存器的SLEEP和SLAK位清0 。
8 ?1 a/ K+ ^( _! x. ?: |9 Z位4        NART: 禁止报文自动重传
% _4 J: s# l- Q7 j/ v0 K0: 按照CAN标准,CAN硬件在发送报文失败时会一直自动重传直到发送成功;
0 V1 @" h* o) v- f7 J1: CAN报文只被发送1次,不管发送的结果如何(成功、出错或仲裁丢失)。8 \6 ]! b/ i5 @' j
位3        RFLM: 接收FIFO锁定模式1 i6 c' X  |) U) I+ H) @
0: 在接收溢出时FIFO未被锁定,当接收FIFO的报文未被读出,下一个收到的报文会覆盖原有的报文;
% b2 ]3 q8 C- ?3 T/ M; X1 ?  h  e7 q1: 在接收溢出时FIFO被锁定,当接收FIFO的报文未被读出,下一个收到的报文会被丢弃。( C; @% z  |' F7 d3 ^: \5 e
位2        TXFP: 发送FIFO优先级4 h# @4 f' f( {. N: f: w& a
当有多个报文同时在等待发送时,该位决定这些报文的发送顺序4 r  z3 E% A3 [' R
0: 优先级由报文的标识符来决定;0 M1 \' p8 p' L8 }% n( L/ d# j. h
1: 优先级由发送请求的顺序来决定。
0 ?1 c( p* [% O& u1 k  ~位1        SLEEP: 睡眠模式请求9 Y# q6 {# S' p. e
软件对该位置1可以请求CAN进入睡眠模式,一旦当前的CAN活动(发送或接收报文)结束,CAN就进入睡眠。
% `8 g; f/ u$ |/ t软件对该位清0使CAN退出睡眠模式。
" {8 j) B  j& s0 T& Y, \, ~& w当设置了AWUM位且在CAN Rx信号中检测出SOF位时,硬件对该位清0。
8 E, ]% N; ~. F0 {在复位后该位被置1-CAN在复位后处于睡眠模式。6 O4 K, ]5 e9 m
位0        INRQ: 初始化请求- L* k' _& H% R3 r
软件对该位清0可使CAN从初始化模式进入正常工作模式:当CAN在接收引脚检测到连续的11个隐性位后,CAN就达到同步,并为接收和发送数据作好准备了。为此,硬件相应地对CAN_MSR寄存器的INAK位清0。# X6 h' f  X% u/ l- t( v: L8 i4 o
软件对该位置1可使CAN从正常工作模式进入初始化模式:一旦当前的CAN活动(发送或接收)结束,CAN就进入初始化模式。相应地,硬件对CAN_MSR寄存器的INAK位置1。, J9 h, `) `  l- v# f( c7 T( ]' _
$ h4 B+ \9 u1 R; v4 v+ S2 n
5.2 CAN主状态寄存器 (CAN_MSR)0 K8 S) b& j, `# F
地址偏移量: 0x04
3 ]' u& h. g9 T. c复位值: 0x0000 0C02" `  f/ ^+ D  R: j1 o+ m
0 W# M) y+ x  r# `) g
5.jpg
                                                                                                        图5/ P) y0 e2 M- u- F% ?& X

3 A, X' O4 l% X+ j位31:12        保留位,硬件强制为0
; b/ G; s/ g4 Y- B位11        RX: CAN接收电平# P: q2 b- G- J5 M3 L
该位反映CAN接收引脚(CAN_RX)的实际电平。
/ c' T# C; j5 w; G位10        SAMP: 上次采样值6 |; t" R" i3 O% T7 h6 w
CAN接收引脚的上次采样值(对应于当前接收位的值)。
1 m, }$ Z  @6 S  N/ V( ^位9        RXM: 接收模式4 [  t3 l6 k$ E$ u0 [% X  |
该位为1表示CAN当前为接收器。
: p, P# e7 m) d  P  q位8        TXM: 发送模式9 a" l7 p8 E" I% ^
该位为1表示CAN当前为发送器。1 r' s7 p4 v* r" [
位7:5        保留位,硬件强制为0。7 W, N8 {2 n% i8 P# [, X' |& R
位4        SLAKI: 睡眠确认中断% [) X1 E: @- g0 k! R3 W, ^+ y7 R
当SLKIE=1, 一旦CAN进入睡眠模式硬件就对该位置1,紧接着相应的中断被触发。软件可对该位清0,当SLAK位被清0时硬件也对该位清0。
! x+ c' S8 h/ j, y' j. `注: 当SLKIE=0, 不应该查询该位,而应该查询SLAK位来获知睡眠状态。
; B/ Z5 [: o5 R( x# }位3        WKUI: 唤醒中断挂号
$ i3 q$ c  h0 Z- {2 i当CAN处于睡眠状态,一旦帧起始位(SOF)被检测到,硬件就对该位置1;并且如果CAN_IER寄存器的WKUIE位为1,则相应的中断被触发。
2 `0 C( Z1 D3 |( t$ I该位由软件清0。9 K- s! L' m" h& |+ Y: w
位2        ERRI: 出错中断挂号
) D) ~8 }* [" T当由于检测到出错而对CAN_ESR 寄存器的某位置1,并且CAN_IER 寄存器的相应中断使能位也被置1时,硬件对该位置1;并且如果CAN_IER寄存器的ERRIE位为1则错误中断被触发。
. S5 b7 M2 S9 d  L4 F该位由软件清0。
3 m; g: {$ h2 |) z6 `& {% {' p& f位1        SLAK: 睡眠模式确认. g# ^6 ?, s9 V) S
当CAN进入睡眠模式时硬件就对该位置1,从而供软件进行状态查询。 该位是对软件请求进入睡眠模式的确认(对CAN_MCR寄存器的SLEEP位置1)。当CAN退出睡眠模式时硬件对该位清0 (需要跟CAN总线同步)。 这里跟CAN总线同步是指,硬件需要在CAN的RX引脚上检测到连续的11位隐性位。
; J) m0 }5 p8 I. ^( G( Y注: 通过软件或硬件对CAN_MCR 的SLEEP位清0,是开启退出睡眠模式过程的唯一途径。有关清除SLEEP位的详细信息,参见CAN_MCR寄存器的AWUM位的描述。+ X0 X; ]* Q9 [9 v5 L" @
位0        INAK: 初始化确认
+ B0 @, i9 `+ Q当CAN进入初始化模式时硬件就对该位置1,从而供软件进行状态查询。 该位是对软件请求进入初始化模式的确认(对CAN_MCR寄存器的INRQ位置1)。) M: M/ s0 |, z& y. l
当CAN退出初始化模式时硬件对该位清0 (需要跟CAN总线同步)。这里跟CAN总线同步是指,硬件需要在CAN的RX引脚上检测到连续的11位隐性位。6 l) E% X; M5 K0 u9 ]
* i2 {! c" a( V# i  J, r
$ ~& `; I3 j7 F' f4 j

: [  _+ L3 d8 S: i  A3 u. C1 G' k
6 l1 R0 _* u) W1 {转载自flydream0; A6 R/ r  ^: e. `. P6 d( c
$ I( d' {8 D5 s- ~/ v; X

; J3 h8 d+ G/ _+ k
* c* T4 x6 Z& E
赞 收藏 2 评论0 发布时间:2018-5-28 14:50

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版