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

【经验分享】STM32-CubeMX-实现CAN通讯

[复制链接]
STMCU小助手 发布时间:2022-6-26 11:29
  首先要安装cubemx跟Keil5两个编程软件,然后打开cubemx软件,新建一个工程项目:
: |4 X" t. {$ a/ m0 L1 ?
微信图片_20220626112734.jpg

8 t$ g& V+ f0 c
    输入CPU型号:
- y. j2 m8 ^$ H* o3 u
微信图片_20220626112737.jpg
( V% r5 B, f3 Y' F( G9 ~
    在右下角双击CPU具体型号:

3 i+ u9 w: c! E1 E' F+ g/ h2 t9 y
微信图片_20220626112740.jpg
9 S( r" j# ?/ h& U" d& N! W9 b
    稍等片刻会打开如下对话框:
- T) |# d( f6 R
微信图片_20220626112750.jpg

- P0 S6 @% s# ^; }: y6 C9 R$ E
    首先要配置系统的调试方式:我们选择SW方式,

- u* D# N# u1 O" \
微信图片_20220626112755.jpg
7 V5 a, M$ w1 J) }$ ?$ |5 ~
    然后配置晶振源,这里选择的是外部晶振,8M,

% I6 q8 U% c: o+ E
微信图片_20220626112758.jpg
$ E( C( ]. O% `
    使能看门狗,
2 T! R, S/ L3 p1 v% u( n
微信图片_20220626112805.jpg
1 j+ b# g6 P+ @; I- Y  j
    使能CAN,
" Y; ]* I' ]! t# |
微信图片_20220626112810.jpg
0 C1 w1 l3 O+ A; K9 a- \
    使能TIM2时钟源,采用内部时钟,

, O/ h; k- ~0 X# P' ^; ]! Q$ r' \
微信图片_20220626112817.jpg

: i! i; e6 S' N  f
    配置完成后可以看到单片机管脚已经做了配置。

7 V) @" @7 Q( ^% T( N; T
微信图片_20220626112826.png

3 X, r# U8 S& t/ X, n
    切换到Clock Configuration选项卡,配置时钟周期,这里配置为8M1 d$ T8 Q: R6 `4 @
3 `8 v( Z- `2 N1 ^. X; L- W8 P
微信图片_20220626112835.png

% Q1 q7 a* h  @4 }. J) f3 |
    切换到Configuration选项卡,进入CAN配置选项配置波特率如下为500Kbps。3 m  N) P) i0 m# k2 r
  F: y6 o6 t- H4 |, J6 S/ V
微信图片_20220626112838.png

9 |. V& S2 r7 q, h
    配置接收中断。
2 h) {% K. S; J" B4 L
5 Z! E- Y# p- u1 a
微信图片_20220626112842.png

& |6 Q. s% ?, D4 q* _, k- p& B
    配置定时器如下为1ms定时器。% v) D. b$ H1 U# z, B
3 @/ |3 M8 D6 ?$ T) [- }) v+ f& _9 L
微信图片_20220626112845.png
: p# ^9 e" m! n. O- u5 C: o: k
    配置定时器中断0 ^" p2 s; q2 [# q
5 k  X4 a4 x( v' L$ d
微信图片_20220626112847.png
0 ~# R5 d3 @3 O& }
    配置完成后点击保存,然后点击如下按钮,生成代码. @6 R. v% p3 a& F
- ^9 s4 ]& y, B) N4 R, J' Q
微信图片_20220626112850.png

9 A+ @9 }5 S( [4 F
    填写工程名称,路径,编程软件等等; E4 t8 f7 E+ d7 C- `4 |

3 [0 c) @. i6 r7 v0 g
微信图片_20220626112853.png
- R# e5 `6 O% Y# i
    选择生成代码的方式
$ h4 s& c, Z/ ]2 i! V& F

. }/ J2 d: f* H5 q) A4 E& K3 h" w& u
微信图片_20220626112857.png

9 L. l, \& [$ b8 q
    等待……
    之后点击打开项目。代码生成部分完成。
, K; q6 c8 c6 R
微信图片_20220626112901.png

' q3 v( B9 t+ X9 @6 j- l' y7 M
    添加一些特殊配置和逻辑代码,添加CAN的配置信息函数。
  1. void Can_Config(void)/ c4 u: a$ U5 l  o: l
  2. {' ^4 U& |' _5 A# u& \- X
  3.   hcan.pTxMsg = &TxMessage;- [: i. z% I$ v5 l) n
  4.   hcan.pRxMsg = &RxMessage;
    + S" f9 C: r+ S& M) l. ]2 x
  5. # H5 N" K* N! {4 J3 _9 J
  6.   /*##-1- Configure CAN1 Transmission Massage #####################################*/
    + E- Y. v# f. C  e4 b/ M5 E
  7.   hcan.pTxMsg->StdId = 0x123;/ X1 c5 r/ E- I, g) }
  8.   hcan.pTxMsg->RTR = CAN_RTR_DATA;+ m9 i+ k0 ~$ K, x9 {
  9.   hcan.pTxMsg->IDE = CAN_ID_STD;
    ( ?3 |6 a1 \% s% S5 T9 v) A% q
  10.   hcan.pTxMsg->DLC = 8;
    - v! _$ m! t" W) a0 b

  11. 0 D1 J3 n# p8 \" c3 C' I- b# b
  12.   /*##-2- Configure the CAN1 Filter ###########################################*/: }: I- x6 c0 e7 Y5 p" {8 m& I- z0 ]: R
  13.   sFilterConfig.FilterNumber = 0;
    8 \' ]) ^' w2 j1 V6 `) R
  14.   sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
    . X% j( l0 c) ]3 q% B* ^' ~
  15.   sFilterConfig.FilterScale = CAN_FILTERSCALE_16BIT;& S7 F! e. ~" O3 X4 @6 S7 i
  16.   sFilterConfig.FilterIdHigh = 0;
    % C% S6 J8 X7 n4 ]7 u
  17.   sFilterConfig.FilterIdLow = 0;
    8 M: t2 i0 d$ T/ _
  18.   sFilterConfig.FilterMaskIdHigh = 0;7 @9 r! `8 {+ q. S( ?
  19.   sFilterConfig.FilterMaskIdLow = 0;
    # N( ?0 V0 e7 |9 P, i
  20.   sFilterConfig.FilterFIFOAssignment = CAN_FIFO0;
    7 ^* p/ o; Z7 X
  21.   sFilterConfig.FilterActivation = ENABLE;+ i+ v2 z6 r: e! J& |
  22.   sFilterConfig.BankNumber = 14;% E9 A+ z/ q, C- V( E
  23.   HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);
    . E% z9 N7 y* x) o; n% n  w; P
  24. }
复制代码

. p' p! t) ^: S  D' A* q
在Main函数中while(1)之前调用一下即可,添加定时器启动函数:
  1. HAL_TIM_Base_Start_IT(&htim2);
复制代码

6 ?4 h* I5 H2 J. B    CAN接收中断启动函数:
  1. HAL_CAN_Receive_IT(&hcan, CAN_FIFO0);
    8 o8 o( ^/ J, c: Q, ]) ?& }
  2. /* USER CODE BEGIN 2 */
      k5 T$ v1 M3 }% [, w- e+ ~6 T
  3. 3 C+ p* N2 K! M) _
  4. Can_Config();                        //Can配置信息6 f- q. [/ `" e0 P% ~4 v
  5. HAL_TIM_Base_Start_IT(&htim2);       //定时器启动3 q0 c4 u  l$ m! i
  6. HAL_CAN_Receive_IT(&hcan, CAN_FIFO0);//使能Can接收中断7 s1 R3 m" w1 S* Y

  7. 6 s% d3 m; ^4 P5 E1 K
  8.   /* USER CODE END 2 */
复制代码

4 u) S. _  u/ c
    打开stm32f1xx_it.c文件,找到如下函数,添加接收中断启动函数:
  1. HAL_CAN_Receive_IT(&hcan, CAN_FIFO0);
复制代码

; s. n* m; t0 k6 M9 Y
    注意:接收中断启动函数使能一次只进一次中断,所以中断退出前要再次使能。
  1. void USB_LP_CAN1_RX0_IRQHandler(void)
    ' \! j$ N8 R( ]/ [: b, Q5 x
  2. {
    3 m# U' Y+ Y( M" d; y
  3.   /* USER CODE BEGIN USB_LP_CAN1_RX0_IRQn 0 */
    2 R" [+ b1 |" ~
  4. 7 D. s9 {8 Y  e* V; B% |
  5.   /* USER CODE END USB_LP_CAN1_RX0_IRQn 0 */5 Z1 C0 \+ D5 u6 V/ S
  6.   HAL_CAN_IRQHandler(&hcan);
    / q2 W# D4 a4 g. _% e+ w+ u
  7.   /* USER CODE BEGIN USB_LP_CAN1_RX0_IRQn 1 */
    8 Y" {; G, f  c( K
  8.   HAL_CAN_Receive_IT(&hcan, CAN_FIFO0);//ʹÄÜCAN½ÓÊÕ; `( z- q6 I5 O1 L0 y: Q, M
  9.   /* USER CODE END USB_LP_CAN1_RX0_IRQn 1 */6 U1 h* ^: X& O1 j& _  _: A& B
  10. }
复制代码
' Q4 H: B2 U/ Z! W
添加CAN接收服务函数:
  1. HAL_CAN_RxCpltCallback
复制代码

* t' e2 o# C3 N: K- b4 k0 U
    说明:该函数在stm32f1xx_hal_can.c文件中已经有定义,它的定义方式如下:
  1. __weak void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef* hcan)
复制代码
+ Q+ c  M, `7 \( n; a
    函数前面的__weak关键字意思是如果有同样的定义,先执行没有__weak关键字的函数,所以当我们定义了HAL_CAN_RxCpltCallback函数后,编译器会先编译我们定义的函数,而忽略系统定义的该函数。当我们没有定义该函数时,系统会编译带有__weak关键字的函数。
  1. void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
    . l$ y1 y2 Z! `% a, c1 p, u
  2. {
    , N5 |9 ~7 n; }) y( L: q: W
  3.     unsigned short int speed;# k  r. X  A  h' ?0 ~4 A
  4.     switch(hcan->pRxMsg->StdId)
    $ Z% \1 V' Z: @% O4 t) x
  5.     {//根据ID处理数据
    ) V5 D, a% a5 X4 n. `
  6.         case 0x123://+ b5 ]  P# ]! D8 R0 p
  7.         /*在此添加数据处理逻辑*/3 L  q, t6 G- I8 v. h
  8.         break;
    . V9 z3 |+ ~8 t- s
  9.         default:1 P, }; J  @- H$ e
  10.         break;: Y6 z2 z) G( V
  11.      }
    / C7 j( D; J( \  O7 T; Z
  12. }
复制代码

1 b2 B4 b; h7 j5 I
添加CAN发送函数:
  1. /* USER CODE BEGIN WHILE */: {) o% w4 _& i7 }/ M
  2.   while (1)
    + _+ R  ~: T. H
  3.   {
    + P7 u# Y/ I6 n2 i# }
  4.         HAL_IWDG_Refresh(&hiwdg); //喂狗函数% z7 R; m  @! W* z

  5. # c0 b: E; S- x/ a: N
  6.         if(Can_Trans_Timer == 0)* H1 M3 H- d2 ?6 @; Z, g8 V7 p( m
  7.         {//每100ms发送一次数据: k& z) q0 x6 V
  8.             Can_Trans_Timer = 100;
    & l9 `" x& {" p  a- A

  9. 0 X) @4 w% Z2 E2 c) T
  10. 2 ]$ @/ [9 {' m1 O/ }1 G7 q- q
  11.             hcan.pTxMsg->StdId = 0x123;
    9 W% l! O  H- X1 L& C2 c& }9 I
  12. ; p2 }* H, O) ^
  13.             hcan.pTxMsg->Data[0] = 'C';
    9 \$ N0 D9 W% O& Y9 U
  14.             hcan.pTxMsg->Data[1] = 'A';- A: _0 @8 H# C1 i
  15.             hcan.pTxMsg->Data[2] = 'N';
    6 R2 Z6 m8 I# r' T2 |
  16.             hcan.pTxMsg->Data[3] = ' ';
    ! K" B0 f- c; ?8 @
  17.             hcan.pTxMsg->Data[4] = 'T';
    9 a- Q& R' h% K6 O/ V' ^" c
  18.             hcan.pTxMsg->Data[5] = 'E';
    / I% g/ O# v$ O$ S3 X( }+ t
  19.             hcan.pTxMsg->Data[6] = 'S';3 }6 g2 b5 U8 T2 D
  20.             hcan.pTxMsg->Data[7] = 'T';
    - e1 U  V- T! S
  21. 7 q% F4 ]3 F% h; f6 G4 r& m. `

  22. * J+ k* \, w- Z
  23.             HAL_CAN_Transmit(&hcan, 200);//发送一帧数据
    $ L  J- E0 B0 f3 H: e' W3 u
  24.         }
    5 i% z$ e% A  U  b1 m
  25.     }8 p9 q8 _8 P, c5 B: _, {
  26.   /* USER CODE END WHILE */
复制代码

7 i( u: B: [: l/ u2 f
在定时器函数中添加定时器代码:
  1. void TIM2_IRQHandler(void). \/ }/ A/ t; Q5 Z
  2. {
    ; l. v: J: }+ Z& p$ _
  3.   /* USER CODE BEGIN TIM2_IRQn 0 */
    ( r) x$ R; Z' I. V8 @% |& @: d
  4.   if(Can_Trans_Timer > 0)          Can_Trans_Timer--;: j. I2 N9 n6 ?8 z' Q! j8 ?: r
  5.   /* USER CODE END TIM2_IRQn 0 */2 j$ d$ {# W" Z/ R
  6.   HAL_TIM_IRQHandler(&htim2);
    1 q7 F5 p2 ^& l1 i/ L4 X
  7.   /* USER CODE BEGIN TIM2_IRQn 1 */* F* U1 a' z# T& R) g- R
  8. 4 B7 g& M) o* U9 d) L0 }
  9. 0 C4 B$ u+ `; @  U
  10.   /* USER CODE END TIM2_IRQn 1 */: n1 }+ F/ S7 E. \/ |
  11. }
复制代码

; N/ g) ]4 O" E4 h
    说明:在往工程中添加代码时要注意,不要任意往里面添加代码,要在注释着USER CODE BEGIN的地方添加代码,这样在重新生成代码时才不至于将已经写好的代码覆盖掉,如下
  1. /* USER CODE BEGIN Includes */
复制代码
" ^& o5 ?# D" W3 G# D* a# @
收藏 评论0 发布时间:2022-6-26 11:29

举报

0个回答

所属标签

相似技术帖

官网相关资源

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