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

基于STM32F1的CAN通信之概述

[复制链接]
攻城狮Melo 发布时间:2023-10-23 15:12
一、专栏简介, E, Z% `: u  [
本专栏介绍如何利用库函数进行STM32单片机开发,主要针对的单片机型号为STM32F103ZET6。总结来说,“速成”体现在以下方面8 G0 N) ]6 b' \8 A& b
• 在讲述基础知识后会有相应的实例或者模板程序
8 d/ k# J" F5 k$ N- A# i' Z! }• 学习完后会有小项目练习5 f/ E1 V4 n6 i' l" i* V
• 专栏基础知识部分内容精简,对于“速成”选手更加友好
1 V. h* `9 k, _% \
) |' y2 j' z4 N+ @/ X/ C

/ J, G4 Z5 G0 M$ v( }其次专栏还有以下内容
+ Y9 i9 b/ r$ X/ W9 e; j7 r4 E. J, l9 _• 简单介绍编程规范和程序架构
. J/ P3 W+ g6 L" _  n6 W7 S• 专栏不断更新一些外设的使用方法并提供例程  P3 U% ?" \  |5 j3 {
6 S5 U- ]  Q- x, N4 m
) z0 b  J) ]$ x5 S: e" q
二、前期准备
3 o' a% q; ^) G+ z前期准备主要有物品以及相关软件的准备。首先是物品,单片机选用的是普中科技的一款核心板,主控芯片为STM32F102ZET6,是下面的样子7 e2 w/ ^. u' ?+ W- c5 f
微信图片_20231023151024.jpg
5 v. r. I9 t( B! G9 ~
STM32F103ZET6

; b$ I1 j6 |$ ?* ]& ~* D) @3 w2 z2 R3 t% ]

& ~" h+ Z  S) H图片上是带有LCD屏幕排母的,有一种是不带的,因为本人开发时经常使用LCD,所以买了带排母的,在某宝和聚诚科技购买的,不带彩屏169RMB。学习过程中除了单片机以外还需要购买调试器,ST-LINK,用来下载程序和调试。USB转TTL(可以直接搜索TTL),用来做串口通信时使用,也可以用来下载程序,但是不可以调试。对于前期学习来讲,这些物品就足够啦。
: O! T3 Y8 g; N' w* m+ g& S
( Z. M8 |4 _/ u. ]
  X& f8 v: C" G& b: w
除了物品之外还需要提前准备一些软件和驱动。比如Keil5,CH340(串口驱动),ST-LINK的驱动,这些都是需要安装的。其他的类似于下载软件,串口调试助手都是不需要安装的,本人用的是普中科技提供的一些常用辅助开发软件,小伙伴们可以自己动手找一下,没有找到的话私信留一下邮箱,注明需要常用辅助开发软件,后续会邮件发送。, I2 {# X- |5 `# h/ ^# c5 ]# @0 r
, B4 a9 v# @. ]7 x8 h

- N8 d- Q: T" d三、编程规范以及程序架构简介
# I- s, d  H8 _5 E3 S1. 编程规范1 k/ z+ c* {. Q* U5 @' E1 b
对于新手来讲,编程规范以及代码架构也非常重要,有一个良好的编程规范和代码架构,可以提高开发效率,方便问题排查以及后续的程序维护。这里介绍的编程规范很简单,要求不严格。主要有以下几点
2 @5 H  n5 ?$ w% @4 M; A; S
5 u+ O& u5 f, q7 c. O  S
' f% e8 M+ o: k) {* d7 t# t
• 变量定义 变量定义时最好是能够体现该变量所属的外设模块,该变量是否为全局变量,静态变量或者指针变量。变量首字母小写,后面的单词首字母大写。举例如下
0 T' e1 k# v" R. T( y8 }' X( T* n, H# X1 N: p
5 l/ O' v3 c# a  P
  1. // 以ADC模块为例,需要定义一个存储AD值的变量,举例说明变量命名方式
    / ]0 Z4 U( t# Y

  2. 4 A% y' S( J5 O8 P7 i" b8 t& G$ x+ J
  3. // 局部变量2 l0 F3 }% a% N0 _! P) s
  4. u32 adValue = 0;
    + n. w9 D8 X! b& U; s) I
  5. * s, C7 [: @2 ~& g
  6. // 全局变量
    " l9 A7 W4 {4 h+ b3 a
  7. u32 gAdcAdValue = 0;   // 加一个g表示是全局变量
    7 Y$ a2 w0 H0 W  Q) G: a) k
  8. 1 u1 |0 P0 U1 D6 R# x+ c/ g9 V
  9. // 全局静态变量
    2 n. v, {4 w, Q  W( Z; M1 |+ `6 o
  10. static u32 gsAdcAdValue = 0;   // 加一个s表示静态变量
    , K$ @; x/ B9 `  f

  11. " I+ S) y* I: X8 Z0 \  b
  12. // 指针变量
      L, p  {* u4 N. y5 I. l0 l
  13. u32 *gpAdcAdValue = (u32*)0x2000800;   // 加一个p表示为指针变量
复制代码

1 T/ y7 ^/ A2 ?% }7 K% r" g5 U9 T. |2 P; f( E
• 注释 函数注释举例如下$ U5 D2 q/ C% V$ Z- p& h! |2 [0 M
  1. /*; f5 n/ M/ l$ W* {# O( H3 W
  2. *==============================================================================2 X4 X$ L% F1 a+ L* R
  3. *函数名称:3 T0 f- n! i+ c" ]3 A* j8 s% ?5 F
  4. *函数功能:0 ]. ?/ j) @" ?: s3 h9 E4 v! V
  5. *输入参数:
    0 d- |' W1 M, Q4 O: @6 ^
  6. *返回值:无, }& e7 X* t( A! p2 a. g
  7. *==============================================================================
    2 E. @6 o7 d4 f! _* }) B
  8. */
复制代码
3 x. p  n* A# p: @0 h; o  O. T
$ l* M2 z5 }' m5 ~( ~6 z8 \$ ?
对于程序语句注释,如果过长可以在程序上方加注释,如果不是很长可以在程序语句后面空三格输入注释。
& @: V+ Y8 S: N3 r4 {1 o: z3 w1 V% h& n7 w* L2 o
; Q1 [3 u6 B, Z
• 函数命名 函数命名要体现函数所属的层级以及函数的功能,关于层级会在代码架构的部分详细说明,这里只说一下函数命名方式。( w5 p  i6 N/ @7 g5 s
  1. // 这里以ADC模块的读取AD值函数为例,说明函数命名方式7 ?- p8 x: a6 |' ~4 V, v' l
  2. void Med_Adc_ReadAdValue (void)
    ' G$ ?; _* \# N
  3. {9 U- J( U- T2 b( o! Q$ @' O; U( J
  4.     // 函数内容
    ( r- Z' b6 K/ B
  5. }
复制代码

% A( t" o* C) f  N- r" p0 G0 I6 A: z  j
这里med指示该函数位于功能层,属于ADC模块,作用是读取AD值。1 @2 w3 }( M) K' W6 g4 M

, W8 q- U9 o; v/ L1 Z+ I9 B4 }

, h: o) ?$ I5 u8 S7 I2 Q  Z• if,while等语句的使用 使用if或者while等语句时,需要在括号前面加一个空格,如下
' L& l$ k# F9 s
  1. if (gAdcAdValue == 0)
    7 S' {8 K, G+ X8 e4 |) _
  2. {
    : M; j5 o( P' j5 J
  3.     // 程序语句
    8 ]3 J* j  a' x$ B+ u. g; F2 i
  4. }
复制代码

0 B- H4 \1 }0 A$ g
7 R! {5 ~4 Y  Q8 I/ X) ~$ K3 E5 q• 四则运算 四则运算符号前后需要加空格,包括等于号等符号。如下' E, J/ c+ r/ r( u3 ?$ N
  1. c = a * b;
复制代码
9 `# k  e# Z' n% j" a+ n6 W
* T* V* J8 W5 F9 G) Q+ U
2. 程序架构
" y& K, W9 ?& e( ~( v. y' Y; |  j; _该程序架构是本人在工作期间学习的,个人感觉还是有助于提高开发效率,方便后续维护的。主要思想是将一个模块的程序分成三部分,每一部分是一个新建的文件夹,下面都是其他模块相同层级的文件。
( E" ]9 y% E  k# i$ z$ z
( P( S0 g) {$ G# c

/ L) B. _; ^# E( q• Drv 驱动层 该层主要是写一些模块的初始化程序,例如GPIO的初始化,ADC的初始化等。( E  N* t! X' r# b/ ]9 ]/ k* |* i: I
• Med 功能层 该层主要是完成一些功能性的操作,比如读取AD值,点亮LED等。Med层的函数可以包含Drv层的函数。1 N" g5 n- H( L* [$ Y
• App 业务层 该层主要是完成一些业务,比如在点亮LED的基础上实现流水灯,比如显示电压值等。
" ~: g2 I5 n4 N- ^5 X
8 r) r( S. u( R

" H# t7 @2 q- \7 E四、STM32F103ZET6简介
( W, g! x: ^3 E0 H- |" ASTM32F103ZET6是由意法半导体(ST)生产的一款单片机,32指32位。STM32也可以成为32位微处理器。STM32F103ZET6的主时钟频率为72MHz,512KB的FLASH,64KB的SRAM。常用到的有GPIO,中断,ADC,TMR,UART,DMA等。0 K$ b/ \4 f/ N5 X( B- z4 z

! F2 W3 Q( ~- o2 J  u5 c+ A

5 f- @. a# e" e1 J! q% s五、程序模板
/ _* b/ k. h, Q. l1 m4 |  \在使用Keil5编程时,针对一个外设需要新建对应的.c和.h文件。这里以LED模块为例,简单介绍一下本人的常用模板
) v/ L# o  a* i! W4 [: w, Z
0 ]. q9 [8 n2 ~/ X. e

7 X, ]* f- |5 W" r.c文件6 S2 U9 T0 U; x( `
  1. #include "LED.h"   // LED头文件
复制代码
# \$ U  N) i  j

' G+ r# M6 }+ c需要注意的是一定要空出来一格,否则编译会报警告。
0 w" |% F6 b8 M+ |6 Y# S
! ^' |% F' d6 e4 D9 n) N: L$ |

' U4 J2 F/ V0 b' b  Z, l: B# k+ \
微信图片_20231023151019.png

; O6 p4 k/ j+ x- I# V
文件最后未空一行的警告
/ N" B% \. c0 w2 Z9 k
.h文件7 F* z6 p0 C  C6 }0 A
  1. #ifndef _LED_H% e1 Z- m2 C7 H5 L6 Z6 T/ O+ z
  2. #define _LED_H0 H6 l+ n3 _- }, M6 y
  3. - G% y0 R4 s, ~  O
  4. #include "sys.h"   // STM32库文件
    3 `7 ?) P+ t# A( `0 a

  5. 7 k5 }4 X" [; b1 Z! l
  6. #endif
复制代码

+ J4 w5 z( Y% s% M( Q
) }  o+ m( P' }! D& p.h文件最后也要空出一行,否则也会有警告。) ^$ }8 K7 Z5 G( D0 L; D
; L% y- U( y. j& h2 ?' g0 @

% ]7 t9 [8 a3 L( g- N8 P新建完之后需要将这两个文件添加到工程中。
6 D7 g8 ^- y# j9 _* c. `, a  G! ^5 \% k( Z% t. S- K! M4 Q

: D  ~- N7 r6 B对于.c文件,右键工程文件夹,选择“Manage Project Items”打开。' k4 _) |0 x4 W$ \, k

7 i- t! \$ q  W% e0 Y
8 {  O$ G/ Z+ Q4 e) F/ G
点击“Add Files”将新建的.c文件加入到对应的文件夹下。
1 b9 j, F: m6 P6 b9 [3 O+ i7 P
4 ~: Z3 d# Y$ C7 B( l  ^- {& A/ o# R
微信图片_20231023151016.png

' f8 o. p5 B; Q& Z* W
添加.c文件

5 d$ S; v' J6 }0 X. e
# y& r( v1 q  S
% ]3 p. m) c# p8 V+ c
对于.h文件,点击魔术棒,选择“C/C++”,点击三个小点选择对应文件夹即可。
( t. R9 T/ Z$ h; Z: @* X. {7 l7 w: c9 D/ x5 L: p$ M' y

2 k; m; Z  |% J1 Q* ?# C5 Z5 t
微信图片_20231023151013.png

  m# G' ^0 n4 ?! S  ?9 s  t
添加.h文件
6 B, R+ n( D$ o; m0 ]- H

9 C3 l- S+ w7 o( q- G8 {

' l/ W) O! w: f# z: M六、ST-Link调试
2 s) R- T: i. x7 f9 {, e在开发过程中学会使用Debug调试,能够帮助我们更快地定位问题。这里简单介绍一下利用ST-Link和普中核心板Debug调试方法。# Q/ m/ I+ H  k7 S4 ?+ j

5 j: S% k3 i9 K5 P
. Q1 o. A" Y1 L: n9 O
6.1 硬件连接
" {$ \1 |; v/ }首先将ST-Link与核心板连接起来,ST-Link的引脚如下
" O- u, B7 x! q) S5 a% o" C" c; N) J  p% k7 G; x& y

  `* _6 ^' U1 T! W
微信图片_20231023151010.png
  D" X! r' w% _' ^$ `# U" Q7 B
ST-Link引脚
& h+ S4 W1 B# l0 m
( }5 p" |% V& l1 ]0 ?- n4 J

+ P* d/ J  @4 D/ b/ N& Y核心板上并没有给ST-Link预留单独的接口,而是跟JTAG一起。9 a' C4 x3 Z6 e7 L0 C9 ]
2 ?' m$ L) J& O7 e- F

4 o7 @/ A& Z* {) A其原理图和硬件图如下
6 G) I8 t' m7 ^$ C; ^. w% k& w' _2 F9 e9 E

6 j& I, P& J4 s) s+ j0 D
微信图片_20231023151007.png
2 i3 {! x0 g6 [# k6 H& c
7 |4 N; G. s  m9 r5 `$ Z4 p- u
JTAG原理图
4 Z, M2 m5 }* j& r6 l2 N# z5 t% ~- i/ E$ A
微信图片_20231023152058.png

6 T9 s0 `! W0 ~$ ^
JTAG硬件图
/ z; e9 y+ \# `$ [: H
9 p" f" Z& k: W  j! D! T7 n4 G1 T3 z
- r$ s6 t0 b$ S4 E3 N1 Z1 ~
由原理图可知,ST-Link的“SWCLK”连接核心板的“JTCK”,“SWDIO”连接核心板的“JTMS”,“RST”接“RESET”。
  Y" k, T3 D; k8 P: t/ n6 ?
- [  J) W6 D! O. o$ G

) u" y+ q7 Q" Y# S2 T. b6 G0 h& ZVCC不要接,接好ST-Link后再单独给核心板供电。% ~) v) n9 ~8 G2 o: ~; D
. z; ~2 ^- F) F  i, e7 |
& H2 v9 v: I: p- V7 @# E, p& \" I
6.2 Keil配置0 V0 W: R; R: j3 `8 K, K
硬件连接好后开始配置Keil5,关于ST-Link驱动的安装这里就不再做介绍了。& ^5 L+ l: F; |" n) G

, V$ u, I* k; B& R  T! t3 F
$ e# w# ]' T3 z6 M1 F- ?
• 首先确定ST-Link驱动是否正常0 x3 }, A5 Y- ?. Q7 s
" `8 U; o: u& s, ]3 s

  B2 }2 a# \! N. u
微信图片_20231023151004.png
8 p( W3 v3 d8 y: ~4 F- `8 R( y
确认ST-Link驱动是否安装正常
) Z+ t9 a. i7 n; i9 M* R+ W  W
; N% G  I8 w& O: |
5 k  z2 q' [4 L5 _6 E( [. l
• 配置Debug 点击魔术棒,选择Debug,下图处选择“ST-Link Debugger”。
3 K: Y+ o# r0 J% L# J) B2 a4 g* ^& S+ {1 v% k1 n  }" ?+ o& Q4 w" r
- H+ ]- O$ n, g& ]% _+ U
微信图片_20231023151001.png

3 O- S  l! e. f
Debug配置

% N! Y9 E# I' q5 j. n, _6 m2 A) @
" ]* r/ f3 g7 O7 ?; a% z8 i
! D& j8 z6 T/ K/ j
然后再点击“Settings”,在“SWIO”右侧不显示“no target connected”就说明ST-Link连接正常。点击“Flash Download”' k( d+ }! J. O7 F
8 d& N2 o" U$ ?/ Z# E

+ Y0 j6 z9 D% g- H% B) C. [
微信图片_20231023150958.png

6 n! B. m7 E0 W; m7 k7 M
Flash Download
$ i6 x2 H$ K9 b- k# a
' o$ e1 T3 m4 G8 |
0 |9 K1 |5 d4 G
按照图示配置,“Programming Algorithm”只要选择符合芯片型号的即可,需要注意的是,只能保留一个。
% S/ q* n$ |8 c  s% l3 F( t! o2 Y. Q$ M+ ]1 n% F$ j+ @
. e6 t6 ^' |' w: k- K3 k- E0 c9 D
微信图片_20231023150955.png
+ d. m' ?7 z. l7 m9 d# q# b8 W
Flash Download配置

5 i+ }( j* q* }1 W  s; j& C4 R# P1 S% V4 [, b

. I- N' e/ ~- A0 O) f按照下图配置“Utilities”。: w. D! _7 o/ C# j

0 P9 X0 |- J; t) c% r- r
- w& ], S3 p" O* n' u7 b
微信图片_20231023150951.png
0 C5 f) I# v+ E, Q7 u
配置Utilities
. T7 J: B( P& _1 H. v
* ?* f- L6 R2 y  K& C7 [. v) j; t

8 S1 Z' v9 m& Q# w5 \" l至此,Keil5关于ST-Link的内容配置完成,如果小伙伴遇到其他问题,可以多去看一些大佬们的博客。% L, F7 D) x6 O7 g0 }
8 K% Z% W$ U1 d' C

8 n5 ]0 v" W" E6 ?& C5 R6.3 下载调试
$ b8 _* A5 x, H配置完上面的内容后就可以使用ST-Link进行下载调试了。下载的话比较简单,编译完成后直接点击下图标注的图标,等到下载完成即可。( C2 s2 R6 s) C2 [& d3 Y
/ K2 }! p+ [$ z2 @' Y

6 F0 F. ]- S2 U4 j" A
微信图片_20231023150944.png
* E+ O& W; }, X) `0 l
下载程序
  w& d7 k% c' y7 W" n

9 d& Y4 s5 P# g5 O* ~
, B: F" h* R$ v" q
调试时点击下图所示按钮,进入Debug调试。
2 r1 M# f- m: C! `/ H; w, I( Z9 w4 k, v1 X% A- Z$ k* o/ T
4 B- e( T9 `7 Q. `  o0 f  E+ R
微信图片_20231023150941.png
$ n9 T" K: X0 p
调试按钮
( l& ^3 ~" E- @4 F+ c7 h
1 D! a2 }! P! |3 U  n. q

  A6 N  `5 `- a/ K下面简单介绍一下调试窗口中各个按钮的作用,其他更加详细的介绍需要小伙伴自行搜索,这里参考了这篇大佬的文章KEIL5中Debug调试。
3 e4 f' O8 Q5 @8 b
% q- W: \% u$ {: E% }

5 t, i- A& ?5 i: X! E6 [  R$ O9 N
微信图片_20231023150937.png

4 T9 W3 b" }5 v; E. g- u1 g
调试窗口按钮含义
; R9 k4 v- Z5 \+ Z

) t8 D! U9 q( `' j/ X2 G

1 {& ~) m7 n" U# ]- z. L第一部分从左到右7 ]1 o* i) N0 M
• 复位$ x# P( T1 b' I) L$ \
• 全速运行
' {( `7 e; A" K# h2 A• 停止
# `/ q2 Z0 S! j- R• 每点一次运行一行,遇到函数体会进入8 Z: h+ B( v0 M5 X! s+ M2 Z9 C$ J
• 每点一次运行一行,遇到函数体不进入,直接执行完到下一行& t: _, ?, n1 H, a
• 快速执行当前函数剩余语句,然后跳出该函数体,准备执行下一条$ C  `" g$ J! a$ @* B7 R3 K
• 直接运行到光标处2 j1 p/ f6 y6 H0 }8 t# c
- o9 `3 r. X; A! _. u

% M' y4 |% x& R2 u8 _! V$ ?0 ]6 c第二部分从左到右! x- H$ l* F7 e
• 设置当前光标处为断点
( g! f8 o* M7 e- }8 @! d+ k) h• 失能当前光标处断点; T9 z; F0 H- s, R6 k9 f
• 失能全部断点# h2 d, ?% ~! [; J* t/ |
• 删除全部断点
; E" Y7 U) I/ q" ~0 S  y
! ]* T8 D6 e. G( n: h7 U7 s

# _0 ?+ R3 _; Q  K" q6 M打断点的方法比较简单,直接在想要打断点的一行左侧点击一下,出现一个红点就表示已经添加了断点。断点的作用是能够让程序运行到断点处停止,有助于我们分析函数运行方式以及变量的变化。2 w1 A) [4 K6 H

( o$ ]2 N, }( J( {2 l

7 N; P2 R. t9 c9 W
微信图片_20231023150933.png

3 A( w% I- Z, l8 G8 o/ a# ^$ u
断点示意图

, J6 c4 c8 l# V* z' k1 e, u1 z) f2 }# {2 P
5 p+ f1 }0 t. _7 e; J+ [
调试时可以查看某一个变量的值。选中想要查看的变量,右键8 P+ i, @9 ^" W) ?# T4 x
% d# |- Y8 `% i8 o! F9 v

# L, f( E* x( {# i% o) L& P
微信图片_20231023150929.png
6 o# @, E! C- z2 Z- F
查看变量值

3 _, w6 _0 t+ t2 \0 a
7 W* y* N, V  B
9 Z. p: ~$ Q; c4 M
此时就会出现一个窗口,能够查看该变量的值。
4 p* E4 l) n3 {1 ?' C- \1 P3 R% _+ N4 A' x- B( v
7 D9 {$ ]# J8 L! `: j9 [
微信图片_20231023150924.png
9 v& j6 _, I- p! _
查看变量值

$ z# I: ^' [- w# H' H9 ~$ }& J. T转载自: 二土电子
( O& P$ m3 Q  m8 B0 @+ Q: D* S0 q, }如有侵权请联系删除+ Q; r7 [1 G. A+ @" u/ |) d
- ^1 x# k7 g( @0 D- }: a  q
收藏 评论0 发布时间:2023-10-23 15:12

举报

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