请选择 进入手机版 | 继续访问电脑版

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

MiniPro STM32H750 开发指南_V1.1-新建寄存器版本MDK工程

[复制链接]
STMCU小助手 发布时间:2022-10-4 18:21
新建寄存器版本MDK工程" w6 W* [4 V+ M" n3 b
通过前面几章的学习,我们对STM32有了个比较清晰的了解,本章我们将讲解新建寄存器库版本MDK工程的详细步骤。我们把本章新建好的工程放在光盘里,路径:4,程序源码\2,标准例程-HAL库版本\实验0 基础入门实验\实验0-2,新建工程实验-寄存器版本,大家在学习新建工程过程中间遇到一些问题,可以直接打开这个工程,然后对比学习。2 g, T! `  S3 c# G, ]2 g
  V+ ]8 o9 V* o* U, C# K
6.1 新建寄存器版本MDK工程- |& Y  R! N; C) b- l8 |
本节我们将教大家如何新建一个STM32H750的MDK5工程。为了方便大家参考,我们将本节最终新建好的工程模板存放在A盘:4、程序源码\2,标准例程-HAL库版本\实验0 基础入门实验\实验0-2,新建工程实验-寄存器版本,如遇新建工程问题,请打开该实验对比。. x- w' ]# B, K8 D3 L
整个新建过程比较复杂,我们将其拆分为5个步骤进行讲解,请准备大概2个小时时间,耐心细致的做完!对你后续的学习非常有帮助!
; U: v3 V8 H( T) s/ ]在新建工程之前,首先我们要做如下准备:
& X) d) D) |0 f1、 STM32Cube官方固件包:我们使用的固件包版本是STM32Cube_FW_H7_V1.6.0,固件包路径:A盘8,STM32参考资料1,STM32CubeH7固件包。( b. b2 b9 E# C" @4 L, r$ {4 B8 }+ }- @
2、开发环境搭建:参考本书第三章相关内容。4 C% @0 R) f' F
6.1.1 新建工程文件夹+ f. C9 h, {! e9 C
新建工程文件夹分为2个步骤:1,新建工程文件夹;2,拷贝工程相关文件。+ r+ q+ Z" I; k. m  F

0 {9 \! ~0 v2 D. @% @# f1.新建工程文件夹
  z9 `: I" P" `5 R0 L首先我们在桌面新建一个工程根目录文件夹,后续的工程文件都将在这个文件夹里建立,我们把这个文件夹重命名为:实验0-2,新建工程实验-寄存器版本。如图6.1.1.1所示:
; W; C* A. q+ z) m: H* F& I 17f331b18b564ccb83cbf64708d46fdb.png $ n* a  Z+ H# A5 _6 V1 i) H$ y! f

, \$ W. l; _- o图6.1.1.1 新建工程根目录文件夹8 B2 H$ O% x5 g. X' b
为了让工程的文件目录结构更加清晰易懂,我们会在工程根目录文件夹下建立以下几个文件夹,每个文件夹名称及其作用如表6.1.1.1所示:
; }7 j, V* W; V8 D' A% j
7 V9 |" V2 _# D1 x) d* d 4a768110cc6241f9b0cf62cc6693af47.png
6 g8 W1 z6 R  ?2 Y( j* o$ ?( @
: W* c2 _. D& M+ D! j. N6 ^表6.1.1.1 工程根目录新建文件夹及其作用
4 j2 V. k- r9 B) @7 P! X新建完成以后,最后得到我们的工程根目录文件夹如图6.1.1.2所示。
! e" z! v" k0 B! J' g1 a1 r2 w5 _" g# X3 f& F+ Q
7972cce9e85c40d2bd17b44b532e5de7.png
' v! m+ l- u5 K* w  ~) Y0 @1 }! ?) }3 w# N; V, a; I1 Z
图6.1.1.2 工程根目录文件夹
' {3 ?- z. w* p! R6 T- O% S7 m6 C0 o工程根目录及其相关文件夹新建好以后,我们需要拷贝一些工程相关文件过来(主要是在Drivers文件夹里面),以便等下的新建工程需要。
- ?+ u. @# E6 I8 r; ?# d
1 t. _* Y, a# H0 O  H5 F2. 拷贝工程相关文件
) j" {5 [' H4 w接下来,我们按图6.1.1.2的根目录文件夹顺序介绍每个文件夹及其需要拷贝的文件。& i4 b  g8 t. X7 J& P$ a% e
Drivers文件夹
4 X/ L# d4 x% P" m! |/ ^该文件夹用于存放与硬件相关的驱动层文件,一般包括如表6.1.1.2所示的三个文件夹:. ?- u3 j! ?+ \

& ]8 b7 [% O$ K( Y/ v! t- q7 F e88e2b3145e946768dd71e8e1dbe1242.png ' b" N! m3 L. R* A& S8 H! c
& Y3 w9 D2 q% m* n( v' t
表6.1.1.2 Drivers包含文件夹9 f' c0 c& u: j: j: V  E
BSP文件夹,用于存放正点原子提供的板级支持包驱动代码,如:LED、蜂鸣器、按键等。本章我们暂时用不到该文件夹,不过可以先建好备用。
7 u# a6 E4 P# z4 p  X" L5 wCMSIS文件夹,用于存放CMSIS底层代码(ARM和ST提供),如:启动文件(.s文件)、stm32h7xx.h等各种头文件。该文件夹我们可以直接从STM32CubeH7固件包(路径:A盘8,STM32参考资料1,STM32CubeH7固件包)里面拷贝,不过由于固件包里面的CMISIS兼容了太多芯片,导致非常大(300多MB),因此我们根据实际情况,对其进行了大幅精简,精简后的CMSIS文件夹大小为2.3MB左右。精简后的CMSIS文件夹大家可以在:A盘4,程序源码1,标准例程-寄存器版本 文件夹里面的任何一个实验的Drivers文件夹里面拷贝过来。
9 H  a  i# R! j, H- k2 _SYSTEM文件夹,用于存放正点原子提供的系统级核心驱动代码,如:sys.c、delay.c和usart.c等,方便大家快速搭建自己的工程。该文件同样可以从:A盘4,程序源码1,标准例程-寄存器版本 文件夹里面的任何一个实验的Drivers文件夹里面拷贝过来。! G5 ?! t' k9 I8 m( O" K
执行完以上操作后,Drivers文件夹最终结构如图6.1.1.3所示:: R$ r/ m4 j! x2 Z

& Y, T4 k% [" ^ ca5c4eb92f3747e8a0ae850002e63fdc.png
  }1 }2 }, A3 K+ ?5 i( R
6 u& B: U. Z. P图6.1.1.3 工程根目录文件夹, d" V' H9 S9 r  }
0 t8 N! ]0 A9 \2 Q$ G
Middlewares文件夹
. i- g, e, e+ C# C* R) U6 h  f该文件夹用于存放正点原子和其他第三方提供的中间层代码(组件/Lib等),如:USMART、MALLOC、TEXT、FATFS、USB、LWIP、各种OS、各种GUI等等。本章我们暂时用不到该文件夹,不过可以先建好备用,后面的实验将会陆续添加各种文件。
# t5 d! o/ F/ g" g" F0 ~
. W3 o' B2 t& R$ Q" IOutput文件夹
3 M6 ?6 m$ v' n" J" b) p该文件夹用于存放编译器编译工程输出的中间文件,比如:.hex、.bin、.o文件等等。这里不需要操作,后面只需要在MDK里面设置该文件夹为编译过程中间文件的存放文件夹就行。; y7 ~; @, b) F

% N  O# _3 p  z7 z9 DProjects文件夹
" }& g/ E4 ^# C  ^6 ^3 p
该文件夹用于存放编译器(MDK、IAR等)工程文件,我们主要用MDK,为了方便区分,我们在该文件夹下新建:MDK-ARM文件夹,用于存放MDK的工程文件,如图6.1.1.4所示:9 b3 s! k: r: u4 e
3 e& B; {- _7 U) j2 I4 K' [9 E
c94f3aa27b3348ffa169e87dba26cbfb.png
# k& c3 E4 l& u2 [! S( p# I7 t  f  b6 Y) m6 V8 G8 H
图6.1.1.4 在Projects文件夹下新建MDK-ARM文件夹! l: u/ ?* }" ^+ [: p
- F' f: s6 d& E& c5 M
User文件夹$ E- Q7 ^/ u$ c$ }/ X- z
该文件夹用于存放用户编写的代码,如:main.c等。目前还没有任何代码,所以暂时为空即可。  @: m" s7 y$ [/ @7 E9 i$ K: M
* l0 R* n0 ?; V5 g: K
6.1.2 新建一个工程框架
* \' b4 n$ u: j! V  I; u4 v首先,打开MDK软件。然后点击ProjectNew uVision Project如图6.1.2.1所示:- b  u" [9 ^) B0 O, `# \# h

; S6 |* R- @* v0 M6 P: i* a d640f3baaa874fa0ba12ef18f81db008.png 3 E3 F. L1 h. l( K; m
0 i6 [. _3 I% G
图6.1.2.1 新建MDK工程
- J- Q* v4 h+ Y% P" O然后弹出工程命名和保存的操作窗口,我们将工程文件保存路径设置在上一节新建的工程文件夹内,具体路径为:桌面实验0-2,新建工程实验-寄存器版本ProjectsMDK-ARM,工程名字我们取:atk_h750,最后点击保存即可。具体操作窗口如图6.1.2.2所示:# g: x1 r, g0 m/ P0 D, O
- l6 I! U# Z' F  G% a
7be029d0b4ea433f899085ffd811b81b.png " d( o9 ?( ^4 \3 V+ l/ D9 h
- C- }8 X% I/ f+ {# R# ^1 J
图6.1.2.2 保存工程界面
' J: l7 Q" `) K3 [之后,弹出器件选择对话框,如图6.1.2.3所示。因为正点原子MiniPRO STM32H750开发板所使用的STM32型号为STM32H750VBT6,所以我们选择:STMicroelectronicsSTM32H7 SeriesSTM32H750STM32H750VBTx(如果使用的是其他系列的芯片,选择相应的型号就可以了,特别注意:一定要安装对应的器件pack才会显示这些内容哦!!如果没得选择,请关闭MDK,然后安装 A盘:6,软件资料\1,软件\MDK5\ Keil.STM32H7xx_DFP.2.5.0.pack这个安装包后重试)。
+ D+ v/ i2 l3 G% G/ z( R7 ^2 ^# C6 b7 i, [
430d60a3433a4e6db0e2979a87976ff7.png 7 j9 a0 d# Y8 P, M

% _6 S0 X( i2 H# t$ N0 c图6.1.2.3 器件选择界面1 U9 k4 e+ Q% U/ {. p
点击OK,MDK会弹出Manage Run-Time Environment对话框,如图6.1.2.4所示:- ~7 Z6 i0 F. T  ?

# _5 J5 B# d% u" @ fb9db7b30ef74a84bb3c63f3a80437b3.png
. Q6 V' m0 ^& `4 I: N( {/ c
/ Y7 u& ~. N+ A: H图3.2.1.4 Manage Run-Time Environment界面, L/ R- e! ]) \2 _2 }
这是MDK5新增的一个功能,在这个界面,我们可以添加自己需要的组件,从而方便构建开发环境,不过这里我们不做介绍。所以在图6.1.2.4所示界面,我们直接点击Cancel,即可,得到如图6.1.2.5所示界面:
. r" m* _6 U6 Y& K5 f* q
8 l4 N4 ?* l, W% m- |3 P# U, m) T 63be7dbc447e407b911baf24bff8d27f.png ) |5 m  W3 Z8 _0 @
& j/ ^* a& g7 V2 x, k
图6.1.2.5 工程初步建立8 r( Z  o4 Y, @
此时,我们打开MDK-ARM文件夹,会看到MDK在该文件夹下自动创建了3个文件夹(DebugConfig、Listings和Objects),如图6.1.2.6所示:& K  S7 v5 z, V& y: `6 O% ^
3 r- R" |5 p" I. r+ m: s1 W9 O" @6 V
e56180442cef468386f0c49a1df37fa5.png
3 `) c8 a" R- w! R1 P" @1 @% k% s
: ^* Y/ i3 b) k7 k/ l8 y  y; e, H图6.1.2.6 MDK新建工程时自动创建的文件夹
& G# q  O* d2 H) Q$ ^; u这三个文件夹的作用如表6.1.2.1所示:- T4 @+ Z( e( D; j/ E2 f- B% B" E( X

5 I' O* l7 n% V1 N( G 8d36136524f943c6b335f5659bd8e68b.png ; Z" u, v& H( c' V. k4 W3 o. q! l# }- a

; b, t6 G3 }7 @, x: E# r) I表6.1.2.1 三个文件夹及其作用2 C6 F' s) b/ y- b
编译过程产生的链接列表、调试信息、预览、lib等文件,统称为中间文件。为了统一管理,方便使用,我们会把输出在Listings和Objects文件夹的内容,统一改为输出到Output文件夹(通过魔术棒设置),我们先把MDK自动生成的这两个文件夹(Listings和Objects)删除。) @+ t/ I4 B+ L+ b0 J; [  h
至此,我们还只是建了一个框架,还有好几个步骤要做,比如添加文件、魔术棒设置、编写main.c等。* g( x4 C6 J) _  E3 y+ p

: C% n$ n5 p! ~5 z2 x, G) j9 Q6.1.3 添加文件/ m5 }# B9 m: ?3 `6 T
本节将分3个步骤:1,设置工程名和分组名;2,添加启动文件;3,添加SYSTEM源码。7 d( H" ^% ]& ?

- \4 e( _' v2 C- m% l& \1. 设置工程名和分组名
/ |8 M( b6 s0 T" u在ProjectTarget上右键,选择Manage Project Items…(方法一)或在菜单栏点击品字形红绿白图标(方法二)进入工程管理界面,如图6.1.3.1所示:
% |  J- ~  F7 K1 H7 w& H* |3 ^' A# h' D0 d4 s0 o
08d6689b9778434d93c37419ff24a997.png
6 m* l1 Q* n4 }+ B
$ I4 W  t: L- o+ M0 G, F0 J6 |图6.1.3.1 进入工程管理界面  Z! }7 l5 L) H: ?. G7 [
在工程管理界面,我们可以执行设置工程名字(Project Targets)、分组名字(Groups)以及添加每个分组的文件(Files)等操作。我们设置工程名字为:Template,并设置四个分组:Startup(存放启动文件)、User(存放main.c等用户代码)、Drivers/SYSTEM(存放系统级驱动代码)、Readme(存放工程说明文件),如图6.1.3.2所示:
1 A4 H) t( U! D6 \6 Q. _& R6 i& v; l! f) X
c06f439a752449e88028b53d2a3170b6.png
, X' z) N5 u  E) ~& f+ I4 I' j8 {& d/ j/ X% R0 o
图6.1.3.2 设置工程名和分组名
4 o9 D3 V% m$ y, |设置好之后,我们点击OK,回到MDK主界面,可以看到我们设置的工程名和分组名如图6.1.3.3所示:( W3 k( O2 b  B+ ]: E1 s8 `

, r! t+ Q  D# L% _: U. m! W- g" s 0ca53d06ca3f4d10b1198a8eefe2f443.png * a1 O. ~6 I* V
8 |' R: w( S( x7 s& y" W" P
图6.1.3.3 设置成功: C3 E2 Y' P) u. r) p4 K
这里我们只是新建了一个简单的工程,并没有添加BSP、Middlewares等分组,后面随着工程复杂程度的增加,我们需要一步步添加对应的分组。* k# I- J) A1 U
注意:为了让工程结构清晰,我们会尽量让MDK的工程分组和我们前面新建的工程文件夹对应起来,由于MDK分组不支持多级目录,因此我们将路径也带入分组命名里面,以便区分。如:User分组对应User文件夹里面的源码,Drivers/SYSTEM分组,对应Drivers/SYSTEM文件夹里面的源码,Drivers/BSP分组对应Drivers/BSP文件夹里面的源码等。
8 x0 u9 M( W/ N! f+ f5 w& [, J% P$ m7 H6 ^
2. 添加启动文件
+ q0 {9 p. o. I' O; Y% D. ~! [启动文件(.s文件)包含STM32的启动代码,其主要作用包括:1、堆栈(SP)的初始化;2、初始化程序计数器(PC);3、设置向量表异常事件的入口地址;4、调用main函数等,是每个工程必不可少的一个文件,我们在本书第九章会有详细介绍。. y: l* x) `- s! d. O
启动文件由ST官方提供,存放在STM32CubeH7软件包的:DriversCMSISDevice STSTM32H7xxSourceTemplatesarm文件夹下。因为我们开发板使用的是STM32H750VBT6,对应的启动文件为:startup_stm32h750xx.s,为了节省空间,在精简版CMSIS文件夹里面我们把其他启动文件都删了。而且,为了更好的匹配寄存器版本代码,我们对startup_stm32h750xx.s做了2处修改:
5 \; f6 P' _9 d' |) [. X1,我们用不到编译器的内存管理函数,为节省内存,将Heap_Size改成 0,源码如下:
: L3 g0 s2 ?2 {2 T% a;未用到编译器自带的内存管理(malloc,free等),设置Heap_Szie为0- c' k5 Z" y! P+ U, ]( V  Y
Heap_Size EQU 0x00000000
9 r4 c; ~2 }$ A+ d2,寄存器代码不需要调用SystemInit函数,因此修改Reset_Handler函数,去掉SystemInit调用,并且还加入了开启 STM32H750 硬件 FPU 的代码,具体源码如下:& {$ [" }8 I; ?  U$ O
$ k% p7 H* u6 r+ I: Z
  1. Reset_Handler    PROC1 P: c# t( E8 F3 e' y
  2.                     EXPORT  Reset_Handler                    [WEAK] + r6 z) _) l, v" W7 V
  3.     ;IMPORT  SystemInit4 |4 h5 q. {! c0 s9 r2 \& e
  4.     ;寄存器代码,不需要在这里调用SystemInit函数,故屏蔽掉,库函数版本代码,可以留下* B1 K' O0 y, n, i6 W' k' j$ t
  5.     ;不过需要在外部实现SystemInit函数,否则会报错.; K* t; O8 ^  v( Q6 b
  6.     IMPORT  __main
    . H7 H( p  [* ], \( l  C

  7. & Q( c& r, c% L7 O0 U
  8.         IF {FPU} != "SoftVFP"  ;通过Target选项卡的Floating Point Hardware选项来控制
    + K: d: [$ j! F6 G- o& n1 t; S5 ~
  9.                                    ;如果选择:Not Used,则不编译以下代码(到ENDIF结束)& E( d8 v) q! G7 M& g& ?2 C
  10.                                    ;如果选择:Use Single/Double Precision,则编译以下代码# e7 ]% P3 b( o5 d; Y0 m0 _1 v" K
  11.         ;Enable Floating Point Support at reset for FPU; e, b- K# \, D$ l4 P
  12.         LDR.W  R0, =0xE000ED88       ; Load address of CPACR register
    " x& h7 Q5 b+ s* H( d; X$ A
  13.         LDR    R1, [R0]                ; Read value at CPACR
    & Z6 r+ j8 }; S9 s* b! G
  14. ; Set bits 20-23 to enable CP10 and CP11 coprocessors
    ' r9 ~* u) c1 \* a3 v& I! w
  15.         ORR    R1,  R1, #(0xF <<20)  ' _8 F4 u6 h7 i
  16.         ; Write back the modified CPACR value
    ! a  J( L+ F5 x1 h7 z# z: F
  17.         STR    R1, [R0]                ; Wait for store to complete
    - m# y; C" P# q7 Z- e
  18.         DSB; q# G2 m% G( l- T3 n" l
  19.                                          ;针对OS应用,FPU寄存器全部由OS压栈保存,关闭硬件压栈
    " c* u: Z: D+ {9 `$ L5 @1 p0 ?
  20.                                          ; Disable automatic FP register content
    0 |3 @2 O, |4 j- }- ?. o
  21.                                          ; Disable lazy context switch: p0 J; n; _6 _1 _9 A- U: O
  22.         LDR.W  R0, =0xE000EF34       ; Load address to FPCCR register
    # i) Z, [# f) a; e' l) R
  23.         LDR    R1, [R0]7 U# d+ r- N, g+ W3 `- }
  24.         AND    R1,  R1, #(0x3FFFFFFF); Clear the LSPEN and ASPEN bits/ A; s6 |9 |/ A7 g* u4 D
  25.         STR    R1, [R0]
    + H: b* q, }6 e( C6 X" {5 D0 q
  26.         ISB                              ; Reset pipeline now the FPU is enabled, L# t' R0 S& ?: p8 O: W3 U3 h3 V
  27.         ENDIF4 E4 ]- C- t9 G. w) N( Z. E

  28. ' u' g/ }# Z; I) Y, Y
  29.         ;LDR     R0, =SystemInit             ;寄存器代码,未用到,屏蔽/ t6 u7 V$ g) H* ]* v3 |
  30.         ;BLX     R0                      ;寄存器代码,未用到,屏蔽
    . b1 ~3 V6 }/ U; g& k' G/ D
  31.         LDR      R0, =__main
    $ a* e2 v: c4 f! Q
  32.         BX       R0
    5 A; |- J9 X) C% A/ e7 A  ]# b+ Y' A  v
  33.         ENDP
复制代码

$ v1 m# X  _2 ~$ _7 p这段代码,我们主要加入了开启 STM32H750 硬件 FPU 的代码,以使能 STM32H750 的浮点运算单元,并关闭硬件自动压栈。其中,0xE000ED88 就是协处理器控制寄存器(CPACR)的地址,该寄存器的第 20~23 位用来控制是否支持浮点运算,这里我们全设置为 1,以支持硬件浮点运算。关于 CPACR 寄存器的详细描述,见《STM32H7 编程手册.pdf》第 4.7.1 节。另外,寄存器版本,我们还屏蔽了 SystemInit 函数的调用,如果是HAL库版本,可以取消这个函数的注释,并在外部实现 SystemInit 函数。0 V& L6 v# w, h! C; T7 F4 @$ x5 Z
特别注意:我们在汇编代码里面使能了 FPU,所以在 MDK 里面,我们也要设置使用 FPU,否则可能代码会无法运行,设置方法如下:选择 Options for Target ‘Target1’,打开 Target 选项卡,在 Code Generation 里面,选择 Double Precision,如图6.1.3.4 所示:
3 @& H+ F1 W0 h& W* I- m
. E7 w+ p8 g) o2 f+ {+ p, R 501ae5395b194fff9013556fb9907b26.png
9 k2 E; r! F4 A$ s( Y
- \0 r- A- [; q8 K图6.1.3.4 MDK开启浮点运算- y3 i3 ]7 O, ^7 v9 |; `, n, X
关于启动文件的说明,我们就介绍这么多,接下来我们看如何添加启动文件到工程里面。我们有两种方法给MDK的分组添加文件:1,双击Project下的分组名添加。2,进入工程管理界面添加。
* B$ p8 l$ U& j1 q$ E4 y5 U这了我们使用方法1添加(路径:实验0-2,新建工程实验-寄存器版本\Drivers\CMSIS
# B0 j* z. u& d' [, H; x/ kDevice\ST\STM32H7xx\Source\Templates\arm),如图6.1.3.5所示:
* Q9 F5 f8 Z3 I6 v; k2 ]  y+ E0 I
28c2660d1698477a864fa6ce5c85e348.png
- w( `4 B2 @2 F0 ?0 V9 }! M( j4 D% D
图6.1.3.5 双击分组添加启动文件(startup_stm32h750xx.s). B4 o7 W  N; ], J5 Q* U! n
上图中,我们也可以点击Add按钮进行文件添加。添加完后,点击Close,完成启动文件- ^$ ~5 {: c* g# o
添加,得到工程分组如图6.1.3.6所示:4 }+ z  L; S- S
9 Q* x3 |! B# W1 e
35719c26891c442ab684e3c5f5982f3a.png
! _: _2 k# f, m* o7 E( O9 c2 |+ M0 S+ g
图6.1.3.6 启动文件添加成功4 u, Q; E" [/ r& w1 c' g

4 p1 q$ n! T5 O; o1 y! n( P6 W) \3. 添加SYSTEM源码& V3 u2 m' G/ Y) I+ h- L* S4 e
这里我们在工程管理界面(方法2)进行SYSTEM源码添加。点击:按钮,进入工程管理界面,选中Drivers/SYSTEM分组,然后点击:Add Files,进入文件添加对话框,依次添加delay.c、sys.c和usart.c到该分组下,如图6.1.3.6所示:; t; L5 Q' N# l
( I" ]0 b( t. @! z0 D- @
7fa6e18f95134622a0ba12f34a804ae1.png 6 ?# B, B/ V9 v3 w, j1 {& M

' s# p. g6 r( n图6.1.3.6 添加SYSTEM源码9 d8 w& H1 L* a. D1 c! `$ Q  c
注意:这些源码都是在第6.1.1小节的第二步拷贝过来的,如果之前没拷贝,是找不到这些源码的。添加完成后,如图6.1.3.7所示:
" u5 J' H4 }/ C' H# i
& S7 `0 O- L) _2 G" M9 W 0990065871b740369c4cfd1b94100f83.png 1 `  }, h# @: _+ S
% _' \9 t& L; x$ M
图6.1.3.7 SYSTEM源码添加完成: ~) M& \+ y& r* w; C; H

4 N7 J; K7 Q8 g6 V7 \: R4 Z6.1.4 魔术棒设置* D  _5 K( _# @5 G) k
为避免编写代码和编译报错,我们需要通过魔术棒对MDK工程进行相关设置。在MDK主界面,点击:(魔术棒图标,即Options for Target按钮),进入工程设置对话框,我们将进行如下几个选项卡的设置。
$ @% O2 v2 x) }2 f# e" k% H8 Z' d$ S4 x. v: Q
1.设置Target选项卡" l6 C# X, n  ~- A7 N1 G0 ]
在魔术棒Target选项卡里面,我们进行如图6.1.4.1所示设置:) t5 q4 q8 N4 |6 v5 Y( i7 c4 W
, p. i: H& V# t3 N
9d749fdd08a64f3fab69aa5da05f1eef.png
  p6 F/ w3 q2 y5 J" ?
7 G# u( x6 \2 Z* H4 M+ @: H! }图6.1.4.1 Target选项卡设置
* c5 M! s( T/ {. |( S) J上图中,我们设置芯片所使用的外部晶振频率为8Mhz,选择ARM Compiler版本为:Use default compiler version 5(即AC5编译器)。
# t5 B' p8 E* V( Q6 ~' e6 h这里我们说明一下AC5和AC6编译的差异,如表6.1.4.2所示:- i) g2 p- m0 k4 @$ f9 y

- C, x! a8 W7 _) K/ Y- {, f ed9756bfc54246f08868dda926a09845.png
$ s% B! M% r3 A8 c) M0 C& W  K3 |( X8 q! w9 V" K
表6.1.4.1 AC5&AC6简单对比, o; M% b: L0 N2 U1 ^
由于AC5对中文支持比较好,且兼容性相对好一点,为了避免不必要的麻烦,我们推荐大家使用AC5编译器。为了让大家自由选择,我们正点原子的源码,也是支持AC6编译器的,不过在选项卡设置上稍有差异,具体差异如表6.1.4.2所示:
; T! F% j1 s9 q, K- a3 t1 S, s1 O( H8 |0 c' N
d630248ef0134601bd580c018d332fa5.png
+ Q2 {6 A' e7 [1 _/ n3 p& |) E2 V% F: F9 `; J- l$ t
表6.1.4.2 AC5&AC6设置差异
. \/ ]! m) k# T+ |) z2. 设置Output选项卡
2 ]! b) I7 O! `- L1 q' W1 l3 N7 f* M在魔术棒Output选项卡里面,进行如图6.1.4.2所示设置:0 a! Z9 K0 o3 e" s" O  V  l$ h0 q& Y
! i  V' B9 w4 Q, e! z
483b9f614c394f8399284373848354f5.png
1 Q* `' O7 v3 u" k  B
$ g8 H4 |9 S* s, n" M( G, R图6.1.4.2 设置Output选项卡) ~  B! m5 W$ h6 f3 E+ V
注意,我们勾选:Browse Information,用于输出浏览信息,这样就可以使用go to definition查看函数/变量的定义,对我们后续调试代码比较有帮助,如果不需要调试代码,则可以去掉这个勾选,以提高编译速度。
5 L4 P9 I- ^7 v/ p) s8 ]. S6 J" v/ G
3. 设置Listing选项卡
0 b1 H5 N; D- I9 y+ Y& K在魔术棒Listing选项卡里面,进行如图6.1.4.3所示设置:
$ D& N/ a% a* A2 `9 ]$ F
# R6 Q7 O4 ]- h5 W0 V 814fd210a41149238db33d210c5dac70.png 2 m1 E! U1 \: q# H, k* F4 u% Z
6 W) \& g4 i2 J/ ?- H* H
图6.1.4.3 设置Listing选项卡
( D6 o. |1 E0 |% P8 U, ?, V1 b; U经过Output和Listing这两步设置,原来存储在Objects和Listings文件夹的内容(中间文件)就都改为输出到Output文件夹了。% s0 D# i+ S$ ?$ o

; O$ Y  G7 w, p  k& N4. 设置C/C++选项卡
* |) }4 X4 F. l在魔术棒C/C++选项卡里面,进行如图6.1.4.4所示设置:, y4 ^* I# h$ [' Q

2 ^& G! ^$ _% I" E: K. ~ d9ffcecf23844052b249ef73ea7a9bfe.png
% u& x/ v& n- y4 v) F7 @0 X  ~% }$ p/ G! C% m! q6 b
图6.1.4.4 设置C/C++选项卡! G' L7 N2 u, S9 ]
在②处设置了全局宏定义:STM32H750xx,用于定义所用STM32型号,在stm32h7xx.h里面会用到该宏定义。
3 q1 W9 d0 z8 l1 M% s  e: a4 D在③处设置了优化等级为-O0,可以得到最好的调试效果,当然为了提高优化效果提升性能并降低代码量,可以设置-O1~-O3,数字越大效果越明显,不过也越容易出问题。注意:当使用AC6编译器的时候,这里推荐默认使用-O1优化。9 r* a3 g9 B3 T
在④处勾选C99模式,即使用C99 C语言标准。# P5 d4 S0 N" @5 c* n( H- p
在⑤处,我们可以进行头文件包含路径设置,点击此按钮,进行如图6.1.4.5所示设置:
$ |$ E% p" ~+ B. Z' U) ^; j, c% ~+ b8 o
1 E* V! B1 W; M3 w" x! B* W, x 53446bf5a8cd4a9b9f03a5f351437b4d.png - I4 Q0 v  @! g, f- g  J

+ x% X  d4 s) n, }5 I! G图6.1.4.5 设置头文件包含路径5 V2 f. H7 k& S5 Z% E1 Y
上图中我们设置了4个头文件包含路径,其中3个在Drivers文件夹下,一个在User文件夹下。为避免频繁设置头文件包含路径,正点原子最新源码的include全部使用相对路径,也就是我们只需要在头文件包含路径里面指定一个文件夹,那么该文件夹下的其他文件夹里面的源码,如果全部是使用相对路径,则无需再设置头文件包含路径了,直接在include里面就指明了头文件所在。
' F& T; ?( h2 G关于相对路径,这里大家记住3点:
; l1 m- ]7 @- x, S9 v$ G$ d1,默认路径就是指MDK工程所在的路径,即.uvprojx文件所在路径(文件夹)7 D( r! w" W7 {! J6 [% w3 r  e1 n1 {
2,“./”表示当前目录(相对当前路径,也可以写做“.\”)0 e* v$ ]& }- x( ?8 A+ A. m
3,“…/”表示当前目录的上一层目录(也可以写做“…\”)
, a( a; n* I( I9 R# y# @举例来说,上图中:…\Drivers\CMSIS\Device\ST\STM32H7xx\Include,前面两个“…\”,表示Drivers文件夹在当前MDK工程所在文件夹(MDK-ARM)的上2级目录下,具体解释如图6.1.4.6所示:
9 C  R; m1 _$ P9 B2 p+ x4 ]4 h! z1 [2 M9 K
e4a85b28842d4a1f8e63850283a1b826.png
( B4 x7 Q/ e7 r( i  c. ?# D8 _, Y1 x( I# H# C) b( {$ h
图6.1.4.6 …\Drivers\CMSIS\Device\ST\STM3H7xx\Include的解释* f/ c9 @4 c, H! b! @1 f8 Q1 u
上图表示根据头文件包含路径:…\Drivers\CMSIS\Device\ST\STM32H7xx\Include,编译器可以找到⑥处所包含的这些头文件,即代码里面可以直接include这些头文件使用。* k: y2 ]+ e7 e
再举个例子,在完成如图6.1.4.5所示的头文件包含路径设置以后,我们在代码里面编写:
% d% O# E- K1 n7 O( S9 {/ o#include “./SYSTEM/sys/sys.h”% C1 G1 U7 v% L
即表示当前头文件包含路径所指示的4个文件夹里面,肯定有某一个文件夹包含了:SYSTEM/sys/sys.h的路径,实际上就是在Drivers文件夹下面,两者结合起来就相当于:
+ A3 l. s' S9 S# l# ^$ T#include “…/…/Drivers/SYSTEM/sys/sys.h”
0 Z* |) O8 W  c  f6 s这就是相对路径。它既可以减少头文件包含路径设置(即减少MDK配置步骤,免去频繁设置头文件包含路径的麻烦),同时又可以很方便的知道头文件具体在那个文件夹,因此我们推荐在编写代码的时候使用相对路径。
, l0 h' }# R3 q; C) B: b6 C& g关于相对路径,我们就介绍这么多,大家搞不明白的可以在网上搜索相关资料学习,也可以在后面的学习,分析我们其他源码,慢慢体会,总之不难,但是好用。
' a8 ?0 O* ?) y7 m最后,我们如果使用AC6编译器,则在图6.1.4.4的Misc Controls处需要设置:-Wno-invalid-source-encoding,避免中文编码报错,如果使用AC5编译器,则不需要该设置!!
) ]2 J% `6 g" M9 p+ u
' w! `$ J+ z4 j* v' X! g5. 设置Debug选项卡
% c/ Q) U2 A$ W8 r9 @, W在魔术棒Debug选项卡里面,进行如图6.1.4.7所示设置:, q; J7 B% W) |& b6 j% z0 c% n

# j- c9 R# x+ y. w 5b5a155e65ff42ed9793787102114d5d.png
& P. _: T- f* {. v) x. s( M5 X
% Z9 c4 x8 |8 b0 D, c图6.1.4.7 Debug选项卡设置
6 k0 ~* y9 D. N; K) U图中,我们选择使用:CMSIS-DAP仿真器,使用SW模式,并设置最大时钟频率为10Mhz,以得到最高下载速度。当我们将仿真器和开发板连接好,并给开发板供电以后,仿真器就会找到开发板芯片,并在SW Device窗口显示芯片的IDCODE、Device Name等信息(图中⑤处),当无法找到时,请检查供电和仿真器连接状况。# E3 D0 H. h) |% K# l. z" L

; q4 [, F( u- ?- d- |: s' d  u6. 设置Utilities选项卡
$ \; n9 D1 q1 J  D! u$ e4 Z在魔术棒Debug选项卡里面,进行如图6.1.4.8所示设置:
) f! E1 x1 B7 x  x+ Z# N& D# }0 A! p) s, X
e87266b475034e129bbaf27880dd66d5.png
# V% C3 M' h3 |( e' O9 E; P3 c7 Q$ G/ V5 g; r+ j
图6.1.4.8 Utilities选项卡设置+ t2 P# {0 h8 F! J# p
图中⑥处下载算法STM32H750,是MDK默认添加的,针对STM32H750系列产品。除此之外,我们还要添加STM32H750VB_W25Q64@ALIENTEK.FLM算法,点击⑦处按钮添加即可。添加好算法后,设置算法使用的 RAM 地址和大小,这里设置的起始地址为:0X2000 0000(DTCM),大小为:0X3000。必须按这个大小设置,否则下载会出错(无法加载算法)。
  g; V" G/ Z' _, Q/ H* S+ ?+ M( e" H+ k$ G: S5 {4 Y
7. 添加分散加载文件
) [( \, a0 H+ p) S* v" @  Y由于STM32H750VBT6芯片内部的FLASH的空间比较少(只有128KB)。对于大的工程,这个FLASH空间是不够用的,为了解决这个问题,同时方便后续工程的新建,我们统一使用分散加载的方式来决定FLASH内存的分配,而不用MDK默认的设置。关于分散加载是什么?我们后面8.3小节会讲解,请大家先跟着我们把新建工程完成。
7 T; c# j5 k- c% B分散加载的文件已经为大家准备好了,可以在实验0-2,新建工程实验-寄存器版本\User\SCRIPT,或者在(A盘)/程序源码/STM32启动文件/分散加载_寄存器版本/SCRIPT中拷贝qspi_code.scf文件到我们的工程User\SCRIPT路径下,如图6.1.4.9所示。, X" O" g; l9 U8 z& i! Q% }2 h, d

  A: H- p% U% k' N; Z' g 871b7faf48ec4f43b1dd55a7066e89c9.png 3 U& k: B( V7 U  Y. m4 \0 g
9 W9 `0 a$ c8 ]
图6.1.4.9 拷贝分散加载文件到工程
) \7 W" S* Y8 B/ D7 H7 H3 S3 l注意:这里的分散加载文件寄存器跟HAL库是不一样的,我们建立寄存器工程,所以必需用寄存器版本的分散加载文件。
% M/ u  x. ?- D' t+ m! V; w接下来我们需要对MDK进行配置,相当于把分散加载文件关联到工程里。方法:点击魔术棒, Linker选项卡取消勾选:Use Memory Layout from Target DialogScatter File路径选择SCRIPT文件夹 选择qspi_code.scf文件,然后,在disable Warnings一栏,添加:6314,6329,屏蔽6314和6329这两个警告。如不屏蔽,当分散加载里面有某些段(section)没用到,则会报警告,所以我们需要屏蔽这两个警告。如图6.1.4.10所示。. U( h1 }7 g0 \. G: L6 e7 y6 m

3 P5 y7 y, O$ W/ @$ P0 ?& U( u* u b07d3ab934674dc9986a7dbb72d7b811.png / Q. Y" E8 \, N9 y
* v9 [8 W& S6 e% b9 u3 n1 {9 W
图6.1.4.10 添加分散加载文件
" A# h# B. \, j至此,添加分散加载文件的相应操作就完成了。  p  o; {- W! a$ G
7 J% u8 f8 u' W! }% g1 j* n5 l
6.1.5 添加main.c,并编写代码3 q. A- d1 C) k7 ]& h
在MDK主界面,点击:,新建一个main.c文件,并保存在User文件夹下。然后双击User分组,弹出添加文件的对话框,将User文件夹下的main.c文件添加到User分组下。得到如图6.1.5.1所示的界面:
3 K( q9 C# `- R( ]4 a& a% O7 h+ Z. m! r, E5 m
6c5a8a9ba304460593c5193a8f1c4bb6.png ; T9 W0 U2 Q" S1 q1 j
& L# ~' n7 Y% g) s! w
图6.1.5.1 在User分组下加入main.c文件: |9 Y6 B) b: ]5 B% w$ F) n9 i
至此,我们就可以开始编写我们自己的代码了。我们在main.c文件里面输入如下代码:: `+ Y/ p6 |" H* k
8 o8 ]+ w  E: j
  1. #include "./SYSTEM/sys/sys.h"
    $ Q, O9 U* w5 Z8 m7 c
  2. #include "./SYSTEM/usart/usart.h"
    1 j: _3 Z2 u3 f2 b+ |
  3. #include "./SYSTEM/delay/delay.h", S( L& I7 S( [9 X. q
  4. int main(void)
    & {$ m% p% x$ @! W1 k% C, Z5 @5 t
  5. {5 z" h0 s  i7 i- i9 _
  6.     uint8_t t = 0;" A2 d- H& v. J! X; k8 q7 ?, S. J  s) W
  7.     sys_stm32_clock_init(240, 2, 2, 4);         /* 设置时钟, 480Mhz */
    % Z: w& R) s* Q) H/ ]5 c
  8.     delay_init(480);                                /* 延时初始化 */
    ) p3 D2 |' I# [" j' Q
  9.     usart_init(120, 115200);                               /* 串口初始化为115200 */
    " q5 l9 e& u0 m3 x% o0 f( Q6 q6 c( x3 G
  10.     while (1)% R* n4 V$ B9 m4 m1 g
  11.     {; O$ E- ^& y+ t1 N
  12.         printf("t:%d\r\n", t);
    & b$ U: `5 z/ A3 l# N# v
  13.         delay_ms(500);
    + @) a# @. x; W! I# E
  14.         t++;$ N/ v9 ]* }4 f6 S' D$ L- |
  15.     }
    2 j. u; k( G$ \$ l, {% V! a- I* m6 I4 a
  16. }
复制代码
5 z$ m  G  J' j" }+ ]. t2 @
此部分代码,在A盘4,程序源码1,标准例程-寄存器版本 实验0 基础入门实验实验0-2,新建最工程实验-寄存器版本Usermain.c里面有,大家可以自己输入,也可以直接拷贝。强烈建议自己输入,以加深对程序的理解和印象!!
# b, G/ `( o8 _, ^9 K( t- i注意,这里的include就是使用的相对路径,关于相对路径,请参考前面C/C++选项卡设置章节进行学习。8 @% k: u! C3 y, g/ `
编写完main.c以后,我们点击:(Rebuild)按钮,编译整个工程,编译结果如图6.1.5.2所示:) A5 L, Q9 \! W2 x( {9 X, C, U

) [9 C% t! e8 Z/ d2 u. R$ L ad51db4406df4dda8aeac90bcb01c68f.png 9 H) Y) p  G% s' w; L0 j) h

1 I3 S& L  X- i  U6 V图6.1.5.2 编译结果7 O9 t" Q# e# [9 t* ]+ `
编译结果提示:代码总大小(Porgram Size)为:FLASH占用4508字节(Code + RO + RW),SRAM占用2360字节(RW + ZI);并成功创建了Hex文件(可执行文件,放在Output目录下);编译0错误,0警告。& {1 k  E3 ]+ k6 H" K
注意:如果编译提示有错误/警告,请根据提示,从第一个错误/警告开始解决,直到0错误0警告。如果出错,很有可能是之前的操作存在问题,请对照教程找问题。5 U+ I; q3 I" b" I0 Z
另外,我们在Readme分组下还没有添加任何文件,由于只是添加一个说明性质的文件(.txt),并不是工程必备文件,因此这里我们就不添加了,开发板光盘的源码我们是有添加的,大家可以去参考一下。
" {: p/ L4 u. f) d8 k6 }至此,新建寄存器版本MDK工程完成。
" \( l; E7 ?6 s( N
: O2 }5 ~. `- r4 T, W$ q5 t! M6.2 下载验证3 l  c0 f* q& M. S' p0 N$ {7 @
这里我们继续使用DAP仿真器下载,在MDK主界面,点击:(下载按钮,也可以按键盘快捷键:F8),就可以将代码下载到开发板,如图6.2.1所示:8 e: u6 |  M" ~
5 O( s% V3 D6 \" N! x, L* K
bf93750fae454ed890eb647860352da0.png 6 I' p7 D0 P  ^- {

- y# A4 ^5 f, M' R: q图6.2.1 下载成功
. Q/ w" Q% ]& ?+ u1 M上图提示:Application running…,则表示代码下载成功,且开始运行。此时,我们打开串口调试助手,并设置好端口号(COM号)和波特率(115200),就可以看到打印出来的t值,如图6.2.2所示:' w+ o" {" P' R+ o0 o  E8 s

, m! L0 A2 A# \! q+ B) F d0f8f2c218504bb8b98afc2605558da8.png
, A' D3 P  [& z" }" t7 r! E, A
+ q# s- n( @+ o" e0 D图6.2.2 收到开发板发回来的数据$ Z5 l: D. H$ ?& X- e. A
说明我们的程序运行正常,下载验证无误。1 U' g& }) e! z
————————————————
- r5 E' c" f/ p+ ^* l8 }* N版权声明:正点原子
, ]8 t1 E4 v3 `+ B# ~. w/ q2 J) A6 q$ i9 M+ r/ A4 X' B/ B

) f8 ?# ~: w; w& x
收藏 评论0 发布时间:2022-10-4 18:21

举报

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