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

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

[复制链接]
aimejia 发布时间:2018-5-28 14:50
本帖最后由 aimejia 于 2018-5-28 14:54 编辑
! f& O+ ?# S$ X. F4 `  B
' v, m8 J. {" Q7 n1 bxCAN工作模式6 Z9 t) x" K7 d
bxCAN有3个主要的工作模式:初始化模式、正常模式和睡眠模式。7 l" Y& z$ m& k( `: f% R; m: j
! l* H5 g! J* K: Z) O$ ^
在硬件复位后,bxCAN工作在睡眠模式以节省电能,同时CANTX引脚的内部上拉电阻被激活。软件通过对CAN_MCR寄存器的INRQ或SLEEP位置’1’,可以请求bxCAN进入初始化或睡眠模式。一旦进入了初始化或睡眠模式,bxCAN就对CAN_MSR寄存器的INAK或SLAK位置’1’来进行确认,同时内部上拉电阻被禁用。
8 [4 S  I; z$ `( \% Q
/ |2 V, s1 j! u9 \当INAK和SLAK位都为’0’时,bxCAN就处于正常模式。在进入正常模式前,bxCAN必须跟CAN总线取得同步;为取得同步,bxCAN要等待CAN总线达到空闲状态,即在CANRX引脚上监测到11个连续的隐性位。
4 v& {+ M. I# V+ r& f$ ~  j& T5 q4 M7 T4 }0 d. t# p/ T. _
1.1 初始化模式软件初始化应该在硬件处于初始化模式时进行。设置CAN_MCR寄存器的INRQ位为’1’,请求bxCAN进入初始化模式,然后等待硬件对CAN_MSR寄存器的INAK位置’1’来进行确认。. {: M+ |# O6 s' }8 L1 Z
    ( i5 B1 g3 C( ~' m; ]/ E  N
清除CAN_MCR寄存器的INRQ位为’0’,请求bxCAN退出初始化模式,当硬件对CAN_MSR寄存器的INAK位清’0’就确认了初始化模式的退出。
% K) l' }; z! U9 G$ }    / K: Z# A; s" N, ?. N' C/ j9 [" T5 {
当bxCAN处于初始化模式时,禁止报文的接收和发送,并且CANTX引脚输出隐性位(高电平)。初始化模式的进入,不会改变配置寄存器。
1 ]" l  G8 o# X2 i: p0 N; T% k" N5 D( _) L3 {
软件对bxCAN的初始化,至少包括位时间特性(CAN_BTR)和控制(CAN_MCR)这2个寄存器。
8 P1 @4 Z# Z' M1 Y! }& H& G% f在对bxCAN的过滤器组(模式、位宽、FIFO关联、激活和过滤器值)进行初始化前,软件要对CAN_FMR寄存器的FINIT位设置’1’。对过滤器的初始化可以在非初始化模式下进行。1 Q9 {% h: D- z5 b$ K
" H6 x6 i/ ^6 W) M3 I3 S( B
注: 当FINIT=1时,报文的接收被禁止。可以先对过滤器激活位清’0’(在CAN_FA1R中),然后修改相应过滤器的值。如果过滤器组没有使用,那么就应该让它处于非激活状态(保持其FACT位为清’0’状态)。
# ^1 E$ j  r# o" {! B( ~1 Y" ?7 j3 j; [8 ]4 W- c
1.2 正常模式+ C, h' T( }) R/ O7 o& k5 K
在初始化完成后,软件应该让硬件进入正常模式,以便正常接收和发送报文。软件可以通过对CAN_MCR寄存器的INRQ位清’0’,来请求从初始化模式进入正常模式,然后要等待硬件对CAN_MSR寄存器的INAK位置’1’的确认。在跟CAN总线取得同步,即在CANRX引脚上监测到11个连续的隐性位(等效于总线空闲)后,bxCAN才能正常接收和发送报文。( A2 y3 w) X8 K( R
2 X6 r9 a; G( T) A& ~
不需要在初始化模式下进行过滤器初值的设置,但必须在它处在非激活状态下完成(相应的FACT位为0)。而过滤器的位宽和模式的设置,则必须在初始化模式中进入正常模式前完成。3 A- F9 R3 }, E6 J0 B- h
6 c+ o! e' f& V' p
1.3 睡眠模式(低功耗)! X) g$ \, x% e0 a- [
bxCAN可工作在低功耗的睡眠模式。软件通过对CAN_MCR寄存器的SLEEP位置’1’,来请求进入这一模式。在该模式下,bxCAN的时钟停止了,但软件仍然可以访问邮箱寄存器。: _# u/ z4 j' f0 ~0 v3 a5 R
! t+ R. h/ s. k2 s9 U, I% D
当bxCAN处于睡眠模式,软件必须对CAN_MCR寄存器的INRQ位置’1’并且同时对SLEEP位清’0’,才能进入初始化模式。
; G- {0 n; n% h6 G有2种方式可以唤醒(退出睡眠模式)bxCAN:通过软件对SLEEP位清’1’,或硬件检测到CAN总线的活动。! v: s$ s: M5 J# o& u4 j, @$ S$ O

& K/ ?# r& a, v) G' U  |如果CAN_MCR寄存器的AWUM位为’1’,一旦检测到CAN总线的活动,硬件就自动对SLEEP位清’0’来唤醒bxCAN。如果CAN_MCR寄存器的AWUM位为’0’,软件必须在唤醒中断里对SLEEP位清’0’才能退出睡眠状态。& u; M$ Q9 z2 |1 C" A6 j
1 X2 I" ?5 y1 |, ~1 Z( ^
注: 如果唤醒中断被允许(CAN_IER寄存器的WKUIE位为’1’),那么一旦检测到CAN总线活动就会产生唤醒中断,而不管硬件是否会自动唤醒bxCAN。
8 U- l4 W( L; f7 ?在对SLEEP位清’0’后,睡眠模式的退出必须与CAN总线同步,当硬件对SLAK位清’0’时,就确认了睡眠模式的退出。
) P( b+ n  b! i0 N+ [- s* ^
: x6 i* \0 ^$ h3 q3 j; W6 W. y9 |2 测试模式
# P1 P8 n# @4 U通过对CAN_BTR寄存器的SILM和/或LBKM位置’1’,来选择一种测试模式。只能在初始化模式下,修改这2位。在选择了一种测试模式后,软件需要对CAN_MCR寄存器的INRQ位清’0’,来真正进入测试模式。
4 J# A+ J' f4 W- P' x9 K! [4 I- ~% H
2.1 静默模式' ?3 o& s& h7 A! V
通过对CAN_BTR寄存器的SILM位置’1’,来选择静默模式。5 T9 H' M6 H; W! c" N& _: c

; a  k6 }; r! H* Z; w8 J7 v在静默模式下,bxCAN可以正常地接收数据帧和远程帧,但只能发出隐性位,而不能真正发送报文。如果bxCAN需要发出显性位(确认位、过载标志、主动错误标志),那么这样的显性位在内部被接回来从而可以被CAN内核检测到,同时CAN总线不会受到影响而仍然维持在隐性位状态。因此,静默模式通常用于分析CAN总线的活动,而不会对总线造成影响-显性位(确认位、错误帧)不会真正发送到总线上。
$ P- Q" K% E' _
$ n7 q9 @: M5 ]8 @% l1 a
1.jpg
                                                                              图1                                                                                   
2.2 环回模式% C$ H* |9 G) ?1 x- c
通过对CAN_BTR寄存器的LBKM位置’1’,来选择环回模式。在环回模式下,bxCAN把发送的报文当作接收的报文并保存(如果可以通过接收过滤)在接收邮箱里。' H9 E6 {6 n0 z5 _* c

) j; e% ~& ]- j% S  d" L1 Z
2.jpg
                                                                                                        图2
. J, O! r1 H, i) v% `* K* s0 V" n, f/ W
环回模式可用于自测试。为了避免外部的影响,在环回模式下CAN内核忽略确认错误(在数据/远程帧的确认位时刻,不检测是否有显性位)。在环回模式下,bxCAN在内部把Tx输出回馈到Rx输入上,而完全忽略CANRX引脚的实际状态。发送的报文可以在CANTX引脚上检测到。4 I+ O9 \8 i; W2 g8 ?
8 I* M  I6 i2 t( k% X0 v1 T+ L
2.3 环回静默模式, F. k0 S; L  [
通过对CAN_BTR寄存器的LBKM和SILM位同时置’1’,可以选择环回静默模式。该模式可用于“热自测试”,即可以象环回模式那样测试bxCAN,但却不会影响CANTX和CANRX所连接的整个CAN系统。在环回静默模式下,CANRX引脚与CAN总线断开,同时CANTX引脚被驱动到隐性位状态。
9 _, Z+ R+ M& g+ j2 I/ _
( B1 \* f3 P! d! m0 K
3.jpg
                                                                                                        图3
! ^; A3 U! I9 m+ r9 K+ ]! t" I+ [7 Y, @7 a+ r6 _8 y! W) L
3 如何设置工作模式6 _& n  t4 T8 B' B
固件接口如下:
& c* e& E& I& z2 N5 s
  1. [cpp] view plain copy/ ~# x+ v! S, z, D: W, q% N  _+ _
  2. /** 8 i  n# q% m7 g; G
  3.   * @brief  Selects the CAN Operation mode. : o) }% _. i" O9 f% \+ T
  4.   * @param  CAN_OperatingMode: CAN Operating Mode. - z) T/ d8 P5 T
  5.   *         This parameter can be one of @ref CAN_OperatingMode_TypeDef enumeration. ( l' g2 C. w) H7 r
  6.   * @retval status of the requested mode which can be
    ( N) c0 l6 e/ `
  7.   *         - CAN_ModeStatus_Failed:  CAN failed entering the specific mode ) c" v) J- m' G5 y4 X" m
  8.   *         - CAN_ModeStatus_Success: CAN Succeed entering the specific mode
    / N5 c2 t% w# b5 _) l. i6 f* Y8 u* i
  9.   */
    3 W6 E# @' f+ n% U
  10. uint8_t CAN_OperatingModeRequest(CAN_TypeDef* CANx, uint8_t CAN_OperatingMode);
复制代码
CAN_operating_mode如下定义:- r; d6 {) W  y" O" p% I# T
  1. [cpp] view plain copy
    6 _: z% m' @$ s7 p; ?- y
  2. /** ; t1 p/ U8 \- t  o- I
  3.   * @defgroup CAN_operating_mode
    # I7 d* }' e: u- Y  r8 S% V0 _9 Z
  4.   * @{ 7 p1 Q9 S; S0 F9 v1 H
  5.   */ 7 h3 j9 a+ r$ \* W! N& K
  6. #define CAN_OperatingMode_Initialization  ((uint8_t)0x00) /*!< Initialization mode */
    ( l( }) c+ v! D6 F/ i6 \+ P8 g
  7. #define CAN_OperatingMode_Normal          ((uint8_t)0x01) /*!< Normal mode */
    8 C2 Y$ m2 l& O6 `* O
  8. #define CAN_OperatingMode_Sleep           ((uint8_t)0x02) /*!< sleep mode */ ; e8 r! f6 F' s; V- L
复制代码

; `0 e& W6 K6 ~, x4 如何设置测试模式
6 k1 _& d: S  o# H
  1. [cpp] view plain copy" h5 R% x3 B; D9 K5 l# R$ G
  2. /** @defgroup CAN_operating_mode
    ( Z& t+ C) K9 a+ Y2 o  Y% n
  3.   * @{ 5 o' f2 u7 I- v9 C5 p4 v6 t
  4.   */ ) I8 n2 B+ i0 |1 N. y! H; \
  5. #define CAN_Mode_Normal             ((uint8_t)0x00)  /*!< normal mode */ / i; e' R1 M  P& P; b
  6. #define CAN_Mode_LoopBack           ((uint8_t)0x01)  /*!< loopback mode */
    8 Z8 j9 X6 S# O& T; Q
  7. #define CAN_Mode_Silent             ((uint8_t)0x02)  /*!< silent mode */ " o( {  X% M6 [1 c( u& r
  8. #define CAN_Mode_Silent_LoopBack    ((uint8_t)0x03)  /*!< loopback combined with silent mode */
复制代码
在CAN初始化函数接口CAN_Init调用时,使用CAN_TypeDef类型的CAN_Mode定义了CAN的测试模式,其值如上所定义。如下所示:9 Z$ _# g% j: d% p: J6 g7 A4 X
  1. [cpp] view plain copy
    * E  M" M& u6 G! j
  2. CAN_DeInit(CAN1); 0 @# K, _  O6 P! Q0 a
  3. CAN-StructInit(&CAN_InitStructure);
    / a$ l- ~2 g3 a4 ^: I
  4. //...
    : q- X7 i/ O$ E( O
  5. CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;//正常模式,或者设置为测试模式 ' |' g( c; [2 c. W8 @
  6. //... 6 U2 W% y# f+ g1 T
  7. if (CAN_Init(CAN1,&CAN_InitStructure) == CANINITFAILED)
    6 W4 ^/ }5 p8 @
  8. { ) a; a; K6 E8 w9 e7 V  M
  9.     //... - i$ E4 l, r- n* \. u: R& ~1 `+ y
  10. } ( |2 a$ P1 H2 d) B4 |
  11. //...
复制代码
8 |4 P9 ~8 |4 S" l3 \* a
5 控制和状态寄存器& O8 g+ y; p/ }* y
5.1 CAN主控制寄存器 (CAN_MCR). l( I/ e; e/ [8 P7 \/ [; t7 I; c. L* i5 X
地址偏移量: 0x00
: j; o) S# o9 `' M! A& }2 d6 M复位值: 0x0001 00022 q% Y' b$ X* d; T) T, b9 s3 O

$ Q7 M. b7 J, q; _1 k, g: v% L
4.jpg
                                                                                                     图4
! K( m8 ]9 K8 S8 h+ i0 w$ K& d+ q  i" k8 u0 t: o8 y# j
位31:16        保留,硬件强制为0。8 Q0 J1 Q4 i9 k
位15        RESET: bxCAN 软件复位* d7 }; C0 _, r, n/ _$ |2 T1 F
0: 本外设正常工作;0 S- G; ?7 B9 X6 Y" w* Q: n
1: 对bxCAN进行强行复位,复位后bxCAN进入睡眠模式(FMP位和CAN_MCR寄存器被初始化为其复位值)。此后硬件自动对该位清0。3 b4 j0 x$ z$ ]' T
位14:8        保留,硬件强制为0。
4 }# _+ d! X% q! p/ s" E位7        TTCM: 时间触发通信模式$ d" d9 H+ |2 |$ n& u4 c
0: 禁止时间触发通信模式;
$ Q7 Y# J% i( |; F9 J2 D1: 允许时间触发通信模式。, ^2 k; P1 h2 Z$ u
注: 要想了解关于时间触发通信模式的更多信息,请参考21.4.2:时间触发通信模式。  S4 K( O/ e8 {6 x; j, e# l
位6        ABOM: 自动离线(Bus-Off)管理
, U7 a) j3 D7 z: j8 r该位决定CAN硬件在什么条件下可以退出离线状态。
6 Q0 w# @' g; N2 S& V0: 离线状态的退出是在,软件对CAN_MCR寄存器的INRQ位进行置1随后清0后,一旦硬件检测到128次11位连续的隐性位,就退出离线状态;
+ u3 Q7 i$ V( M- ?* [5 L) T1: 一旦硬件检测到128次11位连续的隐性位,自动退出离线状态。  V/ [$ O/ q0 a% u
位5        AWUM: 自动唤醒模式4 `8 U% F+ Q& Z, A0 t; m
该位决定CAN处在睡眠模式时由硬件还是软件唤醒& I3 m! o& Z! e! K" K6 h& X' ~: h+ g
0: 睡眠模式通过清除CAN_MCR寄存器的SLEEP位,由软件唤醒;$ x1 u7 D$ `% l1 ^8 {6 i
1: 睡眠模式通过检测CAN报文,由硬件自动唤醒。唤醒的同时,硬件自动对CAN_MSR寄存器的SLEEP和SLAK位清0 。6 M2 v! \  I  ~/ x4 S6 V
位4        NART: 禁止报文自动重传
  M' }8 w6 {" c" j6 ]! K( A& J0: 按照CAN标准,CAN硬件在发送报文失败时会一直自动重传直到发送成功;* {" p8 r. X* j+ Z2 [
1: CAN报文只被发送1次,不管发送的结果如何(成功、出错或仲裁丢失)。* H! e, O7 u4 Z, L: ~* H' P% |
位3        RFLM: 接收FIFO锁定模式  s, r2 }% I2 X
0: 在接收溢出时FIFO未被锁定,当接收FIFO的报文未被读出,下一个收到的报文会覆盖原有的报文;& R! @2 I' ^, s9 A0 Y
1: 在接收溢出时FIFO被锁定,当接收FIFO的报文未被读出,下一个收到的报文会被丢弃。. V; M/ W! ~- M3 T, Y. Y5 F
位2        TXFP: 发送FIFO优先级7 L0 V, c( T* @3 e9 V0 I0 ]
当有多个报文同时在等待发送时,该位决定这些报文的发送顺序7 f6 U; ~& ]+ C7 ]+ v+ z1 W; X
0: 优先级由报文的标识符来决定;6 ^" b) H7 n8 J+ u3 m
1: 优先级由发送请求的顺序来决定。
* X2 z) f8 l) e位1        SLEEP: 睡眠模式请求
6 q7 Z# H2 d1 C) f" G: n" |软件对该位置1可以请求CAN进入睡眠模式,一旦当前的CAN活动(发送或接收报文)结束,CAN就进入睡眠。
* j( u$ s% N$ g9 j8 o/ U7 P软件对该位清0使CAN退出睡眠模式。
1 _& u$ ]' `9 I. {当设置了AWUM位且在CAN Rx信号中检测出SOF位时,硬件对该位清0。9 Q6 ~$ t2 M( J  S0 X! u- b# b' x, G
在复位后该位被置1-CAN在复位后处于睡眠模式。
3 p: P* n/ `8 L0 S6 Y# z位0        INRQ: 初始化请求" i. D" D# d$ T: S$ _1 {- H3 T
软件对该位清0可使CAN从初始化模式进入正常工作模式:当CAN在接收引脚检测到连续的11个隐性位后,CAN就达到同步,并为接收和发送数据作好准备了。为此,硬件相应地对CAN_MSR寄存器的INAK位清0。; n3 P; x/ {' y- n& P! ^; w
软件对该位置1可使CAN从正常工作模式进入初始化模式:一旦当前的CAN活动(发送或接收)结束,CAN就进入初始化模式。相应地,硬件对CAN_MSR寄存器的INAK位置1。1 r; z; _! V8 [: E" W
: e# [# V- s( ~& r0 _$ }. y( r
5.2 CAN主状态寄存器 (CAN_MSR)
0 J# _& W6 K; g9 S/ x地址偏移量: 0x04& a! D9 r  N( A( y9 Y* k
复位值: 0x0000 0C02
, j$ l2 `0 e7 @( t, t# y
- H7 x: m9 \+ A0 L; @
5.jpg
                                                                                                        图5
9 t" P! W; r% R# J7 f( i
; Q+ ~4 C, N. A/ D! c- R位31:12        保留位,硬件强制为0
. j; z; M9 F/ x' ?5 [* D& n位11        RX: CAN接收电平; d9 x& l! o$ c  ^; k5 p0 L
该位反映CAN接收引脚(CAN_RX)的实际电平。
5 h1 S/ o7 @5 O; a$ c位10        SAMP: 上次采样值
- v' q! C: u3 y7 _) p  ECAN接收引脚的上次采样值(对应于当前接收位的值)。
9 A+ `% a. M/ m0 p' X位9        RXM: 接收模式- ~6 E- c3 |7 U
该位为1表示CAN当前为接收器。
$ |5 |% U' ^+ U) I) E" p. ^位8        TXM: 发送模式& e2 S. {( O, u4 r" f: k
该位为1表示CAN当前为发送器。
$ J* F5 P6 Q- Y$ ?$ l, n位7:5        保留位,硬件强制为0。- T$ g+ B2 {5 f4 i; g
位4        SLAKI: 睡眠确认中断( {2 _" M6 E) r
当SLKIE=1, 一旦CAN进入睡眠模式硬件就对该位置1,紧接着相应的中断被触发。软件可对该位清0,当SLAK位被清0时硬件也对该位清0。( b! m  P- K8 V4 d
注: 当SLKIE=0, 不应该查询该位,而应该查询SLAK位来获知睡眠状态。( b* w* X. m( ~1 e. |
位3        WKUI: 唤醒中断挂号% ]/ |1 g0 t2 L& U
当CAN处于睡眠状态,一旦帧起始位(SOF)被检测到,硬件就对该位置1;并且如果CAN_IER寄存器的WKUIE位为1,则相应的中断被触发。, V. k" c: }- A+ L8 ?* t6 E5 P
该位由软件清0。# @: T6 D' w. P+ `- @, q
位2        ERRI: 出错中断挂号; d2 g5 S- v0 ^% _! i7 L9 K
当由于检测到出错而对CAN_ESR 寄存器的某位置1,并且CAN_IER 寄存器的相应中断使能位也被置1时,硬件对该位置1;并且如果CAN_IER寄存器的ERRIE位为1则错误中断被触发。
( m% Z- _* I9 l* v, c5 b该位由软件清0。
- n$ k: `5 w8 r( K: X2 A3 Q9 s位1        SLAK: 睡眠模式确认
& i" r6 G+ \2 Q. z0 k. P3 ~当CAN进入睡眠模式时硬件就对该位置1,从而供软件进行状态查询。 该位是对软件请求进入睡眠模式的确认(对CAN_MCR寄存器的SLEEP位置1)。当CAN退出睡眠模式时硬件对该位清0 (需要跟CAN总线同步)。 这里跟CAN总线同步是指,硬件需要在CAN的RX引脚上检测到连续的11位隐性位。
& \: E1 o9 c8 I) Z; _+ S注: 通过软件或硬件对CAN_MCR 的SLEEP位清0,是开启退出睡眠模式过程的唯一途径。有关清除SLEEP位的详细信息,参见CAN_MCR寄存器的AWUM位的描述。0 C2 N& h' ?) Q* ~6 [" V! U
位0        INAK: 初始化确认
3 T0 H4 z! L0 y3 r& g" H8 |9 K9 R当CAN进入初始化模式时硬件就对该位置1,从而供软件进行状态查询。 该位是对软件请求进入初始化模式的确认(对CAN_MCR寄存器的INRQ位置1)。- m4 k  ^$ C, ~. y: D$ G- r) e0 v
当CAN退出初始化模式时硬件对该位清0 (需要跟CAN总线同步)。这里跟CAN总线同步是指,硬件需要在CAN的RX引脚上检测到连续的11位隐性位。* R+ x7 D3 E$ k

! t, L+ V  u$ K" M0 i
% @% e! ^, f$ j: E+ p$ m+ I+ }; t/ L
- S5 e4 c0 m0 R# r! A; e5 p# J0 `! R9 Y" b, P* F
转载自flydream0- L" J& N# }3 q
# r$ Z  g% b) G: s1 o* H

* ~& x$ q; k1 o# d% \2 c# \* j$ ~; ]; J& Z# X" F2 F. ]: w' ~
收藏 2 评论0 发布时间:2018-5-28 14:50

举报

0个回答

所属标签

相似分享

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