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

基于STM32F1的CAN通信之概述

[复制链接]
攻城狮Melo 发布时间:2023-10-23 15:12
一、专栏简介
- Y' W/ X2 k: l" w- U9 S本专栏介绍如何利用库函数进行STM32单片机开发,主要针对的单片机型号为STM32F103ZET6。总结来说,“速成”体现在以下方面
' V  ?9 S' [! ]/ t• 在讲述基础知识后会有相应的实例或者模板程序3 x- g( k# Z4 Q8 R/ E5 a9 H
• 学习完后会有小项目练习5 P$ M) Y6 v* u/ K) O0 ^
• 专栏基础知识部分内容精简,对于“速成”选手更加友好
. P9 C' v% B" Y5 d
- c! N; ?3 i  x; }: C
: A* T8 M' \5 i- Q) H; c
其次专栏还有以下内容7 E; M* m6 S! L
• 简单介绍编程规范和程序架构
+ f& H- r4 G! Y+ v/ z. i• 专栏不断更新一些外设的使用方法并提供例程
% S4 t) G8 n. [& k# r4 J- f( ^, a7 n
9 M; @) c$ G, u2 Z0 {( Z* {
二、前期准备
! t; T  A1 @* o# x( K+ ]/ I- E( Z- p$ `前期准备主要有物品以及相关软件的准备。首先是物品,单片机选用的是普中科技的一款核心板,主控芯片为STM32F102ZET6,是下面的样子
0 [. X' P1 b1 ]% Z: S
微信图片_20231023151024.jpg
% N/ [( O) g8 w
STM32F103ZET6
- u$ T2 f; [. q3 E

5 M+ x/ r! t# E+ x; M* R# Y$ O$ e
  @+ P! T. _$ Z7 F, j- m" h, ~
图片上是带有LCD屏幕排母的,有一种是不带的,因为本人开发时经常使用LCD,所以买了带排母的,在某宝和聚诚科技购买的,不带彩屏169RMB。学习过程中除了单片机以外还需要购买调试器,ST-LINK,用来下载程序和调试。USB转TTL(可以直接搜索TTL),用来做串口通信时使用,也可以用来下载程序,但是不可以调试。对于前期学习来讲,这些物品就足够啦。0 c) ?6 U1 z3 b

0 v" |/ f% h( `9 ]1 \% G

, {+ G# t5 w7 l6 H: Y除了物品之外还需要提前准备一些软件和驱动。比如Keil5,CH340(串口驱动),ST-LINK的驱动,这些都是需要安装的。其他的类似于下载软件,串口调试助手都是不需要安装的,本人用的是普中科技提供的一些常用辅助开发软件,小伙伴们可以自己动手找一下,没有找到的话私信留一下邮箱,注明需要常用辅助开发软件,后续会邮件发送。# B6 X2 Q3 s$ y! @  ^

2 E$ r3 u5 S" I1 D; L3 a
: E9 A! a3 l4 E, l& O" [
三、编程规范以及程序架构简介
! Y; `" q1 K6 f* e1. 编程规范/ x1 {# C& A) r' t- {; e5 q
对于新手来讲,编程规范以及代码架构也非常重要,有一个良好的编程规范和代码架构,可以提高开发效率,方便问题排查以及后续的程序维护。这里介绍的编程规范很简单,要求不严格。主要有以下几点5 S) A# ?! Y; w( T& ~3 b" s4 C
8 y1 [+ d$ A- a: R) W& d0 U
! S7 R& y) P; }1 q
• 变量定义 变量定义时最好是能够体现该变量所属的外设模块,该变量是否为全局变量,静态变量或者指针变量。变量首字母小写,后面的单词首字母大写。举例如下
! r. N1 f+ Q6 R" G3 _+ ]" Q" J1 l! i% B- W0 O

6 z' ?8 e( R+ X6 _! W+ I
  1. // 以ADC模块为例,需要定义一个存储AD值的变量,举例说明变量命名方式
    * n% n, g* M6 e0 t

  2. 6 F) q0 a) r2 }% B0 p% y$ o& W
  3. // 局部变量
    6 x4 A* Z8 x% Z! U
  4. u32 adValue = 0;  D. W9 R2 j! f8 a/ e9 o, I9 T
  5. 6 }% k- X9 q/ S/ Y
  6. // 全局变量' t* t% V. n0 W+ I3 G
  7. u32 gAdcAdValue = 0;   // 加一个g表示是全局变量) e/ G$ _5 E! Q; d. S- m! P7 O

  8. - Q2 O* b1 \# t
  9. // 全局静态变量0 `& o; r/ {# [+ X3 D! ?4 H
  10. static u32 gsAdcAdValue = 0;   // 加一个s表示静态变量
      @2 _; N5 T9 J5 y/ N
  11. ; X% G9 P1 w9 @
  12. // 指针变量9 ^9 f$ s# E4 ]" O3 x7 k% X
  13. u32 *gpAdcAdValue = (u32*)0x2000800;   // 加一个p表示为指针变量
复制代码
7 p( W/ {# S: g$ T: m

4 M' N+ n2 S& F( [. O• 注释 函数注释举例如下9 }6 O9 Z+ N- ?# X) W3 K/ Q
  1. /*3 b% V2 ^& C! o% m" n
  2. *==============================================================================; a. ]# n! j) O/ C4 i& V
  3. *函数名称:
    : E, x* ^/ t- V& X
  4. *函数功能:1 Q' m3 r8 t' V! o7 V1 N* Q
  5. *输入参数:
      T3 I) A2 B4 `6 q, V6 c
  6. *返回值:无
    1 o$ T, v9 V+ x
  7. *==============================================================================
    $ b7 ]/ U# H: m, s: Y# \
  8. */
复制代码

% L! l+ E4 \7 S& g! d2 Q$ P( b" t, R6 ]( F
对于程序语句注释,如果过长可以在程序上方加注释,如果不是很长可以在程序语句后面空三格输入注释。' Z  h( h/ @2 n9 s: c# v
  u& }  E$ `2 z1 n' G

6 V* Z- D5 U/ U, X! Z4 B1 f# r• 函数命名 函数命名要体现函数所属的层级以及函数的功能,关于层级会在代码架构的部分详细说明,这里只说一下函数命名方式。9 O: B" U& t. _4 {" G* C1 I" Z% R
  1. // 这里以ADC模块的读取AD值函数为例,说明函数命名方式3 [1 g6 G7 n9 R. A8 W! a% [4 ]! w5 n
  2. void Med_Adc_ReadAdValue (void)
    ; N* ]9 b# t- r6 ^1 g, l
  3. {
    8 H! t6 O: y0 q/ n: g6 p& p) _
  4.     // 函数内容; z/ `0 |) q# F! L; i. U) s+ c( t
  5. }
复制代码
. R% x4 I9 R8 B( d

; `* \* ~/ G+ x( }$ z% g% e/ \) J这里med指示该函数位于功能层,属于ADC模块,作用是读取AD值。
) w* o; t0 d, @/ Y7 O  G+ A* B& c" b  h  D( U  }0 v
* p$ g) E3 P# I6 m4 N! n
• if,while等语句的使用 使用if或者while等语句时,需要在括号前面加一个空格,如下. c0 v8 n" Z0 g8 \4 A/ m
  1. if (gAdcAdValue == 0)/ W7 p2 e$ D% J' {9 A& ]/ g- D
  2. {. A/ n' m! ~% {6 d7 Z
  3.     // 程序语句
    , I( n( z' @5 b. m' W( n
  4. }
复制代码
- @" i4 l$ ~! }2 h; @% M  C
; n8 J5 M5 `, D9 b% o7 Z
• 四则运算 四则运算符号前后需要加空格,包括等于号等符号。如下; Z7 Z- q4 t7 P8 O
  1. c = a * b;
复制代码
: T# d$ B) ?0 [! q8 [" Z9 |5 z

0 y3 q7 y0 g( Z7 D) v2. 程序架构
- e, Q" a/ k. @  T3 F该程序架构是本人在工作期间学习的,个人感觉还是有助于提高开发效率,方便后续维护的。主要思想是将一个模块的程序分成三部分,每一部分是一个新建的文件夹,下面都是其他模块相同层级的文件。, r+ D% u: v3 J# i- R5 X
7 c* D# ~0 _7 N

* S$ h5 F. x  s6 D• Drv 驱动层 该层主要是写一些模块的初始化程序,例如GPIO的初始化,ADC的初始化等。$ ?9 v+ z) W% y
• Med 功能层 该层主要是完成一些功能性的操作,比如读取AD值,点亮LED等。Med层的函数可以包含Drv层的函数。
) H6 y) W  D$ d+ Y, s( C& N• App 业务层 该层主要是完成一些业务,比如在点亮LED的基础上实现流水灯,比如显示电压值等。% T' W/ O& J) ^* H
9 k: h9 z8 `, N7 F0 o# h6 {3 _
( l, d7 z5 s9 `! i2 g% q
四、STM32F103ZET6简介. ]% y. `: m( g# I/ t) u
STM32F103ZET6是由意法半导体(ST)生产的一款单片机,32指32位。STM32也可以成为32位微处理器。STM32F103ZET6的主时钟频率为72MHz,512KB的FLASH,64KB的SRAM。常用到的有GPIO,中断,ADC,TMR,UART,DMA等。( c) b4 \1 x$ c* G3 T  M
" W6 z& D0 X: s. N

$ t/ i+ |2 R# U5 V五、程序模板* ?, |. a/ K; h! Z6 r1 ~
在使用Keil5编程时,针对一个外设需要新建对应的.c和.h文件。这里以LED模块为例,简单介绍一下本人的常用模板' o# r  v% S2 a% b
$ N$ o$ b1 p# g2 \
" b% X4 |9 ]# H8 M1 T
.c文件* k% Q8 Q. A# s5 j# m
  1. #include "LED.h"   // LED头文件
复制代码

! w* _9 D7 k: `. ~8 L0 J# X8 Y! h4 ~/ l
2 X. k' }- @4 F7 i" m! \! t0 G需要注意的是一定要空出来一格,否则编译会报警告。- d/ ?8 i  b8 t

$ g, ?, ?/ e$ e. C6 |9 A6 f

9 J; d9 Z4 K  o7 a, q9 W
微信图片_20231023151019.png

( @& f" x6 `; t7 W1 V( x( P( W' s
文件最后未空一行的警告
6 n1 }4 t: k* ~% _# T& P5 X
.h文件4 K( X2 k( U/ X& S$ ]0 _8 w. s
  1. #ifndef _LED_H/ }. y3 T1 F& j0 C2 n# H
  2. #define _LED_H. `/ v- ^2 g5 i# k* M

  3. & E$ _. o: q+ C
  4. #include "sys.h"   // STM32库文件
    ! K+ Q% Y& d7 u- i, i- o, Y9 G

  5. , D5 @: ~" k( P, R3 d) \3 b
  6. #endif
复制代码

5 Y' F+ g9 v# \0 @$ {; }' \. G$ K* L8 ~% C1 l( L
.h文件最后也要空出一行,否则也会有警告。
: V6 i) M2 a: O* ~1 L5 L/ q7 J4 j3 y, u- q3 }( p! y; M
( [  Y( k1 C1 ?2 I, U2 h5 J
新建完之后需要将这两个文件添加到工程中。! z( @, W5 u- J7 N$ j8 k
8 i$ |; W5 }5 [% W* a

8 I8 A, j; b8 Q$ \. G对于.c文件,右键工程文件夹,选择“Manage Project Items”打开。
2 ?4 ^7 X1 @* \" c% l! R; S+ }6 W- Z! ?* K: w6 k4 G5 {
3 ]' c) M+ G1 p$ r4 F! i" ]$ L
点击“Add Files”将新建的.c文件加入到对应的文件夹下。
8 y- I& V3 c8 h  c7 f# f1 F" o% A6 q2 H" E* k$ ]2 s: Q- ~
0 ]3 f! K& V9 Z' Q
微信图片_20231023151016.png

2 k$ m5 \9 h- j5 h
添加.c文件
% j1 v: T- p" D# Q
( x6 w, q& Q+ c

7 ^6 ~1 A& e7 ^对于.h文件,点击魔术棒,选择“C/C++”,点击三个小点选择对应文件夹即可。
7 o3 |, n) f3 Q6 Z- S) Q* Z7 O2 S# x- @. Y3 C& H0 A2 c7 ]# {
3 r* Q( [( |3 @4 `0 [
微信图片_20231023151013.png
& a) l. R8 G, R' P
添加.h文件
$ Y! r1 M' `0 j- f2 |; m5 j

( K% d: G1 ]- b; L3 S$ T

/ i: G5 W- k; I/ n六、ST-Link调试( p' R9 R# d$ Y- |3 j$ m
在开发过程中学会使用Debug调试,能够帮助我们更快地定位问题。这里简单介绍一下利用ST-Link和普中核心板Debug调试方法。
7 \# L% i, w6 L9 x1 [; X! y, v1 @$ C+ c  y- [9 M9 Q" Z
1 b5 H. z6 q& C* V% k  P
6.1 硬件连接* @+ F4 F% A! Z: `7 {4 H" ?9 w
首先将ST-Link与核心板连接起来,ST-Link的引脚如下1 A; Q# X  D0 E) d$ n* x2 h
* F# t2 Y+ W* M- u9 z& r* ~- O9 d

9 O  j# E& ]# p" j* H& I
微信图片_20231023151010.png
! P' x, ]* D/ O
ST-Link引脚

# q4 [$ q, @9 u1 r# i' n- K+ T9 q! V* p( v

$ ~; n7 u' M. v7 o8 h! s: P' V核心板上并没有给ST-Link预留单独的接口,而是跟JTAG一起。
0 k3 S# O# q3 m" U
% Y3 L3 S/ m) P2 ^* D0 A. w6 c
) `% O, Y3 Q/ Q6 f1 q1 w
其原理图和硬件图如下
8 S0 `: A3 j1 w( _$ ]
6 @: X* V/ b$ A/ m  Q9 P3 O
" D* z; i) E( i+ p
微信图片_20231023151007.png

( m1 g( y- q! [" @& a; [
- P& ]& r% t* a8 m- {JTAG原理图
# q' s  j! r- G9 G6 |4 |/ @
- ?- @- s6 w- j) C) z
微信图片_20231023152058.png

# M" G; Y( y& o- q3 f9 h0 i
JTAG硬件图
" j( I& x2 s& y3 W+ B
1 l* m* d9 i6 k: q/ \

1 ~: C/ l: v. o, ?由原理图可知,ST-Link的“SWCLK”连接核心板的“JTCK”,“SWDIO”连接核心板的“JTMS”,“RST”接“RESET”。8 J9 D: v  ]9 R% [; \3 T* h4 ~- o' C

; x8 b5 Z( p' b; X! w

0 q  O( Q# o* `0 TVCC不要接,接好ST-Link后再单独给核心板供电。+ u& r$ X6 l: f+ M

6 ?1 P( ?- [8 b4 @& W2 e8 Z

6 J# P& z) @+ A* s0 N# T% H6.2 Keil配置) i6 @2 C4 _# x3 x0 q) F
硬件连接好后开始配置Keil5,关于ST-Link驱动的安装这里就不再做介绍了。
- y7 Y3 W- R8 y! E; y- q. W( G) `% d" o3 t3 ^) n- \

: T: _3 O; q) D4 A* S2 O• 首先确定ST-Link驱动是否正常  d: i( C4 s2 ]* m5 z
0 @3 ?. ?0 E- w& F3 e& Q
& J4 K2 I+ x* K4 P$ ^( \+ q- l' Y8 F  y
微信图片_20231023151004.png
1 H5 ~6 c. D1 M0 W3 c  J* y/ ^
确认ST-Link驱动是否安装正常

" ^( S1 |8 o; [8 ]7 R+ C  y6 E' U- x$ Q3 }3 u
6 a: {8 E6 w7 l
• 配置Debug 点击魔术棒,选择Debug,下图处选择“ST-Link Debugger”。
5 n0 x5 p0 X4 _$ _: W
8 C! i: ^# i+ G3 A3 {! o5 |7 q

  }3 s! U, z9 }+ N9 v3 {: F
微信图片_20231023151001.png

3 l, T: C3 g# p9 B
Debug配置
+ Q9 J4 L0 W) z6 a* b  j$ ~

4 V3 V. k4 G. g
' k9 E7 x. g( t( C+ q& O
然后再点击“Settings”,在“SWIO”右侧不显示“no target connected”就说明ST-Link连接正常。点击“Flash Download”
* _# Z. r5 k& [' V* ]. @9 |
+ v+ @4 W# ?5 W% {) d

. M7 c/ p9 K% V5 g  h
微信图片_20231023150958.png

# J  y0 x) F) `4 p8 _6 b/ g
Flash Download

  B" a# n1 r3 ~+ U+ q" w
: b9 z6 a" l' q7 ]' Z
1 a+ _: ~* Z  ?8 J6 ~0 ^5 ~* q
按照图示配置,“Programming Algorithm”只要选择符合芯片型号的即可,需要注意的是,只能保留一个。" |- O% l4 v& ]$ B* [0 J+ R- ]

' g; M! Y+ i' q9 M/ f' K1 V" ~
- @  |( \* ]2 B
微信图片_20231023150955.png
4 S- a5 y8 t% E5 `- ]3 b6 x2 @% M
Flash Download配置

; T) `6 |9 {, \3 K: `+ g# H1 _- }, i  }/ f
1 w* @$ m4 Q/ k8 j/ e! V0 C- B9 y
按照下图配置“Utilities”。' E  v0 o) o1 [) P2 Q3 d
/ N2 a; Y/ X! r2 G3 N7 M
4 v( V% E2 F9 D
微信图片_20231023150951.png

$ \- @- K, t2 M" Z1 z4 @5 p* [
配置Utilities
2 O' O  [& H' A! \# _
/ x6 o' @6 h0 i! ]: x  A- S
4 u) u; I$ X4 {( d5 i* ~* n, S
至此,Keil5关于ST-Link的内容配置完成,如果小伙伴遇到其他问题,可以多去看一些大佬们的博客。" h: L$ z! g: }2 X
% Z" Y' D8 V) k2 O+ C3 X

+ T0 g, b, y5 [$ a- {( b6.3 下载调试
, y6 V, r! I3 K, P1 _配置完上面的内容后就可以使用ST-Link进行下载调试了。下载的话比较简单,编译完成后直接点击下图标注的图标,等到下载完成即可。+ d8 P" B" V( N1 z1 G- K* @1 a$ o. _
% [* E  a$ d5 o; g2 ^5 U+ C: X
" j2 u' p; z0 @" j5 n; b( _
微信图片_20231023150944.png
! R1 @9 E3 ^0 n( R! \. L
下载程序

- k; A8 t! O7 G: C# ]4 ~8 `- |
' \. L& |6 b0 p  C

  R+ v/ @- c; R& M+ \调试时点击下图所示按钮,进入Debug调试。% e5 ~, I7 t* l0 ]/ {. {
7 F: ~- l2 O. M1 g" r5 Y; g. V
& A7 }, a6 H8 N8 G* y
微信图片_20231023150941.png
  c% R, a( U) _0 V- J' F" p. \1 o
调试按钮
# w, |: t! O" P
: L7 p  B# D) ]- I. v3 }) A

* [& ?" J& H4 I# i3 q% V& i. P下面简单介绍一下调试窗口中各个按钮的作用,其他更加详细的介绍需要小伙伴自行搜索,这里参考了这篇大佬的文章KEIL5中Debug调试。$ P1 n5 b# S% X7 p; h
# v1 {6 ?: R5 h/ Q8 t& w% m$ Y
# t! E. n' i' z4 b) U
微信图片_20231023150937.png

" g2 a% W6 u% M% ~0 s  j* `1 R
调试窗口按钮含义
- @5 A8 X5 Y$ Q/ N& K
8 O7 Y: Y4 {: ]5 X2 G! E3 n, i2 L

" f1 o6 z" R1 _7 A; y8 @第一部分从左到右
  E! r9 E* n' X/ {, c0 Y/ B7 ^• 复位
  M4 t6 x; z8 e4 s. Z% i* l- _• 全速运行
- L3 m2 Y; D$ X; E9 H2 i• 停止+ g2 N" P0 h( w0 j* I# M
• 每点一次运行一行,遇到函数体会进入
! S; p; ~% @( A% W• 每点一次运行一行,遇到函数体不进入,直接执行完到下一行+ `+ V& H/ k4 _  B$ y0 z" Z6 V5 \
• 快速执行当前函数剩余语句,然后跳出该函数体,准备执行下一条
  n. }. s! |5 G• 直接运行到光标处
; B) z; h6 S, |2 W6 n" P; X6 }" |
3 M* T3 N4 p" g. M( k
' S! c. S2 K% O, q3 B9 i
第二部分从左到右
2 }" j- i) N( W: ~, U2 Q- I• 设置当前光标处为断点
* T8 e2 `4 F5 Q1 j3 C/ Z  e• 失能当前光标处断点7 H9 z* |# I# I$ q
• 失能全部断点0 q) n# [7 n) v; r
• 删除全部断点
4 b6 s' x- Y) D4 y# x  W% w( w
, F( q1 Q/ h- M, c; h$ {, [: J
打断点的方法比较简单,直接在想要打断点的一行左侧点击一下,出现一个红点就表示已经添加了断点。断点的作用是能够让程序运行到断点处停止,有助于我们分析函数运行方式以及变量的变化。4 X& @0 N% Q6 J. V# L9 x
$ Z' v) u) S& K6 U& J; ?

( B4 t! L  O' T6 l( N
微信图片_20231023150933.png

  C, a1 ~8 O; L% E/ e( U
断点示意图
" Y& |( u/ v/ q
2 p+ q2 v; q8 H0 o. B2 h7 S

- v' I* y$ L5 i$ B+ w调试时可以查看某一个变量的值。选中想要查看的变量,右键2 P7 P+ @% A9 E% O- _" O
$ g, t6 ^$ R' H

. B9 V* J* u0 h
微信图片_20231023150929.png

' ^8 _5 o4 N; F+ P/ A$ [6 l
查看变量值

& h) [6 u( N/ }1 y) x

$ B1 ^# u. C8 @: ^% g  d3 J- i

/ P6 f: d- O% S, F$ ], ?此时就会出现一个窗口,能够查看该变量的值。
# ?) ^& \: X2 Y( u& z7 u- T* L6 b/ N+ n1 ?, [

9 |+ X$ l" c1 `
微信图片_20231023150924.png

( o2 V4 ~" \8 f5 W
查看变量值

3 ~! E4 P/ Y0 i  I- `2 o4 R转载自: 二土电子
  G- L( t) D8 X' q/ W" n; d如有侵权请联系删除
& H1 [3 q- M4 m2 O/ P# n# M
# C% o' S% q* a4 M: B$ d+ `
收藏 评论0 发布时间:2023-10-23 15:12

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版