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

基于STM32F1的CAN通信之概述

[复制链接]
攻城狮Melo 发布时间:2023-10-23 15:12
一、专栏简介+ P# I  R5 w  `4 F9 f: _: ?
本专栏介绍如何利用库函数进行STM32单片机开发,主要针对的单片机型号为STM32F103ZET6。总结来说,“速成”体现在以下方面  j; S+ X; V3 x
• 在讲述基础知识后会有相应的实例或者模板程序
! y  x! Z+ v) l7 T2 Y* n7 F' g9 a6 A• 学习完后会有小项目练习
, x9 \9 P" k) B% J( a6 v/ T• 专栏基础知识部分内容精简,对于“速成”选手更加友好4 U" P; E; s  e# z- P2 t2 c

4 Z' W. o4 A4 _/ J2 [0 b
! g% m, ^$ e3 x# [
其次专栏还有以下内容4 j- J6 s4 o6 j- |
• 简单介绍编程规范和程序架构
8 L. [* q. Y% E; ^7 f3 @4 j. k/ k• 专栏不断更新一些外设的使用方法并提供例程5 H) c( t# a$ Q/ p9 u

! B( @, v. ~6 a( u# n, P" k9 x8 M

- e# U; x. o$ h- n9 x1 L" @6 E1 z9 u二、前期准备- u5 K. C; t& s, a, G( ~
前期准备主要有物品以及相关软件的准备。首先是物品,单片机选用的是普中科技的一款核心板,主控芯片为STM32F102ZET6,是下面的样子( t. Z( |/ {" _$ l. {
微信图片_20231023151024.jpg
' X. S$ e" w$ T+ k
STM32F103ZET6

; _$ s. L$ ]& b8 t) i6 H6 @* m$ o# `. L9 K

; [' a7 o: S6 G2 O$ Y图片上是带有LCD屏幕排母的,有一种是不带的,因为本人开发时经常使用LCD,所以买了带排母的,在某宝和聚诚科技购买的,不带彩屏169RMB。学习过程中除了单片机以外还需要购买调试器,ST-LINK,用来下载程序和调试。USB转TTL(可以直接搜索TTL),用来做串口通信时使用,也可以用来下载程序,但是不可以调试。对于前期学习来讲,这些物品就足够啦。$ ~# E5 |& O$ \" z8 r; J6 Y3 M
6 j7 s* G1 F8 h, A& A, V
/ h, Y3 ~# W4 `' \' p
除了物品之外还需要提前准备一些软件和驱动。比如Keil5,CH340(串口驱动),ST-LINK的驱动,这些都是需要安装的。其他的类似于下载软件,串口调试助手都是不需要安装的,本人用的是普中科技提供的一些常用辅助开发软件,小伙伴们可以自己动手找一下,没有找到的话私信留一下邮箱,注明需要常用辅助开发软件,后续会邮件发送。
9 k( l" X% B/ C- o9 N
' c4 s5 O' E0 Z% z' L
# H# E/ m0 C, T. K' S
三、编程规范以及程序架构简介
& b2 R, Q* F6 c' m$ ~4 T  c9 c1. 编程规范. b0 x/ L# H, L* ]9 J
对于新手来讲,编程规范以及代码架构也非常重要,有一个良好的编程规范和代码架构,可以提高开发效率,方便问题排查以及后续的程序维护。这里介绍的编程规范很简单,要求不严格。主要有以下几点
" C( a1 |% b# E6 |  ?5 E0 t
! u; x0 F+ w- ~1 [

2 h  W/ P4 d. F  U! i1 ^• 变量定义 变量定义时最好是能够体现该变量所属的外设模块,该变量是否为全局变量,静态变量或者指针变量。变量首字母小写,后面的单词首字母大写。举例如下
! m8 |/ Z1 ~* Y) K6 r* h! r" f
! t8 F# J3 {1 W3 @& j
$ ~7 f  j. o# x! B9 G7 K- {) g
  1. // 以ADC模块为例,需要定义一个存储AD值的变量,举例说明变量命名方式! D5 q& j/ i: e/ f: v$ n

  2. 5 ~% e" k2 t7 Q4 M) k
  3. // 局部变量
    . n: U! s" J. r$ M
  4. u32 adValue = 0;
    % w7 F/ Q* V3 c9 b
  5. , ^2 A" G9 ]6 |- Y* U
  6. // 全局变量7 Z. x5 A& ]- z
  7. u32 gAdcAdValue = 0;   // 加一个g表示是全局变量
    # P  s6 Q% V0 A3 Z3 R, B
  8. ; P# g$ H4 v/ x9 a" o
  9. // 全局静态变量. I! R, I6 O7 \' _) s  @/ r+ A$ z' ?/ H
  10. static u32 gsAdcAdValue = 0;   // 加一个s表示静态变量
    # q* w6 \4 z4 k+ u3 d

  11. ( ]' ]& b  b* j* g* }  d3 J
  12. // 指针变量
    7 E6 w8 t; [5 C4 ~- \
  13. u32 *gpAdcAdValue = (u32*)0x2000800;   // 加一个p表示为指针变量
复制代码
) y* y- \3 b7 o0 S, N  ^; u
  H1 E. I9 R! @. L
• 注释 函数注释举例如下
. p( W+ ?( T& j/ R3 B# Q' X
  1. /*
    : N* P% F' H; _$ V4 [; l2 k* `
  2. *==============================================================================
    + a6 d2 F; \. n1 Q& q( t4 p
  3. *函数名称:
    $ h8 }/ C7 s" q" `; K/ x
  4. *函数功能:
    % }/ g3 e5 Y1 }: L2 l/ e3 d  U
  5. *输入参数:
    $ \; n3 T  @' d# r  H8 ?1 X
  6. *返回值:无$ s1 r$ l" k$ c
  7. *==============================================================================
    $ p  U/ ~  z/ W
  8. */
复制代码

9 Q* h" P4 @  f+ b3 c$ o; w9 p
, \* o6 Y* B' K7 X对于程序语句注释,如果过长可以在程序上方加注释,如果不是很长可以在程序语句后面空三格输入注释。5 V9 \( O) [- _& i' p, x: W
2 W9 o1 Y' M& j5 @- s

) o) X: ^8 W1 A6 W0 g• 函数命名 函数命名要体现函数所属的层级以及函数的功能,关于层级会在代码架构的部分详细说明,这里只说一下函数命名方式。
7 J. \1 K6 \/ d6 a; u
  1. // 这里以ADC模块的读取AD值函数为例,说明函数命名方式
    ( h. f+ B& ?: m; M% T* {
  2. void Med_Adc_ReadAdValue (void)1 v" l/ f+ ?% m; \$ e- O( D1 [, L
  3. {
    % ]) d& p! R1 p" d
  4.     // 函数内容6 \% K. l5 \. B
  5. }
复制代码

% ^( _3 N$ J# h3 W# W0 g% |- N
( r) O4 s9 H8 C# W) O7 [% `这里med指示该函数位于功能层,属于ADC模块,作用是读取AD值。
# ?, c4 W7 w6 Z- `1 z; I+ Y
6 ^, S/ B- h. J  j+ z4 p

7 D, y* i! Q. A: ~6 a5 K$ J- P0 J• if,while等语句的使用 使用if或者while等语句时,需要在括号前面加一个空格,如下5 _2 v& f5 D- K8 h1 l
  1. if (gAdcAdValue == 0), X3 @7 b4 C5 e0 S
  2. {
    + t& E4 @. j' x% v# U
  3.     // 程序语句7 I0 J+ k+ A' v8 l, R; a8 Y) o
  4. }
复制代码

' R5 E0 t9 s1 f3 t! Q
) o, H2 D8 \5 I8 t# _9 d• 四则运算 四则运算符号前后需要加空格,包括等于号等符号。如下
# C2 H, s2 R, e* S
  1. c = a * b;
复制代码
9 w' [. ]2 f/ C) F) _$ c; n

, H, d: S) `% w( l! w2. 程序架构% |4 f' P# G' n6 t4 e0 z4 Y
该程序架构是本人在工作期间学习的,个人感觉还是有助于提高开发效率,方便后续维护的。主要思想是将一个模块的程序分成三部分,每一部分是一个新建的文件夹,下面都是其他模块相同层级的文件。
5 V* X. P  O, S" n7 w% Y9 U/ _
) X& u+ F* q# @2 C
# _+ z! m6 m; w/ q# [
• Drv 驱动层 该层主要是写一些模块的初始化程序,例如GPIO的初始化,ADC的初始化等。- {+ W' @6 Q: V& w4 s
• Med 功能层 该层主要是完成一些功能性的操作,比如读取AD值,点亮LED等。Med层的函数可以包含Drv层的函数。
- \1 y8 U9 W8 @+ d2 G9 W• App 业务层 该层主要是完成一些业务,比如在点亮LED的基础上实现流水灯,比如显示电压值等。' s7 `. Y# |- O1 {

5 S) S. M# Q  _; ]% K

9 u& t5 m/ ?. \四、STM32F103ZET6简介/ p. n. h& [, A1 X% N
STM32F103ZET6是由意法半导体(ST)生产的一款单片机,32指32位。STM32也可以成为32位微处理器。STM32F103ZET6的主时钟频率为72MHz,512KB的FLASH,64KB的SRAM。常用到的有GPIO,中断,ADC,TMR,UART,DMA等。1 V6 b! s1 h9 }5 V# F4 n/ r. K
1 s1 v. D" n2 V' ?; f: l& |

" }( X0 U+ q! ?, J0 ]" J! F五、程序模板! o* b# V- A2 g7 Z( j$ P
在使用Keil5编程时,针对一个外设需要新建对应的.c和.h文件。这里以LED模块为例,简单介绍一下本人的常用模板
7 w  \# N! l0 _& @! L2 Y  Y3 ?4 \( p5 j' l* `$ A( Q# D

) q- s8 l) ]0 `- C5 [2 D.c文件
! X2 ^2 |  L( [" q
  1. #include "LED.h"   // LED头文件
复制代码

, ?% y0 M5 k, _, \) t8 I. k; y' ^  B7 j* }- t( w! l" X$ P* F" s
需要注意的是一定要空出来一格,否则编译会报警告。
; k2 I1 L- k7 i1 i) s5 l* J) [3 T$ l1 W6 B( e6 f
% _8 f+ N0 w# h2 P8 r2 Z% ^
微信图片_20231023151019.png
: ]7 N' V9 Q% h+ z
文件最后未空一行的警告
& s" w3 ]' M4 e7 m( B- d
.h文件
: b! S' W5 p1 u  Z) t6 a
  1. #ifndef _LED_H
    / q' |) Y# _& _0 O; f
  2. #define _LED_H
      K* O6 y" @7 k6 h

  3. 0 {2 I7 r( l' o! B5 B( G
  4. #include "sys.h"   // STM32库文件
    6 E8 s  u# U* |6 Y
  5. # B) h  a2 B* o& [
  6. #endif
复制代码
! K6 @  N, r# x2 e) o
5 k0 O# f; |+ o2 f
.h文件最后也要空出一行,否则也会有警告。
- [, M0 s6 a3 B; D- g" \0 \! d4 U% Y* V% u, H: e7 F

7 l# `7 g- s9 ]2 s) i7 F新建完之后需要将这两个文件添加到工程中。0 a5 _1 A; d* e
( B) Y( v' B# p8 X, U) M
  b. m: O( R  m4 o+ A2 U4 ]  ^4 _
对于.c文件,右键工程文件夹,选择“Manage Project Items”打开。
, {5 ~; p! u( a- [. ^" }1 Q2 w1 p$ A- ?) ~7 a9 r' d
$ L0 x' W$ c: S! |) R
点击“Add Files”将新建的.c文件加入到对应的文件夹下。8 @% L  [% i# D5 A7 S! S

* m6 n  q- C- j& }) G/ f2 e6 J

  W% L% j0 o% e+ b$ q
微信图片_20231023151016.png
, I% A# s8 V8 q) L8 c& a4 _
添加.c文件

5 k5 j1 U; ~# N5 W' o, S/ V6 z# r# U6 S

$ y& V, {5 `- n: M对于.h文件,点击魔术棒,选择“C/C++”,点击三个小点选择对应文件夹即可。" c/ h( C- [8 ]; C

& n6 V" q7 ~3 d7 A* z% K

0 W6 ~# u/ q* w( |
微信图片_20231023151013.png
9 n7 \* |! A3 f( y, M
添加.h文件
5 N# ], l& S' |& e
2 c8 N* v9 k  M, j
" Q& r1 c, i& f- M
六、ST-Link调试# @& l3 z: P7 d. I7 i+ E
在开发过程中学会使用Debug调试,能够帮助我们更快地定位问题。这里简单介绍一下利用ST-Link和普中核心板Debug调试方法。
. C! V4 E9 _- P: E; y7 |: u) w7 ~( P3 x3 p+ l! v
3 |5 t/ R" a% K
6.1 硬件连接( L" C+ B* I8 A
首先将ST-Link与核心板连接起来,ST-Link的引脚如下8 C- t4 _" x' ]6 y" Z* _8 H
/ _% h2 h- I6 G
. M/ [1 Q7 m2 @1 `0 P
微信图片_20231023151010.png
7 ]$ V4 E% |: v% i
ST-Link引脚
0 @, j. i# [# e

, Y/ D$ c/ k( Z4 G; L1 ]: D5 w! s

5 a) K" n6 s/ f; K% i# O核心板上并没有给ST-Link预留单独的接口,而是跟JTAG一起。
9 e! {6 Z% W# O) b0 @9 T$ v) b# d: Q3 C' `4 T3 }4 @+ `, o

0 R* z3 h$ A( v3 s- A其原理图和硬件图如下& L' Q- {! Y! y( e
9 O0 j) u& |% q% }" |- _( X
3 Q3 U; j. ~0 J# t
微信图片_20231023151007.png
5 E: r! n' \- z' Z

  C$ J# J- U5 ]+ H7 |1 PJTAG原理图+ t$ r. o; S8 a( q
6 W5 V* _5 c2 Y3 _3 A
微信图片_20231023152058.png

! m! E- A: i" S; f. ^- f- \
JTAG硬件图

! W7 S0 _1 e& u" [( x  w% _! x8 O

: Y% i2 U- f6 b5 L) F  S由原理图可知,ST-Link的“SWCLK”连接核心板的“JTCK”,“SWDIO”连接核心板的“JTMS”,“RST”接“RESET”。
- c3 _9 b/ X9 @% G) O" e
$ [  ^3 \  {( Q/ U) N; d. Y7 ~. U' D
4 I) R* c. c' e. T6 X9 g! J
VCC不要接,接好ST-Link后再单独给核心板供电。' f  j3 U7 u; F$ N; R7 c" r
5 i' E" m% i7 E; l
* O0 ?7 s5 ~4 R4 o2 G/ f/ k' n
6.2 Keil配置
  p4 I: z" Y  r, E/ J3 h- {硬件连接好后开始配置Keil5,关于ST-Link驱动的安装这里就不再做介绍了。. u/ e1 h3 D: u- A" U- [. N

( s4 `: d7 r3 v1 h4 A. D/ g

. J( v' N% I( w% y. i" ]3 W4 K4 p• 首先确定ST-Link驱动是否正常$ H- o5 H, a% G4 n) V
2 v5 C4 H9 W# `
! g8 m1 H& N+ u- Q$ h6 d
微信图片_20231023151004.png

+ b. P5 n' j5 N4 b! a! B( R2 j
确认ST-Link驱动是否安装正常
+ k& s* I1 P0 P
* Q* d" |) c! G, d9 p1 }2 E

. f& j  ]0 G- E9 F3 E% z• 配置Debug 点击魔术棒,选择Debug,下图处选择“ST-Link Debugger”。, k% m* S( G+ K6 `8 k5 F- e
( E1 ~( ?7 j1 G6 G& D
8 F+ |. d8 S+ N& B6 G4 z! L" w' Q
微信图片_20231023151001.png

2 d1 J- I  e% d' d. l# t' n  r5 u
Debug配置
: o" O% W3 M; c
: c. {7 b( m0 A, F. P

) D- w; e! I/ o6 A8 d+ m然后再点击“Settings”,在“SWIO”右侧不显示“no target connected”就说明ST-Link连接正常。点击“Flash Download”2 ]: F4 ~1 V9 o- E: h

4 F" {/ u) h) e/ o: S+ A

. J( i8 k" {4 [5 \! O! W
微信图片_20231023150958.png
# ?$ {* ], z3 v* T* U2 o
Flash Download

& l. y! @6 j, o* y! c1 H, O5 u/ O0 g" w& X
& N8 q$ T: G6 H0 W& A
按照图示配置,“Programming Algorithm”只要选择符合芯片型号的即可,需要注意的是,只能保留一个。. O/ H9 r' Z& E" t1 H
# q6 K0 S3 \% r. q* D" E
3 W% [: N, J8 X) T- c* J) ~, _
微信图片_20231023150955.png
# S0 u+ z7 i% \
Flash Download配置
7 j1 i: |1 q: r$ {) C  w) ?

' m: B5 @8 B, u
+ k2 N, k( T8 x5 G; k
按照下图配置“Utilities”。
5 X# L7 B$ d" B4 p4 X% H. L5 V' T" r" N7 y0 {. r2 K
- |  c; Z- q+ {$ q  T/ m
微信图片_20231023150951.png

# W! C* d+ z" i( n" H
配置Utilities
- ]6 S4 Q) j+ Z! F
: g* Z8 R0 x) O" R

2 f  H* Y! e2 J  t* ~. l4 k1 T8 W至此,Keil5关于ST-Link的内容配置完成,如果小伙伴遇到其他问题,可以多去看一些大佬们的博客。/ b4 f2 K+ @. e
6 Y9 l) B! _5 F" q7 B# X

! \% G6 @  s& p4 B7 A+ u8 k0 r6.3 下载调试
& [- F. _! }4 ^" a配置完上面的内容后就可以使用ST-Link进行下载调试了。下载的话比较简单,编译完成后直接点击下图标注的图标,等到下载完成即可。
5 P9 Z: U9 }3 j2 A0 G5 p
6 K6 {1 b( J) W: j

6 q3 A& ^2 F+ O( Y6 m( B! j
微信图片_20231023150944.png
0 j; @- g% [) \% D+ I- j& e
下载程序

% `8 R7 z$ }! m- D1 B
5 L( O# B  |3 y# i2 ^  o

4 {- L& u+ ~( T  J! A& K调试时点击下图所示按钮,进入Debug调试。; d/ l: i( N- |  e9 B1 j6 Q3 ^
+ m4 q' y' j$ |
. P9 a0 }6 M3 v& U3 A
微信图片_20231023150941.png

* a0 C: h6 V/ l! t6 g
调试按钮

. ?- A, m0 O$ I, b+ ?- [  s
; K$ k9 {  h( A$ U2 k4 T3 z
" |# b8 p9 P5 k" ^9 x
下面简单介绍一下调试窗口中各个按钮的作用,其他更加详细的介绍需要小伙伴自行搜索,这里参考了这篇大佬的文章KEIL5中Debug调试。
7 h  a' T) D" r) _  d
& f: U1 F6 n. {+ }, d0 E
; S: X; i& t5 l5 a- D. j( Q$ v# y
微信图片_20231023150937.png
# \$ D8 L& P* D, Q0 o* K; J, s9 Y
调试窗口按钮含义

) y; g' a$ G; d. ~* S2 `+ ~0 M9 Q: O1 v

3 Z" E( o) u  s2 y; s$ B第一部分从左到右
" m9 Y1 \8 R6 @) @1 s/ a6 D• 复位
! h# ^; C9 u  H# i4 s9 t• 全速运行
& \8 f$ {( r+ C; U' J. ?' d$ W• 停止
, Z5 O" t1 G8 d: |• 每点一次运行一行,遇到函数体会进入( v( ~, _& D  M6 h5 e' N; ^8 l/ K
• 每点一次运行一行,遇到函数体不进入,直接执行完到下一行) e  ]2 U+ [, A" n7 |: G6 t
• 快速执行当前函数剩余语句,然后跳出该函数体,准备执行下一条
! D/ S5 u1 v. Y, E- Z• 直接运行到光标处
1 b9 W7 X0 `# O4 v% f, t6 p( i5 m2 ~0 a

6 N9 r4 A! C7 M5 n! b* s' W第二部分从左到右- D- w  S% b% h# |3 J) E0 V
• 设置当前光标处为断点
1 n) u5 n# v. ]; }0 s• 失能当前光标处断点
$ L9 G' u/ i) x• 失能全部断点5 r% h6 i& B$ {/ p+ T
• 删除全部断点
6 `+ g" V6 x; B
) \) @; Q' B5 f* R9 `

% w) E4 A" H% ]4 ~4 g9 x打断点的方法比较简单,直接在想要打断点的一行左侧点击一下,出现一个红点就表示已经添加了断点。断点的作用是能够让程序运行到断点处停止,有助于我们分析函数运行方式以及变量的变化。
0 V# e+ k- o) s2 P6 e
  `: o" O# V. b! H
! V! r* X7 B2 V4 @* p! Z
微信图片_20231023150933.png
6 \- H7 v9 c# S$ E6 ]
断点示意图

) B4 z* Q7 L: c! l
; u% H! ], y9 p  P( k
0 N: d1 M; k; y# f% }* P5 s% J
调试时可以查看某一个变量的值。选中想要查看的变量,右键' C( w. W: @" n  i, d6 ^! ^. T
$ z9 }/ X$ N3 w& M

* m" Y" ~3 K  ~' f9 I2 u
微信图片_20231023150929.png

2 Q9 c+ b: ^: D3 j" R; I, C; T# q
查看变量值

) l4 r+ o" Y4 Y
7 b$ q+ Y: p+ i9 j5 v. W3 u7 B# E

' E5 z) r6 @& u. d, v: Z- `: P7 Q此时就会出现一个窗口,能够查看该变量的值。. k' i/ c# H/ T' A2 N5 d
" l$ O' I& N- F5 G) F' [  B+ j8 M  D
& Q  v) b5 `2 {1 H$ }- Z: u/ s5 Q
微信图片_20231023150924.png

4 ]* i* m' e. T. w  J0 y3 R  G
查看变量值

4 w; J' {: E+ E# D0 d1 s9 I转载自: 二土电子& h# C) ?' O! n4 i6 c6 v
如有侵权请联系删除; ~* G$ `* |# a5 B

: D+ R0 u2 _% }5 o! Y
赞 收藏 评论0 发布时间:2023-10-23 15:12

举报

0个回答

所属标签

相似技术帖

官网相关资源

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