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

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

[复制链接]
aimejia 发布时间:2018-5-28 14:50
本帖最后由 aimejia 于 2018-5-28 14:54 编辑
5 _; W4 y4 N! M8 }0 |" s" ~, R1 m9 m. [
1 bxCAN工作模式" b1 v  W0 Z0 q) Y4 r
bxCAN有3个主要的工作模式:初始化模式、正常模式和睡眠模式。
0 y  t: H: \, K# t: J! L$ |& A# X$ J  i/ v6 v- L5 h
在硬件复位后,bxCAN工作在睡眠模式以节省电能,同时CANTX引脚的内部上拉电阻被激活。软件通过对CAN_MCR寄存器的INRQ或SLEEP位置’1’,可以请求bxCAN进入初始化或睡眠模式。一旦进入了初始化或睡眠模式,bxCAN就对CAN_MSR寄存器的INAK或SLAK位置’1’来进行确认,同时内部上拉电阻被禁用。* {2 i! |: P7 y/ b1 ^3 ~

+ H0 [8 w$ t, ^6 H9 ?当INAK和SLAK位都为’0’时,bxCAN就处于正常模式。在进入正常模式前,bxCAN必须跟CAN总线取得同步;为取得同步,bxCAN要等待CAN总线达到空闲状态,即在CANRX引脚上监测到11个连续的隐性位。
0 h3 ?$ ?- G3 {$ ?% A9 R
# z# @3 C: s1 g0 u0 g1.1 初始化模式软件初始化应该在硬件处于初始化模式时进行。设置CAN_MCR寄存器的INRQ位为’1’,请求bxCAN进入初始化模式,然后等待硬件对CAN_MSR寄存器的INAK位置’1’来进行确认。+ t% ?( v) e7 _
   
; Z1 w6 t0 q# \3 Q9 ^3 P+ ]; N清除CAN_MCR寄存器的INRQ位为’0’,请求bxCAN退出初始化模式,当硬件对CAN_MSR寄存器的INAK位清’0’就确认了初始化模式的退出。( b4 \) g2 B2 ], o
   
' d& Z' A8 C; P6 N当bxCAN处于初始化模式时,禁止报文的接收和发送,并且CANTX引脚输出隐性位(高电平)。初始化模式的进入,不会改变配置寄存器。
$ t$ N  E7 v9 m) ?, s7 ^& Y$ K* B* |1 \1 X5 g
软件对bxCAN的初始化,至少包括位时间特性(CAN_BTR)和控制(CAN_MCR)这2个寄存器。
1 e$ F) k7 v4 L/ I5 B; \& g) K/ K9 V在对bxCAN的过滤器组(模式、位宽、FIFO关联、激活和过滤器值)进行初始化前,软件要对CAN_FMR寄存器的FINIT位设置’1’。对过滤器的初始化可以在非初始化模式下进行。$ J- @" b" I& p" Q

+ Z# i9 N+ U/ y6 e8 a, s" N注: 当FINIT=1时,报文的接收被禁止。可以先对过滤器激活位清’0’(在CAN_FA1R中),然后修改相应过滤器的值。如果过滤器组没有使用,那么就应该让它处于非激活状态(保持其FACT位为清’0’状态)。
  w- {7 M6 l7 R2 ^) }! M! q* z. f& b
1.2 正常模式& c+ y3 Z4 q1 g9 v- X9 I4 p
在初始化完成后,软件应该让硬件进入正常模式,以便正常接收和发送报文。软件可以通过对CAN_MCR寄存器的INRQ位清’0’,来请求从初始化模式进入正常模式,然后要等待硬件对CAN_MSR寄存器的INAK位置’1’的确认。在跟CAN总线取得同步,即在CANRX引脚上监测到11个连续的隐性位(等效于总线空闲)后,bxCAN才能正常接收和发送报文。( F. t, e5 I% K# U2 ~/ [* I$ J

" u, Y6 X0 `  @不需要在初始化模式下进行过滤器初值的设置,但必须在它处在非激活状态下完成(相应的FACT位为0)。而过滤器的位宽和模式的设置,则必须在初始化模式中进入正常模式前完成。/ Q, Y: o, P. ^( \
, J2 F2 N  F7 M: r% ?2 U9 Q, J3 l
1.3 睡眠模式(低功耗)
% O' V; Q, Q' f$ W1 d( F8 d* RbxCAN可工作在低功耗的睡眠模式。软件通过对CAN_MCR寄存器的SLEEP位置’1’,来请求进入这一模式。在该模式下,bxCAN的时钟停止了,但软件仍然可以访问邮箱寄存器。' A6 p& n9 I# q3 h- m& a9 p
; H' `% y$ P2 z( |7 J5 k, P
当bxCAN处于睡眠模式,软件必须对CAN_MCR寄存器的INRQ位置’1’并且同时对SLEEP位清’0’,才能进入初始化模式。; d' J& I' X. b1 @! N1 I1 |
有2种方式可以唤醒(退出睡眠模式)bxCAN:通过软件对SLEEP位清’1’,或硬件检测到CAN总线的活动。
/ d, U2 h+ E( O) F8 {* Y# V+ B3 {: G/ f; _+ @! s( j& a
如果CAN_MCR寄存器的AWUM位为’1’,一旦检测到CAN总线的活动,硬件就自动对SLEEP位清’0’来唤醒bxCAN。如果CAN_MCR寄存器的AWUM位为’0’,软件必须在唤醒中断里对SLEEP位清’0’才能退出睡眠状态。8 \/ u4 K+ q/ z% Z8 c5 u6 t0 Z

3 W) R2 \* Z/ |9 i5 ]: i; U& ]注: 如果唤醒中断被允许(CAN_IER寄存器的WKUIE位为’1’),那么一旦检测到CAN总线活动就会产生唤醒中断,而不管硬件是否会自动唤醒bxCAN。6 v: S- X! V8 R' N  R
在对SLEEP位清’0’后,睡眠模式的退出必须与CAN总线同步,当硬件对SLAK位清’0’时,就确认了睡眠模式的退出。
/ w% z4 I3 Y) s. W/ o: G( R8 s! L( ]  H( ^: F  Y  k
2 测试模式
) ]* r6 X5 y, w/ F通过对CAN_BTR寄存器的SILM和/或LBKM位置’1’,来选择一种测试模式。只能在初始化模式下,修改这2位。在选择了一种测试模式后,软件需要对CAN_MCR寄存器的INRQ位清’0’,来真正进入测试模式。
8 w" _8 R- A& O; k, W
- T5 T, P. l. l2.1 静默模式- S0 D) p9 t! e) N# E4 p
通过对CAN_BTR寄存器的SILM位置’1’,来选择静默模式。
& C! K/ K0 p% t
  m. s& l# n+ @" X- ~& z2 O在静默模式下,bxCAN可以正常地接收数据帧和远程帧,但只能发出隐性位,而不能真正发送报文。如果bxCAN需要发出显性位(确认位、过载标志、主动错误标志),那么这样的显性位在内部被接回来从而可以被CAN内核检测到,同时CAN总线不会受到影响而仍然维持在隐性位状态。因此,静默模式通常用于分析CAN总线的活动,而不会对总线造成影响-显性位(确认位、错误帧)不会真正发送到总线上。3 Q! E6 j6 {* p2 M" P

  M6 g6 g4 C+ `( L$ c6 i, D
1.jpg
                                                                              图1                                                                                   
2.2 环回模式. \% a4 M- G- s1 }# W/ K
通过对CAN_BTR寄存器的LBKM位置’1’,来选择环回模式。在环回模式下,bxCAN把发送的报文当作接收的报文并保存(如果可以通过接收过滤)在接收邮箱里。
7 T1 _5 z+ K' o' w3 J" N0 u0 b0 C
& n0 q& c1 J7 L8 r; r3 x
2.jpg
                                                                                                        图28 d% @. s4 k, M2 `. L

* S% y& P9 f" x4 t环回模式可用于自测试。为了避免外部的影响,在环回模式下CAN内核忽略确认错误(在数据/远程帧的确认位时刻,不检测是否有显性位)。在环回模式下,bxCAN在内部把Tx输出回馈到Rx输入上,而完全忽略CANRX引脚的实际状态。发送的报文可以在CANTX引脚上检测到。% Q7 ^) g: C- R5 t7 R* ]

" [! m8 f0 O6 \6 p& T+ C( V; J0 x2.3 环回静默模式+ _6 Q0 C8 w5 M. T9 m
通过对CAN_BTR寄存器的LBKM和SILM位同时置’1’,可以选择环回静默模式。该模式可用于“热自测试”,即可以象环回模式那样测试bxCAN,但却不会影响CANTX和CANRX所连接的整个CAN系统。在环回静默模式下,CANRX引脚与CAN总线断开,同时CANTX引脚被驱动到隐性位状态。3 w* X! f8 @, q% I! q" o
$ j" ?; W+ h( q9 m5 q, k
3.jpg
                                                                                                        图3
7 z# ~2 O" F# }7 }8 q2 ]- F4 @6 z* `
% B6 ?6 d# Q, g7 Y3 如何设置工作模式' u7 @9 t) c; X  l9 H2 R1 `$ `4 w0 E, {
固件接口如下:( Y6 T1 E& a0 k9 d9 P! T
  1. [cpp] view plain copy
    . I2 l3 D+ I) h  i
  2. /**
    7 }* x' D; J8 ?: n' Z2 z
  3.   * @brief  Selects the CAN Operation mode. - |, Y% h3 o" t; b
  4.   * @param  CAN_OperatingMode: CAN Operating Mode. , ]# a, V4 W2 B0 A
  5.   *         This parameter can be one of @ref CAN_OperatingMode_TypeDef enumeration.
    ! a2 K- }' B* L( d8 u
  6.   * @retval status of the requested mode which can be ; w/ m( E1 x4 o
  7.   *         - CAN_ModeStatus_Failed:  CAN failed entering the specific mode . F% A* [  d# w. w' w4 O8 e
  8.   *         - CAN_ModeStatus_Success: CAN Succeed entering the specific mode
    1 a/ L: Q$ J) e& p1 T+ A8 D+ ?
  9.   */ 7 e  z9 E& G* `! c1 h
  10. uint8_t CAN_OperatingModeRequest(CAN_TypeDef* CANx, uint8_t CAN_OperatingMode);
复制代码
CAN_operating_mode如下定义:
$ G3 j) e4 u+ ~0 l" \; M8 ~
  1. [cpp] view plain copy
    ( j. D4 g7 R* F: k# Z3 H1 R7 ~- e
  2. /** 1 r$ D+ d6 o8 A7 o2 A0 V
  3.   * @defgroup CAN_operating_mode
    # Q  u% z1 G3 T  M7 q
  4.   * @{
    * X. X3 Z4 p) o% S
  5.   */
    ( q0 h% i) w3 c* m0 L
  6. #define CAN_OperatingMode_Initialization  ((uint8_t)0x00) /*!< Initialization mode */ 3 j$ H4 K* n/ `9 p5 v( @9 G5 C
  7. #define CAN_OperatingMode_Normal          ((uint8_t)0x01) /*!< Normal mode */
    % d3 G2 Q9 a0 v: ?
  8. #define CAN_OperatingMode_Sleep           ((uint8_t)0x02) /*!< sleep mode */
    6 u8 C. B) U* g& A
复制代码
8 ]! S9 a) Y; S0 F# G$ s% z9 b
4 如何设置测试模式
, m, h) F7 N: d. z4 O$ ?* J' V' n) m
  1. [cpp] view plain copy
    * T0 A1 A. ^. X3 B, y4 q
  2. /** @defgroup CAN_operating_mode & {  P& R4 x; U5 a" A, g
  3.   * @{ # q0 ?, A$ a; }% {$ I' {. V; \# X
  4.   */ ' Q4 Q  {; f/ c, ~7 E4 f% i
  5. #define CAN_Mode_Normal             ((uint8_t)0x00)  /*!< normal mode */
    1 {6 b, L# G- J5 u
  6. #define CAN_Mode_LoopBack           ((uint8_t)0x01)  /*!< loopback mode */ / S9 e* |9 `* Y* M* l
  7. #define CAN_Mode_Silent             ((uint8_t)0x02)  /*!< silent mode */ & Y: x) I, @8 e* }
  8. #define CAN_Mode_Silent_LoopBack    ((uint8_t)0x03)  /*!< loopback combined with silent mode */
复制代码
在CAN初始化函数接口CAN_Init调用时,使用CAN_TypeDef类型的CAN_Mode定义了CAN的测试模式,其值如上所定义。如下所示:
! k8 v2 [8 Q3 J  j1 X
  1. [cpp] view plain copy
    ) }! O# B" P9 ?& r
  2. CAN_DeInit(CAN1);
    # e5 L, x! @  }& P2 g: I( i+ \9 D
  3. CAN-StructInit(&CAN_InitStructure); 4 c5 m8 Q5 }3 Z$ x' _: T  n
  4. //... 6 M$ ]% u; `) e) r0 S* b
  5. CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;//正常模式,或者设置为测试模式 8 [5 H$ B9 i% r# n5 B  |9 r/ L
  6. //...
    # Y1 O- W: N. R
  7. if (CAN_Init(CAN1,&CAN_InitStructure) == CANINITFAILED) 5 K: o4 m( p# \
  8. {
    6 w5 s  q+ V( X9 {9 I
  9.     //... : a% l+ w' R' ~, ]7 q& [) [9 v
  10. } 3 w: D) R  _! Z! }
  11. //...
复制代码
2 |" p2 T8 Q4 H* ~$ R* ?/ o: }
5 控制和状态寄存器0 D' P: @. r! n, k; H) ~% X1 A
5.1 CAN主控制寄存器 (CAN_MCR)
( D* d  y1 R$ A5 ^4 X地址偏移量: 0x001 Z! j5 ^1 ]! f# {
复位值: 0x0001 0002
3 c! [6 N' g6 p4 k  s
' F$ X; f0 d+ B8 A  u+ d
4.jpg
                                                                                                     图4
( V0 k  a5 l# M% M1 t
* O* Z: B3 A8 F. l位31:16        保留,硬件强制为0。) w4 j1 J8 |4 E$ q, D, J% i2 p
位15        RESET: bxCAN 软件复位+ e) M/ e' v! O" v' V7 T
0: 本外设正常工作;
  O4 c. ~$ T5 w; J/ K* P1: 对bxCAN进行强行复位,复位后bxCAN进入睡眠模式(FMP位和CAN_MCR寄存器被初始化为其复位值)。此后硬件自动对该位清0。
1 B4 q  p  @; i位14:8        保留,硬件强制为0。& s. u9 u$ ^+ G9 p4 H5 L
位7        TTCM: 时间触发通信模式7 f8 |/ f& X5 A; N! S
0: 禁止时间触发通信模式;
$ t8 r+ j$ J1 |1: 允许时间触发通信模式。
  H' I. B" q! m$ m. \注: 要想了解关于时间触发通信模式的更多信息,请参考21.4.2:时间触发通信模式。
* _" _( L7 W: Q- W: t位6        ABOM: 自动离线(Bus-Off)管理$ D- Y# @, Z7 b' f7 v! L4 r
该位决定CAN硬件在什么条件下可以退出离线状态。7 z+ |0 E0 Q3 t
0: 离线状态的退出是在,软件对CAN_MCR寄存器的INRQ位进行置1随后清0后,一旦硬件检测到128次11位连续的隐性位,就退出离线状态;/ |4 c, @- J( A" j2 i; e( z
1: 一旦硬件检测到128次11位连续的隐性位,自动退出离线状态。
+ p0 U2 f& o+ i( |, @2 t( _位5        AWUM: 自动唤醒模式: `: g8 \' s" N
该位决定CAN处在睡眠模式时由硬件还是软件唤醒
" ]( q5 t3 m. B2 m- a# M0: 睡眠模式通过清除CAN_MCR寄存器的SLEEP位,由软件唤醒;
+ E8 b2 \: ?7 p6 M  L4 R1: 睡眠模式通过检测CAN报文,由硬件自动唤醒。唤醒的同时,硬件自动对CAN_MSR寄存器的SLEEP和SLAK位清0 。
' @! m8 T' O, k8 w" S# z4 Y2 R位4        NART: 禁止报文自动重传, O) ~! O5 }5 p3 G# N
0: 按照CAN标准,CAN硬件在发送报文失败时会一直自动重传直到发送成功;
: M! y/ @1 i- B, W8 y& m1: CAN报文只被发送1次,不管发送的结果如何(成功、出错或仲裁丢失)。. j6 x( ^5 A& h" L1 b5 r. ~
位3        RFLM: 接收FIFO锁定模式
+ w1 s) T- u# y7 P0: 在接收溢出时FIFO未被锁定,当接收FIFO的报文未被读出,下一个收到的报文会覆盖原有的报文;
! z# p" i; d( U6 C' H0 S+ r1: 在接收溢出时FIFO被锁定,当接收FIFO的报文未被读出,下一个收到的报文会被丢弃。
4 _% p1 w, _; k3 B9 [) i% v位2        TXFP: 发送FIFO优先级% K6 Z, x7 i6 Q  y
当有多个报文同时在等待发送时,该位决定这些报文的发送顺序  C0 p7 _& ~/ e4 u  f
0: 优先级由报文的标识符来决定;
, J$ }6 ~; f. {& ]1: 优先级由发送请求的顺序来决定。4 }& Q, M9 l: R$ g
位1        SLEEP: 睡眠模式请求" e. H; v& G8 e! m7 _- z
软件对该位置1可以请求CAN进入睡眠模式,一旦当前的CAN活动(发送或接收报文)结束,CAN就进入睡眠。
* c- j. W; \, L- P软件对该位清0使CAN退出睡眠模式。% y6 ~1 E: V& N. I  B' d/ K9 J* Y/ T
当设置了AWUM位且在CAN Rx信号中检测出SOF位时,硬件对该位清0。5 A+ v6 t, Y6 F4 l+ H4 g
在复位后该位被置1-CAN在复位后处于睡眠模式。4 K, z3 L2 a. q: d
位0        INRQ: 初始化请求( Z  f8 c# W3 }5 {( `6 v
软件对该位清0可使CAN从初始化模式进入正常工作模式:当CAN在接收引脚检测到连续的11个隐性位后,CAN就达到同步,并为接收和发送数据作好准备了。为此,硬件相应地对CAN_MSR寄存器的INAK位清0。9 {2 k# L% j. r$ A$ |8 p. y8 `- n: \
软件对该位置1可使CAN从正常工作模式进入初始化模式:一旦当前的CAN活动(发送或接收)结束,CAN就进入初始化模式。相应地,硬件对CAN_MSR寄存器的INAK位置1。5 O. U* Z7 o6 B$ P3 o0 C3 j

# k* m: P1 d( r/ q7 M' D. x5.2 CAN主状态寄存器 (CAN_MSR)
9 n6 r$ m8 R: G6 A# B; P) I' L  e0 d- I+ Y地址偏移量: 0x04
5 [5 \: v+ L) u% g- y1 X- g复位值: 0x0000 0C02  b5 u  C! f; R3 I* B
% @1 K8 _4 @) I
5.jpg
                                                                                                        图57 [  v$ l2 `% j% @9 h

5 d1 H- h7 o  H2 l% A; p位31:12        保留位,硬件强制为0
0 d/ I4 F0 g3 d. J3 j) G! G位11        RX: CAN接收电平* y( q& V8 E; {0 _/ E5 C* U# N
该位反映CAN接收引脚(CAN_RX)的实际电平。
! ^9 U* M" D0 a位10        SAMP: 上次采样值0 j6 Q5 V9 B6 _
CAN接收引脚的上次采样值(对应于当前接收位的值)。% z- _% l7 y9 m* _
位9        RXM: 接收模式
( r7 ~& b6 N" U# [该位为1表示CAN当前为接收器。
5 q8 I# v& K+ i, E7 ]) `. P, N8 \位8        TXM: 发送模式1 W) z( A& R0 u# z. p, Q5 p0 |
该位为1表示CAN当前为发送器。
2 t. U1 a' N) z& E% W位7:5        保留位,硬件强制为0。; X/ o4 ^3 P- m8 m
位4        SLAKI: 睡眠确认中断
" Z0 R! t- \$ b. m1 P0 W当SLKIE=1, 一旦CAN进入睡眠模式硬件就对该位置1,紧接着相应的中断被触发。软件可对该位清0,当SLAK位被清0时硬件也对该位清0。) `+ o2 D' k. Z/ [
注: 当SLKIE=0, 不应该查询该位,而应该查询SLAK位来获知睡眠状态。
* n; R9 M9 S! n, C3 j/ [6 B; @位3        WKUI: 唤醒中断挂号
$ U4 l! t5 ?3 \4 m6 O  B! u2 ]8 g7 |当CAN处于睡眠状态,一旦帧起始位(SOF)被检测到,硬件就对该位置1;并且如果CAN_IER寄存器的WKUIE位为1,则相应的中断被触发。
9 }5 ?+ }' y+ k, D5 _该位由软件清0。2 r( g1 M4 T* n6 S1 N" g' y% A' R' G
位2        ERRI: 出错中断挂号
" X; f5 ?7 A4 X1 H3 a当由于检测到出错而对CAN_ESR 寄存器的某位置1,并且CAN_IER 寄存器的相应中断使能位也被置1时,硬件对该位置1;并且如果CAN_IER寄存器的ERRIE位为1则错误中断被触发。7 e, C* }$ ?1 a
该位由软件清0。
4 e: A/ C( N8 D% n' M! B0 j位1        SLAK: 睡眠模式确认. M; H& r9 Z$ C, y6 h3 f
当CAN进入睡眠模式时硬件就对该位置1,从而供软件进行状态查询。 该位是对软件请求进入睡眠模式的确认(对CAN_MCR寄存器的SLEEP位置1)。当CAN退出睡眠模式时硬件对该位清0 (需要跟CAN总线同步)。 这里跟CAN总线同步是指,硬件需要在CAN的RX引脚上检测到连续的11位隐性位。9 m$ |+ d! e* j
注: 通过软件或硬件对CAN_MCR 的SLEEP位清0,是开启退出睡眠模式过程的唯一途径。有关清除SLEEP位的详细信息,参见CAN_MCR寄存器的AWUM位的描述。; T4 N: U) P  ^) `* j; I3 u6 v
位0        INAK: 初始化确认: o6 @  |7 u6 }" G4 M6 e6 H$ S
当CAN进入初始化模式时硬件就对该位置1,从而供软件进行状态查询。 该位是对软件请求进入初始化模式的确认(对CAN_MCR寄存器的INRQ位置1)。# v5 ^; ?4 c6 q6 G
当CAN退出初始化模式时硬件对该位清0 (需要跟CAN总线同步)。这里跟CAN总线同步是指,硬件需要在CAN的RX引脚上检测到连续的11位隐性位。* H2 P+ k* ~& s  R( A

# G$ w. d; `  D2 O
% G- {, Q* v9 q0 z6 E7 P( y  Q( c( a8 S  a0 r( ^

% `2 ?: P# O, F$ o转载自flydream0
1 l6 O6 e- ?9 c
3 W: p+ Q3 f5 f' s& d. c7 v* a) F* n& ?7 B5 A4 I6 {

* G2 r9 r7 M4 I7 o7 D1 j/ T2 M
赞 收藏 2 评论0 发布时间:2018-5-28 14:50

举报

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