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

【经验分享】STMCubeMX5.10版本CAN使用loopback模式自测

[复制链接]
STMCU小助手 发布时间:2022-7-3 16:00
使用芯片:STM32F103C8T6/ H& E* n5 Q2 O3 Z6 Y# P
cube软件版本:5.10
, S& Z0 [# E3 [( ^软件包版本为:STM32Cube FW_F1 V1.7.0
6 I3 j3 o$ O( v3 ?$ W1 T/ ?
, x6 p5 H# d( k; g" ?一、配置时钟为使用外部晶振,并配置为72M. D1 {8 t( j6 q- f: \% O6 B

9 |, W( q( y+ E& h3 T
DPXOW_XWCY6~5{2@@6@VW00.png
7 i9 ~, s  {6 S( R+ Z/ l 8CJFP6GSDY$CCX{NZ{34[8C.png , w! V1 w  r+ k7 p

% p! r' p# b8 F% b0 |7 e二、使能 can,并配置参数8 g* I$ h% G7 t* a" d* t
设置can波特率为500k,并设置为loopback模式,波特率计算方式为(systime/(pre*(bs1+bs2+sjw))),can时钟为36M,则36/(12*(1+2+3))=500k。8 G% t( P' P* B
- c$ t3 E: B' a3 Q
@RN)FK9600GT_B~R05H@6$K.png   o4 a# H% _) I4 R

# q8 K2 N1 T2 Z$ m' A! Z3 z三、开启can接收中断; S; ]4 b1 r2 ?
' n  H' s$ @& r7 a; T
XQF]BS53B8JK8]K}Q$(RIEX.png 7 J' u" K; N% Z: ~

' W/ g$ U& Z3 L% g' F8 o1 u四、设置生成代码,在生成的can.c函数中增加过滤器配置代码如下
9 P& n5 @7 ?; \' E* Z1 J: o) W

8 r9 k1 h8 D9 a1 S: u FD$(BEU3L~X](9N9YO3)B[G.png 0 O+ t& d# k; P1 x4 m( o

8 z/ h; ?" ]9 `% YCAN_FilterIdHigh和CAN_FilterIdLow组合成一个32位寄存器,用来存储将要过滤的ID
3 a' c) D. i; C5 N) f: S
5 V  f0 I/ W" V# Q! kCAN_FilterMaskIdHigh和CAN_FilterMaskIdLow组合成一个32位寄存器,用来表示这个ID的哪些位必须符合(置1),哪些位不关心(置0).
7 F2 C# l$ M' W- Y: H* S( w例如要过滤的ID为0x1e000000,则CAN_FilterIdHigh、CAN_FilterIdLow、CAN_FilterMaskIdHigh和CAN_FilterMaskIdLow配置为
7 x! u5 N5 g$ w% n+ o! |9 i- z
& X3 n$ ^5 {  }8 k4 E
  1. uint32_t EXTID = 0x1e000000;
    3 ?0 ?) Z0 m' c; |' D
  2. CAN_FilterType.FilterIdHigh=(EXTID<<3)>>16;
    8 V1 e- g. c/ `
  3. CAN_FilterType.FilterIdLow=((EXTID<<3)&0xffff)|CAN_ID_EXT;//只关心扩展帧,标准帧为CAN_ID_STD: a1 O6 w! e  D3 D
  4. CAN_FilterType.FilterMaskIdHigh=0xffff;
    8 A( z9 g1 y3 h0 P' G0 T" \
  5. CAN_FilterType.FilterMaskIdLow=0xffff<<3|CAN_ID_EXT;//每一位都必须一致,只关心扩展帧,标准帧为CAN_ID_STD
复制代码

& l+ H, @0 e8 a7 ~9 q% s以下配置代码,有列表模式和掩码模式,二选一
) P4 H/ D, j8 a7 W" w1 I" E+ |1 Y" [9 G, ^9 r* ^
  1. /* 列表模式只接受0x02200000和0x1e000000 */
    * H2 v* K& M. J2 j
  2. void CAN1_IDLISTConfig(void)$ t6 U4 R* {' r% i, h" H/ [5 H
  3. {9 @0 I# \! I2 x, b
  4.         uint32_t EXTID = 0x02200000;
    + A( f: @+ k3 B+ [" g. C
  5.         uint32_t EXTID1 = 0x1e000000;
    + m7 C: u+ k' V5 S+ K6 S! a
  6.         CAN_FilterTypeDef CAN_FilterType;' @1 Y, _2 q# y# o6 |
  7.         CAN_FilterType.FilterBank=0;6 Z& B1 i- s# G; [5 P' ]* E2 {
  8.         CAN_FilterType.FilterIdHigh=(EXTID<<3)>>16;
    ' I% z$ z2 m& j# O2 L
  9.         CAN_FilterType.FilterIdLow=((EXTID<<3)&0xffff)|CAN_ID_EXT;6 [5 [& U1 u6 b. A
  10.         CAN_FilterType.FilterMaskIdHigh=0xffff;
    ( H$ U  j# h- h) i% _
  11.         CAN_FilterType.FilterMaskIdLow=0xffff<<3|CAN_ID_EXT;
    % L- N% w& Y# N. b* s; E( ~
  12.         CAN_FilterType.FilterFIFOAssignment=CAN_RX_FIFO0;- i( X# K. z+ V1 j2 ^+ _' i
  13.         CAN_FilterType.FilterMode=CAN_FILTERMODE_IDLIST;; s0 C1 o( ]. j
  14.         CAN_FilterType.FilterScale=CAN_FILTERSCALE_32BIT;
    / X* a0 }7 ~, P) y, q2 ~" D
  15.         CAN_FilterType.FilterActivation=ENABLE;
    , G: S7 j) n0 k# ?( m, K$ R* E1 Y
  16.         CAN_FilterType.SlaveStartFilterBank=14;3 ~- Q4 `& V, v6 L  o; Z8 W
  17.         if(HAL_CAN_ConfigFilter(&hcan,&CAN_FilterType)!=HAL_OK)7 e4 P/ b- `& g3 W# w
  18.         {8 H& Q7 h$ _) y. s, M& ^
  19.                 Error_Handler();
    + B- q8 {3 N0 a  ~
  20.         }8 y$ K& G8 R' K- l+ I
  21.         CAN_FilterType.FilterBank=1;9 O- V/ u. o+ X' ~' q
  22.         CAN_FilterType.FilterIdHigh=(EXTID1<<3)>>16;
    6 @& `. G+ m$ |( ?+ d
  23.         CAN_FilterType.FilterIdLow=((EXTID1<<3)&0xffff)|CAN_ID_EXT;
    * Z9 l$ e1 h/ o+ k, W6 n5 k
  24.         CAN_FilterType.FilterMaskIdHigh=0xffff;7 E1 B0 q" k! t1 y* \1 A
  25.         CAN_FilterType.FilterMaskIdLow=0xffff<<3|CAN_ID_EXT;  Q9 s. R6 O3 U" i2 A# ^
  26.         CAN_FilterType.FilterFIFOAssignment=CAN_RX_FIFO0;- ^. C  r9 `" d/ m  i; q: ^  _3 w1 g
  27.         CAN_FilterType.FilterMode=CAN_FILTERMODE_IDLIST;//列表模式
    9 |/ x' z( O: [, j' ^
  28.         CAN_FilterType.FilterScale=CAN_FILTERSCALE_32BIT;" G# L( @% q* y, O% f( L8 b
  29.         CAN_FilterType.FilterActivation=ENABLE;  e; K  Y% d) Z  R# U/ s
  30.         CAN_FilterType.SlaveStartFilterBank=14;
    , s/ D  N# Z; V# j) E/ E! {
  31.         if(HAL_CAN_ConfigFilter(&hcan,&CAN_FilterType)!=HAL_OK)# h* ^# `( q; E+ I/ f4 `
  32.         {3 O- C5 R4 x6 n% ?1 {3 k, N
  33.                 Error_Handler();1 I- C0 b, z( }, l8 B) q' E
  34.         }; C# W" n) O2 \8 j( g; s- [
  35.         if(HAL_CAN_ActivateNotification(&hcan,CAN_IT_RX_FIFO0_MSG_PENDING)!=HAL_OK)( R! f6 D3 F* e) N
  36.         {
    - p; J! g+ S! }* x- ^  @% l$ V0 D. U
  37.                 Error_Handler();3 q% g/ r; N$ V0 B) M
  38.         }
    + a9 ?. I  W$ R1 |! t: T
  39.         if(HAL_CAN_Start(&hcan)!=HAL_OK)
    " e; x2 [5 P. s7 @* p# b* a% {
  40.         {0 ~* n5 J! H  \" ~) @
  41.                 Error_Handler();
    0 \3 p6 P) B& f7 M) x5 M, E7 M
  42.         }
    + @# |5 Z4 t# q' Q6 W- X# ?( G
  43. }
    8 L& V, J% b6 k6 u. c5 K' _
  44. /* 掩码模式全部接收 */
    * v9 f3 N+ |) j' Z) \
  45. void CAN1_IDMASKConfig(void)* u* R# h7 ]2 {4 N8 h0 r1 B
  46. {
    ) g3 i6 g6 \# A* A: i! t' y, [+ U
  47.            CAN_FilterTypeDef CAN_FilterType;' v: _5 A- U4 p, }' ]# l* H1 `$ @
  48.            CAN_FilterType.FilterBank=0;
    ! t/ q& l5 J, @, W- U& S
  49.            CAN_FilterType.FilterIdHigh=0x0000;% ^% U" c% X! i0 r& X6 h1 ]; ]
  50.            CAN_FilterType.FilterIdLow=0x0000;
    8 t* K" E0 ?4 ]! ^/ g+ ?
  51.            CAN_FilterType.FilterMaskIdHigh=0x0000;1 N7 @: P8 v  l  M1 Z) Q: S) t- {. D
  52.            CAN_FilterType.FilterMaskIdLow=0x0000;
    4 S! _0 w5 s1 a- H1 g
  53.            CAN_FilterType.FilterFIFOAssignment=CAN_RX_FIFO0;6 {* F' R" D3 z# |8 `
  54.            CAN_FilterType.FilterMode=CAN_FILTERMODE_IDMASK;//掩码模式3 n& `* n5 u1 b" L3 B: g( W
  55.            CAN_FilterType.FilterScale=CAN_FILTERSCALE_32BIT;/ s- N% p' n# N9 o  G
  56.            CAN_FilterType.FilterActivation=ENABLE;
      ?: i& M3 |8 v
  57.            CAN_FilterType.SlaveStartFilterBank=14;
    5 D9 q' T0 _4 N
  58.            if(HAL_CAN_ConfigFilter(&hcan,&CAN_FilterType)!=HAL_OK)
    8 b! D6 A% P/ g7 V# x* d7 f
  59.            {0 @$ q% b1 Q4 T5 ~! M
  60.                    Error_Handler();
    ( ?; ?2 d" {/ m  e
  61.            }
    1 o5 z- x! m2 _8 t$ T8 E, O6 D$ k
  62.            if(HAL_CAN_ActivateNotification(&hcan,CAN_IT_RX_FIFO0_MSG_PENDING)!=HAL_OK)
    ' g/ g1 H* G" _- p8 w) {  H9 X
  63.            {0 G# [# f3 ]5 ^' Y+ s
  64.                    Error_Handler();
    $ a) G; q" ?9 R/ T
  65.            }
    " f9 M$ [* x5 o5 A; R5 ]
  66.            if(HAL_CAN_Start(&hcan)!=HAL_OK)
    5 S2 v4 a3 F+ n$ A# h
  67.            {& H, Q# `$ j* E2 p0 ]7 N
  68.                    Error_Handler();9 x' v! \* k* b4 X2 a2 w+ `
  69.            }
    & L$ d7 q" K# S5 U9 k' M) h9 P
  70. }
复制代码

# X" [' o  T( ~五、增加can发送函数! z. T/ {* Z2 y) V% n1 Y
  1. /***********************************************
    8 m) P3 U2 F$ k/ f' E9 R) {8 y
  2.     函数功能:can发送数据) x# P, f# n( F8 @9 e) B
  3.     入口参数:% G1 ]4 ]/ V4 s! ?" l6 r
  4.                             ide:        0:标准帧
    5 F% w3 ~! E: G1 S! A
  5.                                             1:扩展帧
    3 W; T% j4 C1 S( j% B
  6.                             id:        帧ID: _' {& C7 C" v. i- N% ?( Y
  7.                             len:        数据长度
      h( u9 C' V' v- Q
  8.                             data:        数据; h2 y, e! Z2 j: X1 f& ]+ H. N
  9.     返回值:0:成功。1:失败9 u+ D' [" j3 p. {: h8 C
  10.     ************************************************/
    ' k$ ~& k) [9 s- t
  11.     uint8_t Can_TxMessage(uint8_t ide,uint32_t id,uint8_t len,uint8_t *data)( J% P0 b0 K, B+ i, o0 Y2 e- I
  12.     {1 y" a( d. j) y0 e: g2 f
  13.             uint32_t   TxMailbox;
    9 g, r; e8 J! x6 n" w# k  a: L
  14.             CAN_TxHeaderTypeDef CAN_TxHeader;
    & u& q/ H2 A! ~# h, b+ t
  15.             HAL_StatusTypeDef   HAL_RetVal;
    : I( V* u3 Q/ z: g) X
  16.             uint16_t i=0;
    1 B" `/ v4 e  m8 e' C5 e
  17.             if(ide == 0)2 t) P7 @# n& ~' V" C. U& o/ f! n
  18.             {" `! Q/ |' E( e1 R, F. }
  19.                     CAN_TxHeader.IDE = CAN_ID_STD;        //标准帧! D; f5 E& ]) ^0 f  D: [( l
  20.                     CAN_TxHeader.StdId = id;
    9 K) r' R' m9 L; o: E, v1 U
  21.             }3 t0 _* K' J) h' Q; Z
  22.             else
    $ `8 ]- I4 V5 |5 M; {9 l
  23.             {
    * s0 `+ N# {" M/ J1 ^6 \
  24.                     CAN_TxHeader.IDE = CAN_ID_EXT;                        //扩展帧4 b+ ]3 n0 `0 X9 y; D- l2 S# Q
  25.                     CAN_TxHeader.ExtId = id;% ^8 v) E% r$ o' {
  26.             }
    ; Z, ~0 P7 ?/ ~4 w* \  x
  27.             CAN_TxHeader.DLC = len;
    6 E1 h! \% D4 X: y0 [+ }
  28.             CAN_TxHeader.RTR = CAN_RTR_DATA;//数据帧,CAN_RTR_REMOTE遥控帧
    & K) N, ]8 p+ A! T3 W4 a7 p3 a
  29.             CAN_TxHeader.TransmitGlobalTime = DISABLE;, Q7 y. {* l( f3 W
  30.             while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan) == 0)+ V+ C. p. m' R# d9 A
  31.             {: U' Q- h8 N! K: D0 k3 I
  32.                     i++;& u7 x/ v# n% ?/ N0 U
  33.                     if(i>0xfffe): X" }$ C( K6 d% d$ H) x
  34.                             return 1;( D6 b6 z5 K- Q; e2 ?
  35.             }) w* d8 E, F: `! h; o1 F0 ]3 r
  36.             HAL_Delay(500);
    ( x- Q, w- v1 M" e! @
  37.             HAL_RetVal = HAL_CAN_AddTxMessage(&hcan,&CAN_TxHeader,data,&TxMailbox);
    1 H* m3 F) s; f# W
  38.             if(HAL_RetVal != HAL_OK)6 ]5 M- K3 Q' ]7 x# X, V8 {9 C
  39.                     return 1;3 ^# S5 x+ ^$ s
  40.             return 0;5 l# P/ s/ c8 D3 U
  41.     }
复制代码
! ^$ c! b8 n( E8 E  N
六、增加接收中断回调函数+ N# |. e% s! i' _3 t
  1. void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
    # n* T2 ^8 o6 `; g& `
  2.     {5 x) N, h6 s# ~# }; }' A; [; ]
  3.             CAN_RxHeaderTypeDef CAN_RxHeader;* m+ [9 ?# P% n& d8 c; B
  4.             HAL_StatusTypeDef HAL_Retval;# X  n! A( G7 d1 z! J
  5.             uint8_t Rx_Data[8];, N6 q2 I% J2 F5 j& l, p
  6.             uint8_t Data_Len=0;
      U' ~# \, ?9 X+ @* ?, O% o& [! b
  7.             uint32_t ID=0;
    " h1 x: _9 I3 `4 {" |1 N4 x( E( C
  8.             uint8_t i;
    : \% F& Q! F3 s+ T3 `
  9.             HAL_Retval = HAL_CAN_GetRxMessage(hcan,CAN_RX_FIFO0,&CAN_RxHeader,Rx_Data);  j5 O9 ?8 ?! W* n% g2 G
  10.             if(HAL_Retval == HAL_OK)
    5 k! N& H- j* l. Q  P
  11.             {6 @* k7 ]. V, U- F: L
  12.                     Data_Len = CAN_RxHeader.DLC;
    % w* o5 q4 K5 X9 c  E9 U( `, L8 V
  13.                     if(CAN_RxHeader.IDE)
    & C: v, n+ o  l; U
  14.                             ID = CAN_RxHeader.ExtId;
    ) E' i5 f; ]% F+ c/ O, l4 w0 D8 c  M! P- Q
  15.                     else) Y* x4 }% I9 \& D
  16.                             ID = CAN_RxHeader.StdId;/ |  }& x  N4 u0 R
  17.                     printf("id:%x\r\n",ID);3 H7 T& V' C& o+ d1 Q
  18.                     printf("Data_Len:%d\r\n",Data_Len);
    $ R# c( O6 k. y" p# p
  19.                     for(i=0;i<8;i++)
    . E% z$ u) e8 P$ ~* W4 w
  20.                             printf("Rx_Data[%d]=%x\r\n",i,Rx_Data<i>);        
    ) N& ~0 m+ [6 a( a) R6 J( m
  21.             }2 ]: r& I! K5 N" Y: }, r2 I! M
  22.     }</i>
复制代码
8 ~/ W3 {9 @! d

8 ~5 g# `$ G7 x* t8 @! S7 F七,在main.c函数中增加函数,最终如下:
4 t8 {4 y( y" t4 A+ W9 a1 K
  1. int main(void)7 ~0 i) k8 \+ S" }
  2.     {
    9 `( O2 ^! i! U0 h! @, d9 u
  3.       /* USER CODE BEGIN 1 */5 H$ c9 J* j+ X3 f
  4.             uint8_t data[8]={1,2,3,4,5,6,7,8};
    3 Q  T+ [9 W# S; p1 p6 J
  5.       /* USER CODE END 1 */' C2 o. _2 T3 l* g9 z6 G
  6. 2 G& _! S7 D& @  f5 s  L
  7.       /* MCU Configuration--------------------------------------------------------*/
    ! ]! S, C; q; l8 I: k1 n8 C

  8. / g: l! t- q* O2 `0 Y( l$ {6 t
  9.       /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
    2 l- e9 |; p) f& z; J+ e! `
  10.       HAL_Init();
    8 ?4 q4 G5 o5 e
  11. # ^; O. J+ r, ?0 M, J3 U
  12.       /* USER CODE BEGIN Init */
    - P' m* Y" }* D% H! s9 T
  13. ; v0 [/ u2 l1 D. Q8 M5 e: R
  14.       /* USER CODE END Init */
    - P1 m7 L( K9 Y0 T- T6 `: Q
  15. # y$ q3 N+ t8 y6 I
  16.       /* Configure the system clock */! n( d  r- ^- ]) H
  17.       SystemClock_Config();" [3 S* x* d& K" ]1 Y1 j8 H

  18. , P5 L: ^9 }( `, C( n
  19.       /* USER CODE BEGIN SysInit */0 }! e5 }) X8 F

  20. 3 p  x. S! H6 m% b$ X- B
  21.       /* USER CODE END SysInit */+ T+ j( w( Z% k% j3 R. h
  22. 4 R9 }' D& g2 }$ Z; }
  23.       /* Initialize all configured peripherals */& n: l$ r, {5 T5 V* F/ \1 h0 Z* w$ r
  24.       MX_GPIO_Init();, @* w9 q5 Z* Y: j" s* J
  25.       MX_CAN_Init();
    ; j5 N" d7 h8 @* i: g
  26.       MX_USART1_UART_Init();
    7 h) ]" m/ F( d/ }- ?# m. Y
  27.       /* USER CODE BEGIN 2 */
    ' C3 O, r) ]* Q) ~: D! T
  28.             CAN1_IDMASKConfig();//过滤器配置& V2 d. `, I7 G- z
  29.       /* USER CODE END 2 */
    2 J4 n5 `: R1 p8 }  x( B
  30.       /* Infinite loop */
    4 ]# M% j' q& K$ W0 H
  31.       /* USER CODE BEGIN WHILE */
    / M$ z5 Q4 w2 ?( A5 n
  32.       while (1)2 W8 Z4 G/ W2 {) v& M# _. h; H
  33.       {
    + N. S4 s1 C' _& d% [$ b! K
  34.         /* USER CODE END WHILE */& n5 \* O& M* S) I: \
  35. ) c' c/ i7 `4 c. p
  36.         /* USER CODE BEGIN 3 */
    ) _( Y8 I" f7 A( t
  37.               Can_TxMessage(0,0x222,8,data);//CAN发送
    3 C+ a) v2 w! t/ S$ M' {
  38.               HAL_Delay(1000);
    4 j0 v: x. g, y: g" J! T6 j6 U7 F. z: j
  39.       }# z9 c+ `9 g( q2 d/ O) a* k
  40.       /* USER CODE END 3 */3 Q  W, q% W/ r0 N! _
  41.     }
    ) x# I6 P/ S0 m1 k7 J' ~- U
复制代码

) `1 W$ e. t7 z3 Y: o每隔1S,通过can向标识符为0x222的设备发送一次数据,因为本例程设置的为loopback模式,所以不需要接任何外设即可,通过串口调试助手查看接收到的数据,与发送数据相符
* W- ^1 z3 {8 @3 c& H! ^) S5 v, J7 a6 X2 y/ u2 G

# q. Y! _& A( b# I, O. t% k# W
& F# F1 x6 `# Z3 ]
V$YJS[W1Z]9LB(@}N~5F@1H.png
赞 收藏 评论0 发布时间:2022-7-3 16:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

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