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

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

[复制链接]
aimejia 发布时间:2018-5-28 14:50
本帖最后由 aimejia 于 2018-5-28 14:54 编辑 . V8 d7 \7 F& Y0 x, O

# ~5 ]/ q8 u( e1 bxCAN工作模式
) ~+ @4 o! j& l8 ^% QbxCAN有3个主要的工作模式:初始化模式、正常模式和睡眠模式。* t/ [$ ^$ A; q' P/ ]0 i6 W, A
" N! u, k9 t6 E  l
在硬件复位后,bxCAN工作在睡眠模式以节省电能,同时CANTX引脚的内部上拉电阻被激活。软件通过对CAN_MCR寄存器的INRQ或SLEEP位置’1’,可以请求bxCAN进入初始化或睡眠模式。一旦进入了初始化或睡眠模式,bxCAN就对CAN_MSR寄存器的INAK或SLAK位置’1’来进行确认,同时内部上拉电阻被禁用。
8 M& M: W) d0 u
: Y) J* I! A& h2 X9 O; F当INAK和SLAK位都为’0’时,bxCAN就处于正常模式。在进入正常模式前,bxCAN必须跟CAN总线取得同步;为取得同步,bxCAN要等待CAN总线达到空闲状态,即在CANRX引脚上监测到11个连续的隐性位。
5 P3 V; s7 Q0 l9 g0 ]
) {1 a# S( ~7 |+ A1.1 初始化模式软件初始化应该在硬件处于初始化模式时进行。设置CAN_MCR寄存器的INRQ位为’1’,请求bxCAN进入初始化模式,然后等待硬件对CAN_MSR寄存器的INAK位置’1’来进行确认。
9 Q- p* ^" \. j$ D* r, S' c% p5 B   
/ L7 i5 w7 A1 j" |4 }3 A清除CAN_MCR寄存器的INRQ位为’0’,请求bxCAN退出初始化模式,当硬件对CAN_MSR寄存器的INAK位清’0’就确认了初始化模式的退出。
$ g6 a# ]5 ]+ b) [& u% j   
, h& g; ?% y3 `- m+ u当bxCAN处于初始化模式时,禁止报文的接收和发送,并且CANTX引脚输出隐性位(高电平)。初始化模式的进入,不会改变配置寄存器。
2 H+ H* y% Z1 \
, A: B7 ?8 C5 D- T' q软件对bxCAN的初始化,至少包括位时间特性(CAN_BTR)和控制(CAN_MCR)这2个寄存器。
8 j& w' o8 I: G  G. L$ {8 p在对bxCAN的过滤器组(模式、位宽、FIFO关联、激活和过滤器值)进行初始化前,软件要对CAN_FMR寄存器的FINIT位设置’1’。对过滤器的初始化可以在非初始化模式下进行。
) e8 `2 v0 Y9 H4 H. p
$ l% C" y( J. |/ }* P注: 当FINIT=1时,报文的接收被禁止。可以先对过滤器激活位清’0’(在CAN_FA1R中),然后修改相应过滤器的值。如果过滤器组没有使用,那么就应该让它处于非激活状态(保持其FACT位为清’0’状态)。4 ?: p  x4 k6 y3 |# H. K
: N1 J, k# f( G+ a
1.2 正常模式. r3 X2 u: [3 t1 B2 b
在初始化完成后,软件应该让硬件进入正常模式,以便正常接收和发送报文。软件可以通过对CAN_MCR寄存器的INRQ位清’0’,来请求从初始化模式进入正常模式,然后要等待硬件对CAN_MSR寄存器的INAK位置’1’的确认。在跟CAN总线取得同步,即在CANRX引脚上监测到11个连续的隐性位(等效于总线空闲)后,bxCAN才能正常接收和发送报文。
0 a: g* J, e# n- Y# C0 l7 i3 N* |) [, s* _3 y
不需要在初始化模式下进行过滤器初值的设置,但必须在它处在非激活状态下完成(相应的FACT位为0)。而过滤器的位宽和模式的设置,则必须在初始化模式中进入正常模式前完成。# r# `6 r; |8 M) O' f

+ T& E; A+ W' f, W% h/ n/ p* q1.3 睡眠模式(低功耗)/ H  W+ D! r  N. {3 N2 U0 ]( c
bxCAN可工作在低功耗的睡眠模式。软件通过对CAN_MCR寄存器的SLEEP位置’1’,来请求进入这一模式。在该模式下,bxCAN的时钟停止了,但软件仍然可以访问邮箱寄存器。
& x1 R" _$ F! U" ]
, i* y& `$ C1 N; {5 B3 q3 f当bxCAN处于睡眠模式,软件必须对CAN_MCR寄存器的INRQ位置’1’并且同时对SLEEP位清’0’,才能进入初始化模式。; M8 z& w: q" l
有2种方式可以唤醒(退出睡眠模式)bxCAN:通过软件对SLEEP位清’1’,或硬件检测到CAN总线的活动。
2 @( z" t) T, w3 Q% R8 @& L
8 x) ~0 x( }7 _& S$ Q- `6 E: \/ s如果CAN_MCR寄存器的AWUM位为’1’,一旦检测到CAN总线的活动,硬件就自动对SLEEP位清’0’来唤醒bxCAN。如果CAN_MCR寄存器的AWUM位为’0’,软件必须在唤醒中断里对SLEEP位清’0’才能退出睡眠状态。& |/ T" ^, f0 J7 y* W, o; F" F
0 k5 \. C# v" y. g( B
注: 如果唤醒中断被允许(CAN_IER寄存器的WKUIE位为’1’),那么一旦检测到CAN总线活动就会产生唤醒中断,而不管硬件是否会自动唤醒bxCAN。
7 [* d/ n6 x: d- F) r+ z在对SLEEP位清’0’后,睡眠模式的退出必须与CAN总线同步,当硬件对SLAK位清’0’时,就确认了睡眠模式的退出。, f9 k, I* c, Q5 B7 X1 N

* \  I8 ~! C+ a: w+ X/ t* G& n2 测试模式3 z5 A2 ~9 D3 \7 ^- s# Q5 V/ A; }
通过对CAN_BTR寄存器的SILM和/或LBKM位置’1’,来选择一种测试模式。只能在初始化模式下,修改这2位。在选择了一种测试模式后,软件需要对CAN_MCR寄存器的INRQ位清’0’,来真正进入测试模式。
7 P' M. E4 o% g1 b; x' s' l3 {7 S5 i- N9 Z
2.1 静默模式4 K5 h* o5 _8 u
通过对CAN_BTR寄存器的SILM位置’1’,来选择静默模式。3 s: v5 y4 p+ S

3 p' U8 s" j0 ^" q8 ?7 t8 \在静默模式下,bxCAN可以正常地接收数据帧和远程帧,但只能发出隐性位,而不能真正发送报文。如果bxCAN需要发出显性位(确认位、过载标志、主动错误标志),那么这样的显性位在内部被接回来从而可以被CAN内核检测到,同时CAN总线不会受到影响而仍然维持在隐性位状态。因此,静默模式通常用于分析CAN总线的活动,而不会对总线造成影响-显性位(确认位、错误帧)不会真正发送到总线上。
6 o8 B1 S- n4 N$ ~7 I4 U5 W4 f$ t# r, t, g
1.jpg
                                                                              图1                                                                                   
2.2 环回模式% r0 X( c# Z6 e4 e$ l
通过对CAN_BTR寄存器的LBKM位置’1’,来选择环回模式。在环回模式下,bxCAN把发送的报文当作接收的报文并保存(如果可以通过接收过滤)在接收邮箱里。0 p) p+ F/ [( M' W( M& x9 k

; e, E2 g6 d' g1 t; G
2.jpg
                                                                                                        图2
: @; @( I' {( o! y
% T) ~8 C/ Q$ l+ x环回模式可用于自测试。为了避免外部的影响,在环回模式下CAN内核忽略确认错误(在数据/远程帧的确认位时刻,不检测是否有显性位)。在环回模式下,bxCAN在内部把Tx输出回馈到Rx输入上,而完全忽略CANRX引脚的实际状态。发送的报文可以在CANTX引脚上检测到。
. y$ w" R3 }+ p) a
# T% V- S. z5 a  X2.3 环回静默模式" @+ N! |' O- K( S% t+ T8 S" s
通过对CAN_BTR寄存器的LBKM和SILM位同时置’1’,可以选择环回静默模式。该模式可用于“热自测试”,即可以象环回模式那样测试bxCAN,但却不会影响CANTX和CANRX所连接的整个CAN系统。在环回静默模式下,CANRX引脚与CAN总线断开,同时CANTX引脚被驱动到隐性位状态。
3 F! E* L) p% P' P4 u3 ?+ ^* G- R( I0 }
3.jpg
                                                                                                        图3
: @+ `; l  J5 [. `# v" y2 I5 c* e" x
3 如何设置工作模式
3 M. e0 _7 u9 L) }固件接口如下:
. A* d# ?( |; z
  1. [cpp] view plain copy  L; B) V# n4 R0 ]$ w5 A' R5 U( i
  2. /**
    $ s( H! F$ d, T  d
  3.   * @brief  Selects the CAN Operation mode.
      Y% W2 V" C3 @- m0 @
  4.   * @param  CAN_OperatingMode: CAN Operating Mode.
    : z6 g' }' u7 F0 t3 C
  5.   *         This parameter can be one of @ref CAN_OperatingMode_TypeDef enumeration.
    2 p. \' i1 f  e, L
  6.   * @retval status of the requested mode which can be
    , }: W; k4 T! M+ u8 K& m* C+ e7 E
  7.   *         - CAN_ModeStatus_Failed:  CAN failed entering the specific mode 4 {, M( S& ~5 X% ~  j
  8.   *         - CAN_ModeStatus_Success: CAN Succeed entering the specific mode
    3 K4 f; O/ M& F& r
  9.   */
    , t7 ^2 x3 I5 J  n/ b
  10. uint8_t CAN_OperatingModeRequest(CAN_TypeDef* CANx, uint8_t CAN_OperatingMode);
复制代码
CAN_operating_mode如下定义:
7 J  P5 Z9 ?, U
  1. [cpp] view plain copy; V5 g9 z( G/ `( _# n& e" ~
  2. /** * u2 \; @& \/ L9 j4 y' M
  3.   * @defgroup CAN_operating_mode 9 @$ g& x, G1 {1 l% w, _
  4.   * @{
    7 E0 P& b+ B8 K
  5.   */
      \8 {' E+ _/ e8 G" x" \
  6. #define CAN_OperatingMode_Initialization  ((uint8_t)0x00) /*!< Initialization mode */
    - O$ m# a2 @/ N- U0 n+ m1 Q: I
  7. #define CAN_OperatingMode_Normal          ((uint8_t)0x01) /*!< Normal mode */
    + E8 U# d; D& C. c  h& [) r+ b
  8. #define CAN_OperatingMode_Sleep           ((uint8_t)0x02) /*!< sleep mode */
    $ y3 `9 o. ?, v  ]7 @$ v8 p* g
复制代码

; Q5 o" ^' E1 N; o6 `- p4 ]5 l) d4 如何设置测试模式9 G: w- u& @' w+ ~
  1. [cpp] view plain copy
    4 P+ M* \. p# h0 G- P- t3 g
  2. /** @defgroup CAN_operating_mode # [! ^% \9 p- u3 q
  3.   * @{
    & H9 P! j0 q$ T3 h* J. W2 s
  4.   */ * b' ^6 S# s/ Q; V5 D2 z
  5. #define CAN_Mode_Normal             ((uint8_t)0x00)  /*!< normal mode */ 3 z8 U0 u, y8 |5 w# N
  6. #define CAN_Mode_LoopBack           ((uint8_t)0x01)  /*!< loopback mode */
    5 u  K1 F  y( W. J
  7. #define CAN_Mode_Silent             ((uint8_t)0x02)  /*!< silent mode */
    % N+ J/ M1 m! U; i  H: t
  8. #define CAN_Mode_Silent_LoopBack    ((uint8_t)0x03)  /*!< loopback combined with silent mode */
复制代码
在CAN初始化函数接口CAN_Init调用时,使用CAN_TypeDef类型的CAN_Mode定义了CAN的测试模式,其值如上所定义。如下所示:
; M0 q: C" Q3 N3 D
  1. [cpp] view plain copy3 A4 L  |$ |% Z
  2. CAN_DeInit(CAN1);
    ( h" X" V& w7 }. _- c- ^
  3. CAN-StructInit(&CAN_InitStructure); 3 D" f. _) S, b7 w+ Y! p
  4. //... + ^0 b7 k0 O6 d6 f
  5. CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;//正常模式,或者设置为测试模式 - P, r2 x3 S$ t# C" e
  6. //...
    " R0 P4 a! f/ J4 P
  7. if (CAN_Init(CAN1,&CAN_InitStructure) == CANINITFAILED) ! }& q  N: }2 f
  8. { 2 K' Z' y* R9 ]1 |
  9.     //...
    ; {* U1 A) H" X4 @
  10. }
    % R' Z' q4 l* M! j
  11. //...
复制代码

5 Z, v3 s; @5 ~9 C) A: p5 控制和状态寄存器
9 v. \6 N1 n8 z; t5.1 CAN主控制寄存器 (CAN_MCR)2 o$ ^6 |3 Z/ n& V6 E
地址偏移量: 0x00
" O7 R, H; }- p/ D+ w; J复位值: 0x0001 00029 }  S! Z9 R& P
8 Q7 H+ M5 N! E0 \* Z5 S
4.jpg
                                                                                                     图41 I9 H$ p6 X- ~* Q9 F0 p, `

6 n+ j- g% e* J- x# T6 ]: v$ W位31:16        保留,硬件强制为0。
: K0 u$ _$ j2 x% N& l8 t0 C: x位15        RESET: bxCAN 软件复位
& B% ^7 B( {  \1 I0 K. ~8 a$ F, M' {0: 本外设正常工作;1 i9 @* U+ V+ y; c. g2 K  _
1: 对bxCAN进行强行复位,复位后bxCAN进入睡眠模式(FMP位和CAN_MCR寄存器被初始化为其复位值)。此后硬件自动对该位清0。* o/ {8 F& o6 r; J
位14:8        保留,硬件强制为0。
$ e) ^9 ^- M, @7 e位7        TTCM: 时间触发通信模式" j6 B) |# q2 x8 |
0: 禁止时间触发通信模式;
% E& B$ ?+ q/ w$ [* I$ a) s1: 允许时间触发通信模式。& J: Y* s' j, g7 O' O
注: 要想了解关于时间触发通信模式的更多信息,请参考21.4.2:时间触发通信模式。. f6 U* \6 R) J- R5 v
位6        ABOM: 自动离线(Bus-Off)管理8 N  @' J# l. r* T9 y
该位决定CAN硬件在什么条件下可以退出离线状态。
% Q# O+ d1 _- P" _5 {* I# D0: 离线状态的退出是在,软件对CAN_MCR寄存器的INRQ位进行置1随后清0后,一旦硬件检测到128次11位连续的隐性位,就退出离线状态;
' O! Q1 T/ E, o8 z1: 一旦硬件检测到128次11位连续的隐性位,自动退出离线状态。
5 m! c& |" p, z6 b9 \* V1 s5 c位5        AWUM: 自动唤醒模式5 ?" r9 J, O7 \4 K) E3 c( G
该位决定CAN处在睡眠模式时由硬件还是软件唤醒
1 _( n. F, ^) l1 _- E4 k0: 睡眠模式通过清除CAN_MCR寄存器的SLEEP位,由软件唤醒;
$ w+ w% S: b2 k. [( i1: 睡眠模式通过检测CAN报文,由硬件自动唤醒。唤醒的同时,硬件自动对CAN_MSR寄存器的SLEEP和SLAK位清0 。
8 |3 A7 K" F7 N  E8 s! J3 ?, c* J位4        NART: 禁止报文自动重传
( W- x1 x* {9 W( {) k0: 按照CAN标准,CAN硬件在发送报文失败时会一直自动重传直到发送成功;
/ i1 C7 [; e: K! A# J$ R$ k/ s1: CAN报文只被发送1次,不管发送的结果如何(成功、出错或仲裁丢失)。
' s; s' x# A9 ?. [位3        RFLM: 接收FIFO锁定模式* X7 b7 ~4 e; Y0 w
0: 在接收溢出时FIFO未被锁定,当接收FIFO的报文未被读出,下一个收到的报文会覆盖原有的报文;8 p, L& T) U8 g4 h
1: 在接收溢出时FIFO被锁定,当接收FIFO的报文未被读出,下一个收到的报文会被丢弃。2 B+ d" N, O& ?. s& R
位2        TXFP: 发送FIFO优先级1 q& u5 c  U& a+ C' X
当有多个报文同时在等待发送时,该位决定这些报文的发送顺序
& m/ ~+ j; d" y* H  X6 H0: 优先级由报文的标识符来决定;
& X: v- e, r5 g# J9 `1: 优先级由发送请求的顺序来决定。
- v2 c' f' x4 l' M; f3 b位1        SLEEP: 睡眠模式请求
+ h6 a: [5 Q3 w: s软件对该位置1可以请求CAN进入睡眠模式,一旦当前的CAN活动(发送或接收报文)结束,CAN就进入睡眠。9 V3 g! ~  b* l8 i) _! c5 Q* W  W
软件对该位清0使CAN退出睡眠模式。
" o8 @) B$ Y. A! t: s: b9 n$ w当设置了AWUM位且在CAN Rx信号中检测出SOF位时,硬件对该位清0。
, T( N9 f3 I- [* K" U在复位后该位被置1-CAN在复位后处于睡眠模式。
# n( y& Y; p- y- G9 @位0        INRQ: 初始化请求4 s5 o, [. |8 L1 B- ]$ l- Y/ c/ ^
软件对该位清0可使CAN从初始化模式进入正常工作模式:当CAN在接收引脚检测到连续的11个隐性位后,CAN就达到同步,并为接收和发送数据作好准备了。为此,硬件相应地对CAN_MSR寄存器的INAK位清0。! f. w; ], F( d. e% w$ z. `8 c6 [
软件对该位置1可使CAN从正常工作模式进入初始化模式:一旦当前的CAN活动(发送或接收)结束,CAN就进入初始化模式。相应地,硬件对CAN_MSR寄存器的INAK位置1。  Z- M  L: A" R0 \# f+ f& m

* ?& G! c( [$ E6 S5.2 CAN主状态寄存器 (CAN_MSR)
* c  q  ]: }2 n% E5 G地址偏移量: 0x04
: r5 Q4 b6 i  d复位值: 0x0000 0C02
) I5 |' P3 Y/ P; ]0 o/ G8 Q' e& X8 `: e/ Y
/ _: M9 f1 T- e5 Y
5.jpg
                                                                                                        图5
4 f2 y6 d! c+ y: J  h. y; N- H4 W
/ F4 y0 `* Y9 G  b位31:12        保留位,硬件强制为0
: Y1 U' l+ q- n位11        RX: CAN接收电平% s9 A: }. I: T. @' [
该位反映CAN接收引脚(CAN_RX)的实际电平。
+ u2 X% I0 `$ r. Y9 E% E位10        SAMP: 上次采样值
6 [5 F" A$ V0 p" @7 _* w* ECAN接收引脚的上次采样值(对应于当前接收位的值)。2 o# j" p8 S3 u
位9        RXM: 接收模式
  q& k7 J% Y" C7 A, j该位为1表示CAN当前为接收器。/ e, i' O/ S2 Z5 A% @  Q
位8        TXM: 发送模式
8 O- m/ t' ~, g9 r9 ]该位为1表示CAN当前为发送器。
/ c  V+ M% b  E  y. F* y位7:5        保留位,硬件强制为0。# O# }  w: l+ O  e
位4        SLAKI: 睡眠确认中断. s5 W$ i. q, m0 A
当SLKIE=1, 一旦CAN进入睡眠模式硬件就对该位置1,紧接着相应的中断被触发。软件可对该位清0,当SLAK位被清0时硬件也对该位清0。( X5 \9 \: e1 B3 L7 x
注: 当SLKIE=0, 不应该查询该位,而应该查询SLAK位来获知睡眠状态。
* f0 f3 Q2 z) v5 o& a/ _( D5 P位3        WKUI: 唤醒中断挂号
6 V+ S5 E( Y% P5 d3 C# Y& y当CAN处于睡眠状态,一旦帧起始位(SOF)被检测到,硬件就对该位置1;并且如果CAN_IER寄存器的WKUIE位为1,则相应的中断被触发。/ z7 h4 l" X* F" N% z/ ]
该位由软件清0。! A% a: ]( p5 o$ ^* Y+ a
位2        ERRI: 出错中断挂号
# {: F1 y; j* a0 T当由于检测到出错而对CAN_ESR 寄存器的某位置1,并且CAN_IER 寄存器的相应中断使能位也被置1时,硬件对该位置1;并且如果CAN_IER寄存器的ERRIE位为1则错误中断被触发。! E6 ^2 s( T; s& U
该位由软件清0。3 j* {% {: j5 j  ~, @  \
位1        SLAK: 睡眠模式确认9 F7 a1 x( p& [, F8 a5 L* s
当CAN进入睡眠模式时硬件就对该位置1,从而供软件进行状态查询。 该位是对软件请求进入睡眠模式的确认(对CAN_MCR寄存器的SLEEP位置1)。当CAN退出睡眠模式时硬件对该位清0 (需要跟CAN总线同步)。 这里跟CAN总线同步是指,硬件需要在CAN的RX引脚上检测到连续的11位隐性位。
6 t$ h0 G7 n& ~7 `! B& t7 }注: 通过软件或硬件对CAN_MCR 的SLEEP位清0,是开启退出睡眠模式过程的唯一途径。有关清除SLEEP位的详细信息,参见CAN_MCR寄存器的AWUM位的描述。& ~9 Q9 ~+ w. a) W  _
位0        INAK: 初始化确认
' ?& d) J+ d5 H- D/ e  e  ?$ e  Y当CAN进入初始化模式时硬件就对该位置1,从而供软件进行状态查询。 该位是对软件请求进入初始化模式的确认(对CAN_MCR寄存器的INRQ位置1)。$ f! F2 C3 x+ M2 r2 {: Z% ~
当CAN退出初始化模式时硬件对该位清0 (需要跟CAN总线同步)。这里跟CAN总线同步是指,硬件需要在CAN的RX引脚上检测到连续的11位隐性位。8 P! E; l- W/ H/ A6 R: l7 w3 l

8 x  O8 q) _/ z# e$ v# _
2 B* w, T7 j& o+ D% n" \* w" {+ V! P0 a+ v' h; e, ?; v
) t2 t6 U2 B( K, V# {
转载自flydream0! W6 q( ^9 K. m( Y5 N

% K( Q% Q7 R( {0 w$ B0 \7 v% u6 `: W

# L- z: N/ }& F9 b/ U8 R& Y
收藏 2 评论0 发布时间:2018-5-28 14:50

举报

0个回答

所属标签

相似分享

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