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

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

[复制链接]
aimejia 发布时间:2018-5-28 14:50
本帖最后由 aimejia 于 2018-5-28 14:54 编辑
  ~& U, W, U- ]& Q/ W/ V( k+ s3 s/ N3 \% i
1 bxCAN工作模式% N7 y: v; ], [4 s# M5 G
bxCAN有3个主要的工作模式:初始化模式、正常模式和睡眠模式。! ]3 P. H& y- ?! d' r3 `% t
+ }. g) S* @* T6 l3 N% Y! c
在硬件复位后,bxCAN工作在睡眠模式以节省电能,同时CANTX引脚的内部上拉电阻被激活。软件通过对CAN_MCR寄存器的INRQ或SLEEP位置’1’,可以请求bxCAN进入初始化或睡眠模式。一旦进入了初始化或睡眠模式,bxCAN就对CAN_MSR寄存器的INAK或SLAK位置’1’来进行确认,同时内部上拉电阻被禁用。; w% Z. y  T3 I' |3 K
2 w4 @# j& J& H" v: z7 X# h3 @
当INAK和SLAK位都为’0’时,bxCAN就处于正常模式。在进入正常模式前,bxCAN必须跟CAN总线取得同步;为取得同步,bxCAN要等待CAN总线达到空闲状态,即在CANRX引脚上监测到11个连续的隐性位。
5 M1 j1 |; u: F5 N! D: i# I8 I( H- w; C' a  N
1.1 初始化模式软件初始化应该在硬件处于初始化模式时进行。设置CAN_MCR寄存器的INRQ位为’1’,请求bxCAN进入初始化模式,然后等待硬件对CAN_MSR寄存器的INAK位置’1’来进行确认。& x& N" S9 {, s1 Y0 F' c
    ) c' U" r; N* @# G& K! u9 ^/ k8 U' t
清除CAN_MCR寄存器的INRQ位为’0’,请求bxCAN退出初始化模式,当硬件对CAN_MSR寄存器的INAK位清’0’就确认了初始化模式的退出。
5 p" n  F6 j- e: E! u    , K% v' a5 v) X
当bxCAN处于初始化模式时,禁止报文的接收和发送,并且CANTX引脚输出隐性位(高电平)。初始化模式的进入,不会改变配置寄存器。
0 i" c0 ?2 c- h4 O8 `0 b2 p" L* T2 ~/ R3 E3 G7 y8 h
软件对bxCAN的初始化,至少包括位时间特性(CAN_BTR)和控制(CAN_MCR)这2个寄存器。: i. ]5 p0 F0 G. m9 [
在对bxCAN的过滤器组(模式、位宽、FIFO关联、激活和过滤器值)进行初始化前,软件要对CAN_FMR寄存器的FINIT位设置’1’。对过滤器的初始化可以在非初始化模式下进行。# C% c/ H) t6 Z" w2 k8 Q# a

/ x8 z$ K! N* s  x* @! A' H* H注: 当FINIT=1时,报文的接收被禁止。可以先对过滤器激活位清’0’(在CAN_FA1R中),然后修改相应过滤器的值。如果过滤器组没有使用,那么就应该让它处于非激活状态(保持其FACT位为清’0’状态)。
& h$ K& x1 k! a* K9 v( k5 J1 W& a# P8 K+ H
1.2 正常模式
# ^" L6 e7 p) r4 Y0 o1 s9 [在初始化完成后,软件应该让硬件进入正常模式,以便正常接收和发送报文。软件可以通过对CAN_MCR寄存器的INRQ位清’0’,来请求从初始化模式进入正常模式,然后要等待硬件对CAN_MSR寄存器的INAK位置’1’的确认。在跟CAN总线取得同步,即在CANRX引脚上监测到11个连续的隐性位(等效于总线空闲)后,bxCAN才能正常接收和发送报文。
5 b1 E  Q4 L9 j! G$ W7 D7 r1 S& g. @3 S
不需要在初始化模式下进行过滤器初值的设置,但必须在它处在非激活状态下完成(相应的FACT位为0)。而过滤器的位宽和模式的设置,则必须在初始化模式中进入正常模式前完成。
8 s0 d. Y5 z" [7 B/ P$ u  x% y7 R% O& h- P
1.3 睡眠模式(低功耗)
9 C6 B8 x7 h8 E9 s% QbxCAN可工作在低功耗的睡眠模式。软件通过对CAN_MCR寄存器的SLEEP位置’1’,来请求进入这一模式。在该模式下,bxCAN的时钟停止了,但软件仍然可以访问邮箱寄存器。
) F( x) l* w0 j7 h1 o/ R
, i* q( X' @5 m当bxCAN处于睡眠模式,软件必须对CAN_MCR寄存器的INRQ位置’1’并且同时对SLEEP位清’0’,才能进入初始化模式。5 O2 C% a2 ]. R8 G1 g- @
有2种方式可以唤醒(退出睡眠模式)bxCAN:通过软件对SLEEP位清’1’,或硬件检测到CAN总线的活动。
. u9 O, N6 B5 D- x3 a! ^1 [! e1 V5 |! i4 t; n: `% Z4 q( y/ t
如果CAN_MCR寄存器的AWUM位为’1’,一旦检测到CAN总线的活动,硬件就自动对SLEEP位清’0’来唤醒bxCAN。如果CAN_MCR寄存器的AWUM位为’0’,软件必须在唤醒中断里对SLEEP位清’0’才能退出睡眠状态。! N# u) Z5 x' |. j& \

0 F+ m  t$ ^8 g1 ~  U8 G注: 如果唤醒中断被允许(CAN_IER寄存器的WKUIE位为’1’),那么一旦检测到CAN总线活动就会产生唤醒中断,而不管硬件是否会自动唤醒bxCAN。) p; i  U: c3 C) |* P9 Q2 f
在对SLEEP位清’0’后,睡眠模式的退出必须与CAN总线同步,当硬件对SLAK位清’0’时,就确认了睡眠模式的退出。1 O4 f2 \' n) b( N8 X0 w- m: s4 y
( m5 ]3 P$ ?+ z! E! Z1 r- P
2 测试模式3 Q' Q$ ~$ l0 x' g. X6 n
通过对CAN_BTR寄存器的SILM和/或LBKM位置’1’,来选择一种测试模式。只能在初始化模式下,修改这2位。在选择了一种测试模式后,软件需要对CAN_MCR寄存器的INRQ位清’0’,来真正进入测试模式。
3 Y& @6 u& q4 u: ^3 d; O+ P: [1 c; p
8 r- [1 m, U$ ~1 v2.1 静默模式
6 E& @+ S3 }' ]6 c: y. R通过对CAN_BTR寄存器的SILM位置’1’,来选择静默模式。* U; p% j1 ~+ O$ V( e

' `( ~2 ]' c1 @( S1 b) r1 z在静默模式下,bxCAN可以正常地接收数据帧和远程帧,但只能发出隐性位,而不能真正发送报文。如果bxCAN需要发出显性位(确认位、过载标志、主动错误标志),那么这样的显性位在内部被接回来从而可以被CAN内核检测到,同时CAN总线不会受到影响而仍然维持在隐性位状态。因此,静默模式通常用于分析CAN总线的活动,而不会对总线造成影响-显性位(确认位、错误帧)不会真正发送到总线上。4 c( w" o' Y6 @& A. r

) g0 h) H- Z$ c. e) s
1.jpg
                                                                              图1                                                                                   
2.2 环回模式# ?4 G* ^* R. b( T1 G: `  @
通过对CAN_BTR寄存器的LBKM位置’1’,来选择环回模式。在环回模式下,bxCAN把发送的报文当作接收的报文并保存(如果可以通过接收过滤)在接收邮箱里。# a* |, {, G2 X( n2 I* C4 U
0 \/ U( ?2 C- ^' k. w* o
2.jpg
                                                                                                        图2" _  P; z) }/ v; K! z) q3 j

1 q/ S! i# n6 W' }' |/ v! F8 Z% q环回模式可用于自测试。为了避免外部的影响,在环回模式下CAN内核忽略确认错误(在数据/远程帧的确认位时刻,不检测是否有显性位)。在环回模式下,bxCAN在内部把Tx输出回馈到Rx输入上,而完全忽略CANRX引脚的实际状态。发送的报文可以在CANTX引脚上检测到。% N8 ?2 H" i7 J; J  h# N  t

6 f9 e- U# P9 N+ c$ C- e2.3 环回静默模式
$ i; `9 n" p" S  |通过对CAN_BTR寄存器的LBKM和SILM位同时置’1’,可以选择环回静默模式。该模式可用于“热自测试”,即可以象环回模式那样测试bxCAN,但却不会影响CANTX和CANRX所连接的整个CAN系统。在环回静默模式下,CANRX引脚与CAN总线断开,同时CANTX引脚被驱动到隐性位状态。
- b8 f4 u$ O6 n
1 |+ x) ~5 ~# W* o) j4 r
3.jpg
                                                                                                        图3
7 C# Z2 y- @! l0 L9 w! T! n' U4 H
3 g' x/ T' w: r+ z7 K, Q3 如何设置工作模式
9 `8 k4 [# m8 G" ~. I- C4 ~8 K固件接口如下:
# d7 H! Z* }" S/ ~: [" h0 b
  1. [cpp] view plain copy
    - ]4 \! ^2 E$ Q% F5 z3 y
  2. /** ( n5 G) D& R: b& y. e
  3.   * @brief  Selects the CAN Operation mode.
    ) Z8 K: E% @9 q4 L
  4.   * @param  CAN_OperatingMode: CAN Operating Mode.
    ' o8 P2 O# A) P1 j3 g# b
  5.   *         This parameter can be one of @ref CAN_OperatingMode_TypeDef enumeration. 0 m3 w' S8 D/ G4 H3 Z
  6.   * @retval status of the requested mode which can be 9 b+ s3 n( Z$ Y) O* K" Y- L" p
  7.   *         - CAN_ModeStatus_Failed:  CAN failed entering the specific mode ( Y. }7 I" G$ d) z8 c/ w
  8.   *         - CAN_ModeStatus_Success: CAN Succeed entering the specific mode ) `+ ~$ h9 A1 k
  9.   */
    + Y# N6 ~3 ^! w3 q1 Y- h
  10. uint8_t CAN_OperatingModeRequest(CAN_TypeDef* CANx, uint8_t CAN_OperatingMode);
复制代码
CAN_operating_mode如下定义:2 u- j/ L6 ]+ f& t! \9 _
  1. [cpp] view plain copy9 \4 h* X, A) ^
  2. /** 1 t  W2 q7 `9 x* C% c
  3.   * @defgroup CAN_operating_mode . n7 D" o: a3 I: A3 [: W6 g2 A
  4.   * @{ / o* O4 Z, J2 z; j  P
  5.   */
    + ~. c3 o9 h# r6 E6 F# p
  6. #define CAN_OperatingMode_Initialization  ((uint8_t)0x00) /*!< Initialization mode */ 4 S4 e- A5 @) B: G
  7. #define CAN_OperatingMode_Normal          ((uint8_t)0x01) /*!< Normal mode */
    ; S1 E! O: ^1 h+ s! r( `
  8. #define CAN_OperatingMode_Sleep           ((uint8_t)0x02) /*!< sleep mode */ # g$ r0 V3 L: \: H4 F* v& \7 B
复制代码

, l5 @7 {' X4 O$ K" z$ S4 如何设置测试模式' k  J  X/ X7 X4 H$ m( @2 M9 r; D
  1. [cpp] view plain copy4 z2 d) S% m" ?7 K. l* m
  2. /** @defgroup CAN_operating_mode : U3 |3 P6 e  P, Z
  3.   * @{ ; Y" p: }2 J0 c) f! r. R  H
  4.   */ 1 t/ x; z: P" C& H
  5. #define CAN_Mode_Normal             ((uint8_t)0x00)  /*!< normal mode */ . \* W" ~8 e3 }0 G: t
  6. #define CAN_Mode_LoopBack           ((uint8_t)0x01)  /*!< loopback mode */
    * K1 O2 G7 |7 b, _3 W
  7. #define CAN_Mode_Silent             ((uint8_t)0x02)  /*!< silent mode */
    & s; D4 n; `0 K5 l
  8. #define CAN_Mode_Silent_LoopBack    ((uint8_t)0x03)  /*!< loopback combined with silent mode */
复制代码
在CAN初始化函数接口CAN_Init调用时,使用CAN_TypeDef类型的CAN_Mode定义了CAN的测试模式,其值如上所定义。如下所示:
! g  o" N7 a* `( Q9 c+ M' O
  1. [cpp] view plain copy" C8 O8 s! P! V/ h2 Y( @+ [
  2. CAN_DeInit(CAN1); % R7 V3 V; W2 x$ I# l% H, t
  3. CAN-StructInit(&CAN_InitStructure);
    / {/ L  P" {9 Y- i) g
  4. //...
    4 m3 f: l/ D$ s% Q- S
  5. CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;//正常模式,或者设置为测试模式 : d6 a& i; Y1 K' i3 s
  6. //... 8 E6 r/ H- `  x6 i2 |
  7. if (CAN_Init(CAN1,&CAN_InitStructure) == CANINITFAILED) / r9 H& o) ^( ?: |3 U
  8. { . g6 S) o1 l' ?' g+ ~; B& t* ]
  9.     //...
    ; C" ?4 u9 Q6 i3 o* D8 _6 j- s
  10. } # V' l6 }8 H* w( Z
  11. //...
复制代码

# q+ h) M& m! y7 H# h* o& |5 控制和状态寄存器/ n6 D/ w2 p* s: Y! S, [
5.1 CAN主控制寄存器 (CAN_MCR). J1 H3 e7 P+ A6 Y
地址偏移量: 0x00
. S' P/ e! k* m4 d! z复位值: 0x0001 0002$ {& H( D3 t  U8 `& u
. w* B7 n2 }5 u0 H7 C6 I
4.jpg
                                                                                                     图4
) M7 l2 B3 v* g: w' `5 M; t6 i6 B6 Z" `( d3 D$ M: n  w- |2 H
位31:16        保留,硬件强制为0。
9 K  D7 Q( }, P0 d* H, T位15        RESET: bxCAN 软件复位
" d4 l2 D1 w2 M  f2 B2 `0 U1 @& c7 F0: 本外设正常工作;7 b3 c; b2 y7 s' Q' l1 S6 @" Q
1: 对bxCAN进行强行复位,复位后bxCAN进入睡眠模式(FMP位和CAN_MCR寄存器被初始化为其复位值)。此后硬件自动对该位清0。. T# l8 v, t% h' _0 k, x6 {
位14:8        保留,硬件强制为0。/ J8 v; ^( Z5 X& t7 Z' m8 z, V# _0 @
位7        TTCM: 时间触发通信模式
8 F0 \7 }; m, y/ k9 \% Z0: 禁止时间触发通信模式;
: P5 E$ W% ^6 F7 {1: 允许时间触发通信模式。
# c% h. L* ?* ^, l0 m( {3 s注: 要想了解关于时间触发通信模式的更多信息,请参考21.4.2:时间触发通信模式。
/ d0 v0 a9 z0 L! r7 [1 w位6        ABOM: 自动离线(Bus-Off)管理8 u' S! I" o* S
该位决定CAN硬件在什么条件下可以退出离线状态。
) H! x4 w8 E- K1 n/ W  P. x0: 离线状态的退出是在,软件对CAN_MCR寄存器的INRQ位进行置1随后清0后,一旦硬件检测到128次11位连续的隐性位,就退出离线状态;
* V4 {- D6 Y, X1: 一旦硬件检测到128次11位连续的隐性位,自动退出离线状态。+ `" C( l& \  k( `
位5        AWUM: 自动唤醒模式
# A& }' ?' `/ U该位决定CAN处在睡眠模式时由硬件还是软件唤醒( ]' R2 t, u% V. T/ ]2 L
0: 睡眠模式通过清除CAN_MCR寄存器的SLEEP位,由软件唤醒;( A. G# b! f& n( b# L( T
1: 睡眠模式通过检测CAN报文,由硬件自动唤醒。唤醒的同时,硬件自动对CAN_MSR寄存器的SLEEP和SLAK位清0 。# o+ h& W! `9 D+ E
位4        NART: 禁止报文自动重传
" n: X# s* w& n0: 按照CAN标准,CAN硬件在发送报文失败时会一直自动重传直到发送成功;/ E/ |$ Z/ R; J. Z
1: CAN报文只被发送1次,不管发送的结果如何(成功、出错或仲裁丢失)。
- n  A, J' C2 s) H# A* J( c0 p7 A位3        RFLM: 接收FIFO锁定模式
5 \& Q, T$ N5 J* |; x$ Y0: 在接收溢出时FIFO未被锁定,当接收FIFO的报文未被读出,下一个收到的报文会覆盖原有的报文;
! L9 |# [0 l3 k% a1: 在接收溢出时FIFO被锁定,当接收FIFO的报文未被读出,下一个收到的报文会被丢弃。1 n( q# P: g) i% p
位2        TXFP: 发送FIFO优先级
# E$ i. W* U4 K% `4 q6 B5 i当有多个报文同时在等待发送时,该位决定这些报文的发送顺序! j( N( W% }$ |' p# f
0: 优先级由报文的标识符来决定;
  h$ P  H; w6 ^* R1: 优先级由发送请求的顺序来决定。2 c6 x9 J3 O! F4 s( a
位1        SLEEP: 睡眠模式请求
7 I+ m$ Y( @+ R# n) m软件对该位置1可以请求CAN进入睡眠模式,一旦当前的CAN活动(发送或接收报文)结束,CAN就进入睡眠。
' ~& T' U6 t6 U; T. y. j) P% ^软件对该位清0使CAN退出睡眠模式。
) ?& x; g3 ~' l当设置了AWUM位且在CAN Rx信号中检测出SOF位时,硬件对该位清0。
1 O+ _0 [# Q5 s! h# e在复位后该位被置1-CAN在复位后处于睡眠模式。: o7 d8 t  F& A" Y7 ~! \) K8 x
位0        INRQ: 初始化请求
' M8 L5 ~. M3 N软件对该位清0可使CAN从初始化模式进入正常工作模式:当CAN在接收引脚检测到连续的11个隐性位后,CAN就达到同步,并为接收和发送数据作好准备了。为此,硬件相应地对CAN_MSR寄存器的INAK位清0。
3 X, Y7 e9 Y+ M软件对该位置1可使CAN从正常工作模式进入初始化模式:一旦当前的CAN活动(发送或接收)结束,CAN就进入初始化模式。相应地,硬件对CAN_MSR寄存器的INAK位置1。
5 O8 d2 t4 f' I5 t( J8 U8 r, I& O+ o" N+ M; c" n( ^" i; \5 i
5.2 CAN主状态寄存器 (CAN_MSR)
# r+ ?) P- v$ T9 t! G; ]地址偏移量: 0x04
* a" f% F" e) e9 R/ |) b% t( `复位值: 0x0000 0C02
- i* t4 F% U5 k2 {/ }3 X1 g6 C. h6 U
. B! `, ~$ z6 M8 w+ Q
5.jpg
                                                                                                        图5: l; C  k3 z! `* C! R; V
7 Z0 M( B9 t4 v/ ?" _: d
位31:12        保留位,硬件强制为0* I4 R! _1 `" ~. v
位11        RX: CAN接收电平
$ c, |0 }7 X+ P( Q0 ^该位反映CAN接收引脚(CAN_RX)的实际电平。* I, X9 [. B! l- l
位10        SAMP: 上次采样值0 m7 T  _* ?: l
CAN接收引脚的上次采样值(对应于当前接收位的值)。
2 }2 l- A; m5 t! I位9        RXM: 接收模式
% o( b/ b7 J- n' e3 L0 g该位为1表示CAN当前为接收器。8 ~( Z9 k/ z! ?% Z$ @
位8        TXM: 发送模式- _' z4 K& S# N& ^' _6 G
该位为1表示CAN当前为发送器。
- e$ C; \* h8 R0 [位7:5        保留位,硬件强制为0。
+ o* v8 R' r, W5 s位4        SLAKI: 睡眠确认中断8 P/ g) q- M" J% T
当SLKIE=1, 一旦CAN进入睡眠模式硬件就对该位置1,紧接着相应的中断被触发。软件可对该位清0,当SLAK位被清0时硬件也对该位清0。! m. P! N! ^6 k: T0 s, {6 _& H
注: 当SLKIE=0, 不应该查询该位,而应该查询SLAK位来获知睡眠状态。
! S6 w) {3 D3 Z" g0 K& b0 e' B, ~位3        WKUI: 唤醒中断挂号
% {- W- A( ]; i' s$ h, W当CAN处于睡眠状态,一旦帧起始位(SOF)被检测到,硬件就对该位置1;并且如果CAN_IER寄存器的WKUIE位为1,则相应的中断被触发。
3 w# }/ P* D( n) Q, x, j该位由软件清0。! Y6 g; v/ H* L
位2        ERRI: 出错中断挂号
) f4 F( `; T3 K/ c9 s' |当由于检测到出错而对CAN_ESR 寄存器的某位置1,并且CAN_IER 寄存器的相应中断使能位也被置1时,硬件对该位置1;并且如果CAN_IER寄存器的ERRIE位为1则错误中断被触发。
5 h" V- M  |2 x: }9 Z; i该位由软件清0。
' F4 D# z+ l: W" k, r位1        SLAK: 睡眠模式确认
7 f8 z& E, R% h* Q. r- k当CAN进入睡眠模式时硬件就对该位置1,从而供软件进行状态查询。 该位是对软件请求进入睡眠模式的确认(对CAN_MCR寄存器的SLEEP位置1)。当CAN退出睡眠模式时硬件对该位清0 (需要跟CAN总线同步)。 这里跟CAN总线同步是指,硬件需要在CAN的RX引脚上检测到连续的11位隐性位。
* p5 _5 p1 v5 ?6 T1 T( M注: 通过软件或硬件对CAN_MCR 的SLEEP位清0,是开启退出睡眠模式过程的唯一途径。有关清除SLEEP位的详细信息,参见CAN_MCR寄存器的AWUM位的描述。
8 c$ o. ~6 y- m1 N2 s: E* ^6 H位0        INAK: 初始化确认& v2 P& f  l3 L* x' J3 g
当CAN进入初始化模式时硬件就对该位置1,从而供软件进行状态查询。 该位是对软件请求进入初始化模式的确认(对CAN_MCR寄存器的INRQ位置1)。0 Z9 ~& N( t2 K6 G  [
当CAN退出初始化模式时硬件对该位清0 (需要跟CAN总线同步)。这里跟CAN总线同步是指,硬件需要在CAN的RX引脚上检测到连续的11位隐性位。, o2 [" k) Z! @/ D1 Y8 Y) j. h
, x. }# @2 N9 E# x8 _8 o

( r) y8 I/ I. o5 H
5 x0 J' E% t3 J; h2 l: P; K. s3 o$ c9 v" a+ w8 n2 @
转载自flydream0
& C3 m3 N; j, R
8 c% @, z) z" i( c9 T; s2 I% r( T9 a/ {8 o4 Y9 D
, X+ O1 G$ J, _  D# H
收藏 2 评论0 发布时间:2018-5-28 14:50

举报

0个回答

所属标签

相似分享

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