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

基于STM32F1的CAN通信之概述

[复制链接]
攻城狮Melo 发布时间:2023-10-23 15:12
一、专栏简介
; n( o9 k  j7 {' U+ Z! _* n) _本专栏介绍如何利用库函数进行STM32单片机开发,主要针对的单片机型号为STM32F103ZET6。总结来说,“速成”体现在以下方面
( `& r- c% ?7 j' N" ~• 在讲述基础知识后会有相应的实例或者模板程序
' `3 @) L3 k5 L• 学习完后会有小项目练习1 B' r* [, P& \4 P2 v9 Z8 f
• 专栏基础知识部分内容精简,对于“速成”选手更加友好
7 F/ b3 R2 ]6 C. w) J
; z  [7 V8 y% y+ d: E6 {

( S7 G8 X# r  I: k; i9 A其次专栏还有以下内容4 |+ h) z% |4 }, H& l' [
• 简单介绍编程规范和程序架构8 j6 ^/ Q0 F# `% V  a- N
• 专栏不断更新一些外设的使用方法并提供例程
6 J3 f1 }2 e; _( h7 C8 I9 v" _7 n2 @2 j. Z3 n7 Y

  {- J2 f* T  l$ j/ _二、前期准备
; j$ s. I! p( i- W( X7 _6 t& v. C前期准备主要有物品以及相关软件的准备。首先是物品,单片机选用的是普中科技的一款核心板,主控芯片为STM32F102ZET6,是下面的样子
% O: J# ^$ p# R/ h
微信图片_20231023151024.jpg
, i: s$ Q: q" Y  K
STM32F103ZET6
/ z* b; m1 w& q$ y4 w

, T) _4 R+ U: _$ A& S

* D6 N  ]' n" V( P8 y4 M* M( E, |图片上是带有LCD屏幕排母的,有一种是不带的,因为本人开发时经常使用LCD,所以买了带排母的,在某宝和聚诚科技购买的,不带彩屏169RMB。学习过程中除了单片机以外还需要购买调试器,ST-LINK,用来下载程序和调试。USB转TTL(可以直接搜索TTL),用来做串口通信时使用,也可以用来下载程序,但是不可以调试。对于前期学习来讲,这些物品就足够啦。
. R( O+ h8 W) B7 ]
2 t. E$ W4 A" l  u

* E' A! O7 l: B/ v; G% d* f5 n除了物品之外还需要提前准备一些软件和驱动。比如Keil5,CH340(串口驱动),ST-LINK的驱动,这些都是需要安装的。其他的类似于下载软件,串口调试助手都是不需要安装的,本人用的是普中科技提供的一些常用辅助开发软件,小伙伴们可以自己动手找一下,没有找到的话私信留一下邮箱,注明需要常用辅助开发软件,后续会邮件发送。) q/ ~+ V+ w5 Y( W8 P. v- Z4 f
& j! H' |3 q* M) n) E0 x
! s" T# X* o( `- n
三、编程规范以及程序架构简介7 K* y- P. U- w0 @5 a0 U8 m
1. 编程规范
; s' K3 B6 N! v4 b% [: o+ h3 j对于新手来讲,编程规范以及代码架构也非常重要,有一个良好的编程规范和代码架构,可以提高开发效率,方便问题排查以及后续的程序维护。这里介绍的编程规范很简单,要求不严格。主要有以下几点
5 m: A0 G6 S0 }  x  {# s" i% t2 U8 b( m! S
& ^$ O* H, m$ J" ?+ K5 Z' E" ]
• 变量定义 变量定义时最好是能够体现该变量所属的外设模块,该变量是否为全局变量,静态变量或者指针变量。变量首字母小写,后面的单词首字母大写。举例如下' e+ n! z# J# Y' W+ ~
) F# L. d" H# ^+ V4 y4 A4 R
( _) Q5 @# _# N# N% K0 E+ Y
  1. // 以ADC模块为例,需要定义一个存储AD值的变量,举例说明变量命名方式
    # p8 Z/ \& e: i& P6 q  P. L
  2. " \! i  j, H; w8 T- ]$ m
  3. // 局部变量" ^5 f6 J! {$ w+ w2 h6 W, V, _
  4. u32 adValue = 0;
    ; n# H0 ]3 _& E- E0 K! t

  5. % M  L8 G) M8 }, `" L& P$ V! y
  6. // 全局变量5 ~% G1 s: {: V0 x. X: d0 M
  7. u32 gAdcAdValue = 0;   // 加一个g表示是全局变量
    ; p, f$ f5 x$ @9 ^

  8. $ M+ O0 B9 U  \  y9 s" `
  9. // 全局静态变量; Q; t- \+ X3 K9 W, K7 l
  10. static u32 gsAdcAdValue = 0;   // 加一个s表示静态变量
    ' V% q4 G5 ^( [6 O

  11. 1 L" `( R* e: U0 R8 i* H0 q
  12. // 指针变量
    / B  K$ n+ q- W% L1 s. A
  13. u32 *gpAdcAdValue = (u32*)0x2000800;   // 加一个p表示为指针变量
复制代码

, Q! O! m$ P+ L
. p& g) T: c. m. P' m, Y+ v• 注释 函数注释举例如下9 W/ t3 h9 A0 V: j( l- K
  1. /*5 i3 _+ @- G; ]/ B# L1 T
  2. *==============================================================================) D; ?! H" J2 _8 R8 D8 V
  3. *函数名称:! K: q8 z3 B7 s6 L% j1 F
  4. *函数功能:; x4 f) N+ o: M4 ~) F
  5. *输入参数:
    ( L2 r# U3 F# A( ], v
  6. *返回值:无% Z% V! h, v" T1 h. d8 @) R. o7 t
  7. *==============================================================================% s  q- b: u2 u2 u# h+ S
  8. */
复制代码
; H/ f$ p+ W5 Y6 g8 V" A9 ^/ M1 z

) O( L% `  c7 @" Z( p  v% S# ]对于程序语句注释,如果过长可以在程序上方加注释,如果不是很长可以在程序语句后面空三格输入注释。0 I1 ?- ]0 f3 _# J0 U) _/ L0 S
" @* `# {! W9 s1 C0 e
/ f% P. ~$ _; V0 X0 r/ L
• 函数命名 函数命名要体现函数所属的层级以及函数的功能,关于层级会在代码架构的部分详细说明,这里只说一下函数命名方式。. |; z3 E9 P! k9 i8 u# E
  1. // 这里以ADC模块的读取AD值函数为例,说明函数命名方式% ]  L. y2 ?6 _* B9 R* ~& b& j+ A
  2. void Med_Adc_ReadAdValue (void)9 o# o  I% s! x3 ?
  3. {! U2 k# q5 |6 e; L; ~8 T
  4.     // 函数内容6 W7 a" c2 Y9 G1 b) B7 y0 a
  5. }
复制代码
7 y# |$ ~; y% _- V, n
+ ]  H  `2 Y( D
这里med指示该函数位于功能层,属于ADC模块,作用是读取AD值。
! k/ y- {3 b& _$ u- `$ _9 r- a1 X! `( o5 L6 X* V3 L" ~

# G# \* e# F. P& g# E" N! u• if,while等语句的使用 使用if或者while等语句时,需要在括号前面加一个空格,如下
  n- T" m- B4 K8 A1 C+ z, f
  1. if (gAdcAdValue == 0)
    . g/ |! ^/ M' R, c# g
  2. {
    8 T, t3 }# T/ P) p) [3 r4 `
  3.     // 程序语句
    4 T/ N( g% z- [& r
  4. }
复制代码

2 U' z  w$ p6 Z8 `$ p6 p1 j0 Y8 M3 c. ]: O
• 四则运算 四则运算符号前后需要加空格,包括等于号等符号。如下
0 N+ e. f) l+ ]# o9 I9 i! Y
  1. c = a * b;
复制代码

: f8 Q! N* v0 s& C0 G7 Q' R
, s' D6 d: r/ _3 e0 H6 T2 c2. 程序架构
  n" H$ X/ N. V( G* @+ J该程序架构是本人在工作期间学习的,个人感觉还是有助于提高开发效率,方便后续维护的。主要思想是将一个模块的程序分成三部分,每一部分是一个新建的文件夹,下面都是其他模块相同层级的文件。
  j3 X! X, J7 I: E$ N5 q* t+ O' N  }6 F. `: `

: P9 F/ ~! N% ]& f# z: U• Drv 驱动层 该层主要是写一些模块的初始化程序,例如GPIO的初始化,ADC的初始化等。
  p. G& U6 q' g' s1 l& C• Med 功能层 该层主要是完成一些功能性的操作,比如读取AD值,点亮LED等。Med层的函数可以包含Drv层的函数。
3 z' a% I% X) y! _• App 业务层 该层主要是完成一些业务,比如在点亮LED的基础上实现流水灯,比如显示电压值等。$ T0 e# B6 c/ ]# p/ k0 Q4 Q
1 j& z; X) B  [

: }: i: u" ^9 M/ S四、STM32F103ZET6简介! D; X/ c; _- X, w4 U4 y/ g8 U# s
STM32F103ZET6是由意法半导体(ST)生产的一款单片机,32指32位。STM32也可以成为32位微处理器。STM32F103ZET6的主时钟频率为72MHz,512KB的FLASH,64KB的SRAM。常用到的有GPIO,中断,ADC,TMR,UART,DMA等。
& C6 }0 d- E$ d$ U( g8 Y8 p1 _- _
% n) n  {! F3 p

; w- \% r3 {, ?: Y7 @五、程序模板+ z8 B/ |- k) R" N1 A! D8 x4 G# ~
在使用Keil5编程时,针对一个外设需要新建对应的.c和.h文件。这里以LED模块为例,简单介绍一下本人的常用模板
  V0 K( K. c5 h+ `2 I% I& M$ @
- F2 j! a' z+ }; G- d. [( u- i

5 ]( e8 C* Z$ k; A5 E.c文件
, ^! R8 m9 e7 p8 B
  1. #include "LED.h"   // LED头文件
复制代码
' Z9 E8 ^/ R9 }7 q# e0 Q9 R

9 `7 Z8 b. c" e: [* r1 S需要注意的是一定要空出来一格,否则编译会报警告。6 Z& V7 W: }* m! m

2 \4 G7 j6 t3 r( ~
0 E2 h- S$ y2 l* q
微信图片_20231023151019.png
; }% _4 d# D: h) o2 g5 l4 S- P9 n
文件最后未空一行的警告

$ g7 s; [. H9 t6 X$ l5 ^, M6 h.h文件$ _: K& g4 z. i2 L: g7 h, M
  1. #ifndef _LED_H
    . U$ |4 G( l6 s, R1 n! S
  2. #define _LED_H
    " T, t0 A  @4 k1 \, e: G

  3. + R1 s& N2 A/ m
  4. #include "sys.h"   // STM32库文件
    . ?, B; N; W# a4 B' F% q/ c# a3 K0 K
  5. - t) T4 W& M$ x- W
  6. #endif
复制代码
! I4 Y( H4 l% V4 [

7 e( S  V6 ?2 w! G2 b6 E4 S6 m) ?2 _- l.h文件最后也要空出一行,否则也会有警告。
/ r& e/ u6 x3 {0 O, E  [3 |$ w/ Y- q  n3 N7 O$ L  r1 V

* k( {; o0 \! Q" ]( h新建完之后需要将这两个文件添加到工程中。
% i0 e; [& s1 E: C* c
2 c4 Y6 ~2 ~8 q2 L( O

& G; {0 W2 g7 A# S( [( F+ M对于.c文件,右键工程文件夹,选择“Manage Project Items”打开。7 P; x+ o) _  H
2 H9 v# l5 M" o1 ]0 ]
7 l) l" W7 K6 M
点击“Add Files”将新建的.c文件加入到对应的文件夹下。1 U* B' }8 W  Z2 r4 N
; c5 \$ W4 L1 {5 W% C+ b$ D+ S+ s9 g# h- A

' k& ?  O& e- T; [9 U( H* I# M# H
微信图片_20231023151016.png
. |2 q9 J! b. T+ j. c. \# L
添加.c文件

4 r) x( p0 i6 H2 k2 H, L* m) M" n; I! H
) c0 e& {6 {, w8 o
对于.h文件,点击魔术棒,选择“C/C++”,点击三个小点选择对应文件夹即可。  H) ?; k: h3 ^- f/ m& y
- c. j  d, Z- o; X- q: w8 |
6 s# o% D2 d& c" N- h) t# s! b9 b
微信图片_20231023151013.png

3 [3 y9 Y1 X. c
添加.h文件

- C( g( c3 I& v8 \6 @2 J6 |% B0 P
" n  A7 [* \5 D& }% r+ ]; I1 J
! n: E( L# a% x+ J4 _3 @
六、ST-Link调试
& z7 N! p. j6 O! l0 J在开发过程中学会使用Debug调试,能够帮助我们更快地定位问题。这里简单介绍一下利用ST-Link和普中核心板Debug调试方法。
2 [& a* o' U! @6 Z9 D
( ]9 h* Z6 n* I/ g3 b( l6 c

) E& C0 E1 h1 P& `) W4 e6.1 硬件连接
4 a5 u. X. x. s/ P( Q) A" _首先将ST-Link与核心板连接起来,ST-Link的引脚如下
% {8 j7 Q" t5 C& {, M6 m6 \" p6 l! A# H( G  h0 n0 t

1 `6 W0 M: j% A0 l
微信图片_20231023151010.png
( q+ d: \. Q9 b$ f0 n9 @
ST-Link引脚
2 W, X) v# h7 d+ \( i( r

9 x0 W9 d0 c3 q2 c+ A: A/ b9 {
  o4 F. P2 A9 S# n: D& B& c3 x
核心板上并没有给ST-Link预留单独的接口,而是跟JTAG一起。( D& d5 |$ v' E7 X/ w% t
& Y; t: `# a" Q4 r3 O# y
7 I3 R* O: w6 y5 J$ a
其原理图和硬件图如下% ]  @5 r$ @2 l# H% {0 }
& r2 [4 B9 i, S- q
3 r- [- D) e# I$ X$ B% Q
微信图片_20231023151007.png
2 S8 C& V1 y8 d! ~9 W
+ f0 Z( K. b$ q6 J" B. K0 q
JTAG原理图
. G3 X) y4 \3 H5 {7 V
: R- a- ]  S, m4 F: s
微信图片_20231023152058.png

8 H' r. x* N* x- E/ m5 P
JTAG硬件图
: f/ w' E$ x" d* I# Q& S6 O
$ Y: h' W# Y, p: T
0 u2 z. n6 o! o6 {+ j
由原理图可知,ST-Link的“SWCLK”连接核心板的“JTCK”,“SWDIO”连接核心板的“JTMS”,“RST”接“RESET”。
9 `+ X0 ?9 c5 u7 d: b
# ]& \, L) Z) w( D9 L( X0 v* v

) X- V) c, @8 k1 E) P4 KVCC不要接,接好ST-Link后再单独给核心板供电。
+ w; E+ L+ B7 J& S3 [
( g+ N# r7 X; |5 s$ J& C& M

/ m1 Y! O. {% }( Z0 @, b, q6.2 Keil配置% ~7 Q0 I- |/ _( D, {
硬件连接好后开始配置Keil5,关于ST-Link驱动的安装这里就不再做介绍了。; o2 A. B: j' e$ q) O
+ P6 H+ ~& o) J& K

9 P$ P, d" ^* F• 首先确定ST-Link驱动是否正常( R+ w! G' U/ w* H7 m

0 Y, s  A: j$ f
& z+ K( ]) R3 Q5 Z) ^0 }
微信图片_20231023151004.png

. B: |$ w/ l8 _9 J. u+ C. o
确认ST-Link驱动是否安装正常

+ e+ s& E$ }* X0 r. P: f% [# S- |0 K6 J
) k$ m' ~! C* l
• 配置Debug 点击魔术棒,选择Debug,下图处选择“ST-Link Debugger”。
( z; K* o& S8 W  N" M) k( M* w% E

& @4 \# O' ?* k3 ]# @
微信图片_20231023151001.png

0 U! T! Y5 Q9 O8 g8 Q/ Y# a1 q
Debug配置

1 ~6 u5 K. j6 ]- V) d* g: J$ ~, c3 n6 M! ]8 n/ ^$ n, B# v

/ _2 [4 g$ F- M. O, A6 c  O5 G然后再点击“Settings”,在“SWIO”右侧不显示“no target connected”就说明ST-Link连接正常。点击“Flash Download”
6 [6 h: M% l1 l# n# y/ S6 w( k" j5 E

/ D# U3 n: ~" w8 Y# H6 c
微信图片_20231023150958.png

1 x% Y  L; b. v& }
Flash Download
% K& s- x6 B" _6 _* P* R

' {3 b: R6 I3 j4 U" s4 G- p

+ X# c4 D, T4 u/ O& F1 r, b按照图示配置,“Programming Algorithm”只要选择符合芯片型号的即可,需要注意的是,只能保留一个。! V% Y/ w% g7 u! ?) L7 v/ Z
4 I5 E' s; [; S* I4 Y

) f1 Q3 V) F4 E4 e, u
微信图片_20231023150955.png

. ~5 o: p' z9 @3 x" G, K
Flash Download配置

5 I9 c1 n5 y0 p5 G/ \. j% N% M6 n5 l( d8 v$ y' v9 p5 e+ O* T
/ ~9 c5 R4 Q" J4 b( b3 X
按照下图配置“Utilities”。
7 c. R  i( \6 g0 A& u/ ]5 B/ X* Y/ f+ N0 |+ g4 X  u
) @8 W7 \* s( m! \
微信图片_20231023150951.png

4 }6 b# n+ a1 m+ W8 s& V. W
配置Utilities
, d0 z, T  G& A* Q1 V5 ~
8 v; a$ u' K/ N( o/ E+ g
+ R/ P) y3 Z; ^7 s
至此,Keil5关于ST-Link的内容配置完成,如果小伙伴遇到其他问题,可以多去看一些大佬们的博客。0 e, J+ K: f* }+ d' M! {

, S0 h+ Q$ ~4 O+ k
# X1 _9 s9 o7 ~4 y3 C+ z0 u
6.3 下载调试2 A6 f5 O; n0 q* B* g0 x
配置完上面的内容后就可以使用ST-Link进行下载调试了。下载的话比较简单,编译完成后直接点击下图标注的图标,等到下载完成即可。8 {3 X2 s3 ~) h! K+ Q8 _3 ~

+ c* s/ e6 R  l+ b; [
4 g9 W) u; R% c
微信图片_20231023150944.png

3 ?; P" U5 r# Q, T. ]
下载程序

, x% f5 H' w- G: |
, L- A  J0 n- r4 D* G- [: S
8 P0 x8 c) x# r, B8 o$ M5 h
调试时点击下图所示按钮,进入Debug调试。
7 \" P( ~' L- t7 C
$ n  W$ M1 F. @4 ~) B5 T
& |& ?* a( B( |- a( F
微信图片_20231023150941.png

) P# Q2 J) y( F
调试按钮

, a+ Y2 J5 ?6 c. O' g
' h! z9 U. z; Q0 X7 q/ q$ v1 T( w
6 M& G  T0 }" E; H$ T& E: P
下面简单介绍一下调试窗口中各个按钮的作用,其他更加详细的介绍需要小伙伴自行搜索,这里参考了这篇大佬的文章KEIL5中Debug调试。
/ z2 S' n4 t7 ^5 V/ V
# H% R/ N7 Q6 g5 K
$ t" k) _  P1 C7 y, R/ l
微信图片_20231023150937.png

3 c! _% H# g& a1 T& z, o6 i: h
调试窗口按钮含义

+ J8 T( x7 C0 t- Q6 n: N" K, y
  z% ]* ?4 f, [% W& U4 N+ ]; U
* H( M6 m3 c: }9 l% \% N6 C* L
第一部分从左到右3 D* \; o5 k) k7 B2 t7 X
• 复位8 `+ W$ ?) I& M: D4 d
• 全速运行
5 C' }; _" ^/ }8 v* L6 A* Y• 停止
4 a; ~+ S& ]8 i2 b- Z4 ?9 E/ ?6 J• 每点一次运行一行,遇到函数体会进入
8 G! Z( M# A9 k0 t* I" T% h4 D• 每点一次运行一行,遇到函数体不进入,直接执行完到下一行
7 P, Y1 h: w& y1 _6 i1 _1 _• 快速执行当前函数剩余语句,然后跳出该函数体,准备执行下一条2 F2 p( \$ J+ s5 ^1 g
• 直接运行到光标处. @- R) b, ^$ D! @) ^) i# f! u$ B

  z- A- W" n' l

; I3 m( N2 E8 B' Z$ D第二部分从左到右4 \2 s& x8 v) x: w" g
• 设置当前光标处为断点/ `+ R) T5 E7 `3 Y6 d  _& O+ E
• 失能当前光标处断点$ T, b0 l# y; S7 {4 ?
• 失能全部断点4 o2 X3 k& s! t. X( z9 N: X$ }
• 删除全部断点( d9 ?2 y9 E' @- [: l

" L" }0 z. w6 C9 Q, W) Y

* I( F7 {( e' @打断点的方法比较简单,直接在想要打断点的一行左侧点击一下,出现一个红点就表示已经添加了断点。断点的作用是能够让程序运行到断点处停止,有助于我们分析函数运行方式以及变量的变化。8 r7 [! E1 N: _% e
9 w" R. h0 S+ Y: Q  u* E% Y: i

" H) s& O* \$ }7 {
微信图片_20231023150933.png

( S+ t. L" a2 q. q& ~- \/ j  a; P
断点示意图
/ R4 r2 s3 W, h( H- f

9 Y  L6 a. n0 U

: Q8 o  l  F+ V1 z9 I调试时可以查看某一个变量的值。选中想要查看的变量,右键9 x% _$ @1 k# Z4 u! z5 Y
; z4 r6 ?/ P4 p) B7 R6 z! g" `

! w* t( i, Y7 v* v) I
微信图片_20231023150929.png

, [- Q" K% `  S8 d
查看变量值
- A5 x1 [" |% k7 o( B7 }$ F& l

7 q) y5 H& ]+ D7 W5 C

4 \5 }. ^, e/ t9 w( x6 m8 G此时就会出现一个窗口,能够查看该变量的值。
. F& J) \% G7 p& Y$ ]
9 j) \4 S3 V2 r6 F/ Z( P9 g
' G+ I) Z- T5 p0 I
微信图片_20231023150924.png
2 t" m6 O$ n8 s
查看变量值
( s; w8 {' X$ |+ e2 q
转载自: 二土电子
# w7 O; n& p5 A* V如有侵权请联系删除
4 A! n2 F8 M; Z7 T2 g+ u
  R# z% G8 X/ W$ A' [
赞 收藏 评论0 发布时间:2023-10-23 15:12

举报

0个回答

所属标签

相似技术帖

官网相关资源

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