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

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

[复制链接]
STMCU小助手 发布时间:2022-10-4 18:21
新建寄存器版本MDK工程
+ x9 [4 F$ \) r( U通过前面几章的学习,我们对STM32有了个比较清晰的了解,本章我们将讲解新建寄存器库版本MDK工程的详细步骤。我们把本章新建好的工程放在光盘里,路径:4,程序源码\2,标准例程-HAL库版本\实验0 基础入门实验\实验0-2,新建工程实验-寄存器版本,大家在学习新建工程过程中间遇到一些问题,可以直接打开这个工程,然后对比学习。
) E! c" C( F% ^2 w# X  ?" v
! F) e( j% a% P; F0 n3 N/ ]& R6.1 新建寄存器版本MDK工程3 `% d7 @; P0 m/ t
本节我们将教大家如何新建一个STM32H750的MDK5工程。为了方便大家参考,我们将本节最终新建好的工程模板存放在A盘:4、程序源码\2,标准例程-HAL库版本\实验0 基础入门实验\实验0-2,新建工程实验-寄存器版本,如遇新建工程问题,请打开该实验对比。8 w  [% F* t5 s  V; E" E, @
整个新建过程比较复杂,我们将其拆分为5个步骤进行讲解,请准备大概2个小时时间,耐心细致的做完!对你后续的学习非常有帮助!% n1 C, _8 N0 |  K% V/ ^
在新建工程之前,首先我们要做如下准备:' T+ K0 @. ^" n$ Y4 F
1、 STM32Cube官方固件包:我们使用的固件包版本是STM32Cube_FW_H7_V1.6.0,固件包路径:A盘8,STM32参考资料1,STM32CubeH7固件包。
, V5 B+ Q9 }( J) M3 m# l& @6 O2、开发环境搭建:参考本书第三章相关内容。
8 H# }4 x! f& g: ?6.1.1 新建工程文件夹+ L# O' ~4 e9 O3 l  I% ^
新建工程文件夹分为2个步骤:1,新建工程文件夹;2,拷贝工程相关文件。
8 |$ [7 q/ k- W6 e+ T6 g# u( J2 R8 S8 H1 s$ ]2 u% f- O
1.新建工程文件夹
+ A0 S2 n8 R+ C' n首先我们在桌面新建一个工程根目录文件夹,后续的工程文件都将在这个文件夹里建立,我们把这个文件夹重命名为:实验0-2,新建工程实验-寄存器版本。如图6.1.1.1所示:. t: b2 X0 q/ r$ I2 T2 V8 y; y
17f331b18b564ccb83cbf64708d46fdb.png
' g' R7 m3 {) x$ M1 D4 q1 n) U1 k: s6 U2 F' V! o2 F
图6.1.1.1 新建工程根目录文件夹. L0 ?4 j/ E/ e7 K! A+ H
为了让工程的文件目录结构更加清晰易懂,我们会在工程根目录文件夹下建立以下几个文件夹,每个文件夹名称及其作用如表6.1.1.1所示:/ D. E% Z; a) m8 Z; v; Z5 ^* b7 _
3 A" u; A( ^# e+ T, ~6 n7 B  n
4a768110cc6241f9b0cf62cc6693af47.png   r$ C5 W8 k6 p* X" m/ I

- A3 O* r& O; @0 z$ w表6.1.1.1 工程根目录新建文件夹及其作用7 V$ H% _3 M5 ?& H+ K
新建完成以后,最后得到我们的工程根目录文件夹如图6.1.1.2所示。
% R2 |, I  y2 p  H: i% ^
: t9 x5 [; E- f" l) f7 d+ o' [; N 7972cce9e85c40d2bd17b44b532e5de7.png
$ X) u; y7 D  ]! n0 X
1 l3 s( L5 o  ^. e# t% I. ?图6.1.1.2 工程根目录文件夹2 P8 {. I# Z9 B# X
工程根目录及其相关文件夹新建好以后,我们需要拷贝一些工程相关文件过来(主要是在Drivers文件夹里面),以便等下的新建工程需要。
7 q5 E4 ~6 o$ h" g8 z1 I; ]/ i$ q. h6 T: z
2. 拷贝工程相关文件/ a1 O1 {9 p+ c! x9 d; h
接下来,我们按图6.1.1.2的根目录文件夹顺序介绍每个文件夹及其需要拷贝的文件。
% \3 p* G# M5 z5 q0 [, ^Drivers文件夹9 K, t6 A; R5 P3 o; y
该文件夹用于存放与硬件相关的驱动层文件,一般包括如表6.1.1.2所示的三个文件夹:
. t% D9 j/ z3 w3 m' b) C/ x9 A1 r+ v" K
e88e2b3145e946768dd71e8e1dbe1242.png % ~2 P5 H1 [# o7 S) J
4 Z% @) F2 m( l5 Q2 ]
表6.1.1.2 Drivers包含文件夹
9 O" L" e- O9 W/ lBSP文件夹,用于存放正点原子提供的板级支持包驱动代码,如:LED、蜂鸣器、按键等。本章我们暂时用不到该文件夹,不过可以先建好备用。, W4 e1 {* {2 ~3 ~3 q7 K- G
CMSIS文件夹,用于存放CMSIS底层代码(ARM和ST提供),如:启动文件(.s文件)、stm32h7xx.h等各种头文件。该文件夹我们可以直接从STM32CubeH7固件包(路径:A盘8,STM32参考资料1,STM32CubeH7固件包)里面拷贝,不过由于固件包里面的CMISIS兼容了太多芯片,导致非常大(300多MB),因此我们根据实际情况,对其进行了大幅精简,精简后的CMSIS文件夹大小为2.3MB左右。精简后的CMSIS文件夹大家可以在:A盘4,程序源码1,标准例程-寄存器版本 文件夹里面的任何一个实验的Drivers文件夹里面拷贝过来。1 W3 ]6 w0 V2 L7 V, y; ^
SYSTEM文件夹,用于存放正点原子提供的系统级核心驱动代码,如:sys.c、delay.c和usart.c等,方便大家快速搭建自己的工程。该文件同样可以从:A盘4,程序源码1,标准例程-寄存器版本 文件夹里面的任何一个实验的Drivers文件夹里面拷贝过来。
, b+ e4 T3 o$ b& b# m. w3 O0 F" ]执行完以上操作后,Drivers文件夹最终结构如图6.1.1.3所示:2 S+ m  w8 F  G4 }' b9 b( J
/ ]5 i2 R' S) O) M# N3 |
ca5c4eb92f3747e8a0ae850002e63fdc.png
; N1 C% T9 T6 `& F4 o! d. i* s* t, J8 f
图6.1.1.3 工程根目录文件夹
2 S* x" u  z. j& D% }7 g% V7 ?) A# p, D/ r
Middlewares文件夹
" s6 z7 O( }2 n: n/ y4 V该文件夹用于存放正点原子和其他第三方提供的中间层代码(组件/Lib等),如:USMART、MALLOC、TEXT、FATFS、USB、LWIP、各种OS、各种GUI等等。本章我们暂时用不到该文件夹,不过可以先建好备用,后面的实验将会陆续添加各种文件。
! v0 w  @6 ^" {& ^8 o4 g; B/ z
" A) [; p" E% d4 y3 q3 ?& R% w5 bOutput文件夹/ f" m& N( l! B  n
该文件夹用于存放编译器编译工程输出的中间文件,比如:.hex、.bin、.o文件等等。这里不需要操作,后面只需要在MDK里面设置该文件夹为编译过程中间文件的存放文件夹就行。  ^& \1 Z; H# B) c' x' _

1 f: U3 r( I% ?! Q! bProjects文件夹
' E; Y6 ]2 G% h' {8 i9 ?$ j
该文件夹用于存放编译器(MDK、IAR等)工程文件,我们主要用MDK,为了方便区分,我们在该文件夹下新建:MDK-ARM文件夹,用于存放MDK的工程文件,如图6.1.1.4所示:
2 g0 H; T9 s: P1 [7 i2 c" w
$ g6 ^" q5 T( e c94f3aa27b3348ffa169e87dba26cbfb.png % e" e4 C- z2 D' |- I
+ ?/ g0 d  u8 ?3 w% h
图6.1.1.4 在Projects文件夹下新建MDK-ARM文件夹4 B* I5 a* J1 g4 C* i! _, }% ^9 W
; ~* K5 D& ]- c1 S; Y
User文件夹
- ?& U# @: o) I' ^该文件夹用于存放用户编写的代码,如:main.c等。目前还没有任何代码,所以暂时为空即可。
7 i3 D9 T5 E* U! w
2 r& \" s. e8 t' M( B8 V6 w6 Y6.1.2 新建一个工程框架
. K3 h# b/ W8 q) @5 v8 \0 o首先,打开MDK软件。然后点击ProjectNew uVision Project如图6.1.2.1所示:' Z& ^- d3 s( v; ]; C

2 ^4 O- Y; R9 D; `# K; L7 \ d640f3baaa874fa0ba12ef18f81db008.png
) d' Y2 |5 f! v4 F; \- q
. P, o+ R- g+ ^3 |. O% C图6.1.2.1 新建MDK工程
+ g7 E% c" U9 ]! f  R然后弹出工程命名和保存的操作窗口,我们将工程文件保存路径设置在上一节新建的工程文件夹内,具体路径为:桌面实验0-2,新建工程实验-寄存器版本ProjectsMDK-ARM,工程名字我们取:atk_h750,最后点击保存即可。具体操作窗口如图6.1.2.2所示:; l# l! w$ P( {2 X! i

" _& Y0 e8 P" ^) l; F 7be029d0b4ea433f899085ffd811b81b.png
$ j+ c, c0 v! H3 Q/ K2 q
; z$ C, y0 _0 i- l" _- n/ F图6.1.2.2 保存工程界面5 ^! b6 h  e4 z
之后,弹出器件选择对话框,如图6.1.2.3所示。因为正点原子MiniPRO STM32H750开发板所使用的STM32型号为STM32H750VBT6,所以我们选择:STMicroelectronicsSTM32H7 SeriesSTM32H750STM32H750VBTx(如果使用的是其他系列的芯片,选择相应的型号就可以了,特别注意:一定要安装对应的器件pack才会显示这些内容哦!!如果没得选择,请关闭MDK,然后安装 A盘:6,软件资料\1,软件\MDK5\ Keil.STM32H7xx_DFP.2.5.0.pack这个安装包后重试)。
4 d& C; G! y. \/ M( N& L1 ?6 y, r+ R0 R2 P! f, W6 ~, Z8 N
430d60a3433a4e6db0e2979a87976ff7.png 2 H; z8 I/ F5 F# u8 k/ ~, F
2 q7 i( f- m8 Z( @; ?4 Z
图6.1.2.3 器件选择界面
  S# `( y7 S8 R0 D, w& ~点击OK,MDK会弹出Manage Run-Time Environment对话框,如图6.1.2.4所示:5 t/ ~$ F( ^  g, n, z& w) ^
9 a. x* s3 o2 R! v
fb9db7b30ef74a84bb3c63f3a80437b3.png
8 }- L" \$ L+ S
( U7 H* v+ q4 U- j; _* N, `" k图3.2.1.4 Manage Run-Time Environment界面
1 r. m( }; R1 t$ I这是MDK5新增的一个功能,在这个界面,我们可以添加自己需要的组件,从而方便构建开发环境,不过这里我们不做介绍。所以在图6.1.2.4所示界面,我们直接点击Cancel,即可,得到如图6.1.2.5所示界面:- ]$ l0 U0 V) {  f2 \$ ~

. ]$ U  M; I- N1 S4 c& K- E% @ 63be7dbc447e407b911baf24bff8d27f.png 5 i3 c+ I' e4 p. b0 k

* @  V4 s! E( l: _! T0 v1 Y图6.1.2.5 工程初步建立# m0 L0 H) O' u; `: I0 j2 D: M% c
此时,我们打开MDK-ARM文件夹,会看到MDK在该文件夹下自动创建了3个文件夹(DebugConfig、Listings和Objects),如图6.1.2.6所示:6 i7 M8 [) h8 O* T9 z  T) X* v5 }

' U( h/ {0 s$ n' q' K9 N3 p e56180442cef468386f0c49a1df37fa5.png
( R! s- [% p% F4 u! M
* L8 g7 q" V: A1 n图6.1.2.6 MDK新建工程时自动创建的文件夹
( |5 S5 I6 R- r( T这三个文件夹的作用如表6.1.2.1所示:8 D, }2 J2 [3 l" S" [

" F1 a3 ^; g) r+ n 8d36136524f943c6b335f5659bd8e68b.png ' J. C) J" j; p2 g' ~! x

2 n$ j1 h$ U! }7 v  o4 p7 e# G& }表6.1.2.1 三个文件夹及其作用
0 v: N4 L6 |$ J编译过程产生的链接列表、调试信息、预览、lib等文件,统称为中间文件。为了统一管理,方便使用,我们会把输出在Listings和Objects文件夹的内容,统一改为输出到Output文件夹(通过魔术棒设置),我们先把MDK自动生成的这两个文件夹(Listings和Objects)删除。
6 K# n6 M7 i: m7 d0 x, T& |至此,我们还只是建了一个框架,还有好几个步骤要做,比如添加文件、魔术棒设置、编写main.c等。* n- ]: d% J" S+ E* h
7 s- }" @1 M/ n+ Q" r6 Y* V# @4 `
6.1.3 添加文件# v& l0 s  I* ^6 w0 A
本节将分3个步骤:1,设置工程名和分组名;2,添加启动文件;3,添加SYSTEM源码。9 a5 _( X: D! z4 m, U0 r

- ^- B7 B5 C. H2 F3 w* K1. 设置工程名和分组名
+ y9 R9 y( m& ^在ProjectTarget上右键,选择Manage Project Items…(方法一)或在菜单栏点击品字形红绿白图标(方法二)进入工程管理界面,如图6.1.3.1所示:
; q: S& l2 b( M+ t' D8 d* {
8 F; z5 z! a  t! O- _3 Y 08d6689b9778434d93c37419ff24a997.png ' [5 \* Y9 g5 ]) S  m! H

+ q& N- B4 k5 w; k4 \图6.1.3.1 进入工程管理界面# p; j& ]. L* Y7 K7 o! D
在工程管理界面,我们可以执行设置工程名字(Project Targets)、分组名字(Groups)以及添加每个分组的文件(Files)等操作。我们设置工程名字为:Template,并设置四个分组:Startup(存放启动文件)、User(存放main.c等用户代码)、Drivers/SYSTEM(存放系统级驱动代码)、Readme(存放工程说明文件),如图6.1.3.2所示:
) |- f5 H8 M5 ?- K% S0 }7 g; D$ _/ i" n8 _+ ?  K0 g/ @2 S9 q
c06f439a752449e88028b53d2a3170b6.png
7 \9 {. }# [. `7 I2 |  W  X7 g0 L8 W, l/ `
图6.1.3.2 设置工程名和分组名
$ w( ]2 h$ p0 G6 a( j& b* T设置好之后,我们点击OK,回到MDK主界面,可以看到我们设置的工程名和分组名如图6.1.3.3所示:
0 A. n6 X$ w- ]0 z
0 v( d6 c9 j, _ 0ca53d06ca3f4d10b1198a8eefe2f443.png
& d( |$ M9 M1 n8 ~- k+ C' S* v3 A, x7 t! w' q% g/ ~9 |! |
图6.1.3.3 设置成功) _7 g" s& K' _9 c
这里我们只是新建了一个简单的工程,并没有添加BSP、Middlewares等分组,后面随着工程复杂程度的增加,我们需要一步步添加对应的分组。+ j( w. G5 @* d& y! ]5 w
注意:为了让工程结构清晰,我们会尽量让MDK的工程分组和我们前面新建的工程文件夹对应起来,由于MDK分组不支持多级目录,因此我们将路径也带入分组命名里面,以便区分。如:User分组对应User文件夹里面的源码,Drivers/SYSTEM分组,对应Drivers/SYSTEM文件夹里面的源码,Drivers/BSP分组对应Drivers/BSP文件夹里面的源码等。) J# A) x# `# a* ]+ o' q

7 g# d2 t4 i) @6 l4 e* _6 U2. 添加启动文件
2 S9 Q/ o5 a! J3 L- w启动文件(.s文件)包含STM32的启动代码,其主要作用包括:1、堆栈(SP)的初始化;2、初始化程序计数器(PC);3、设置向量表异常事件的入口地址;4、调用main函数等,是每个工程必不可少的一个文件,我们在本书第九章会有详细介绍。
8 g3 H% l) M, T) n! C启动文件由ST官方提供,存放在STM32CubeH7软件包的:DriversCMSISDevice STSTM32H7xxSourceTemplatesarm文件夹下。因为我们开发板使用的是STM32H750VBT6,对应的启动文件为:startup_stm32h750xx.s,为了节省空间,在精简版CMSIS文件夹里面我们把其他启动文件都删了。而且,为了更好的匹配寄存器版本代码,我们对startup_stm32h750xx.s做了2处修改:
0 ]$ c% ]: [; x1,我们用不到编译器的内存管理函数,为节省内存,将Heap_Size改成 0,源码如下:
: s0 d% ]" V$ r, n( {( T0 W;未用到编译器自带的内存管理(malloc,free等),设置Heap_Szie为08 ~, v1 N$ i( V5 K
Heap_Size EQU 0x000000005 @: C. i8 W1 `' H7 j& D
2,寄存器代码不需要调用SystemInit函数,因此修改Reset_Handler函数,去掉SystemInit调用,并且还加入了开启 STM32H750 硬件 FPU 的代码,具体源码如下:
8 h& F1 N1 A3 a% p" f3 ~5 x9 {6 O5 L( |" Y5 L) W8 t8 i& {! L2 ~) F* S( E
  1. Reset_Handler    PROC
    " w8 ], V: N9 t
  2.                     EXPORT  Reset_Handler                    [WEAK]
    ' t- [. C3 G, Y5 Z! ]2 W
  3.     ;IMPORT  SystemInit
    / I0 O0 O& Z: ~: R( _* i* N
  4.     ;寄存器代码,不需要在这里调用SystemInit函数,故屏蔽掉,库函数版本代码,可以留下8 m7 _* g7 S- V3 q6 N0 @$ N5 E
  5.     ;不过需要在外部实现SystemInit函数,否则会报错.
    9 d  \' e- l0 L% a' X' ]
  6.     IMPORT  __main; `2 z2 t+ U3 ?9 q  I
  7. 5 w9 N/ q# A# N5 b3 [* x' g6 G
  8.         IF {FPU} != "SoftVFP"  ;通过Target选项卡的Floating Point Hardware选项来控制
    ) j' c' ]4 V* M
  9.                                    ;如果选择:Not Used,则不编译以下代码(到ENDIF结束)
    % w% ~+ Z6 ^: t
  10.                                    ;如果选择:Use Single/Double Precision,则编译以下代码
    : V, b; @4 A5 R9 G" X/ U% K0 J
  11.         ;Enable Floating Point Support at reset for FPU) r0 f$ a/ }% @
  12.         LDR.W  R0, =0xE000ED88       ; Load address of CPACR register
    5 C5 u+ h& V. m3 m' t$ ]
  13.         LDR    R1, [R0]                ; Read value at CPACR: ]0 S7 o- [- B7 m! h6 p4 W
  14. ; Set bits 20-23 to enable CP10 and CP11 coprocessors& S! P# n& L6 E- o
  15.         ORR    R1,  R1, #(0xF <<20)  
    # j) H, _: h. a- N- k
  16.         ; Write back the modified CPACR value
    + Q/ V, I6 l! O& u
  17.         STR    R1, [R0]                ; Wait for store to complete
    ; P! |" A, z" J0 w! M
  18.         DSB
    ! y2 W5 s8 u+ m# u' N' v
  19.                                          ;针对OS应用,FPU寄存器全部由OS压栈保存,关闭硬件压栈
    ( ^6 a% D; i2 x9 c2 W/ r
  20.                                          ; Disable automatic FP register content
    . s( d0 o/ j( c. L: D& [( i
  21.                                          ; Disable lazy context switch
    # Q6 T9 U% A* \3 K7 B
  22.         LDR.W  R0, =0xE000EF34       ; Load address to FPCCR register
    & P) e+ H  Z8 @! b4 z
  23.         LDR    R1, [R0]) o7 @5 f* c+ Z0 v. @
  24.         AND    R1,  R1, #(0x3FFFFFFF); Clear the LSPEN and ASPEN bits* o, }( c/ L8 y9 Z# V
  25.         STR    R1, [R0]! k9 U" c  R" ~4 n- p+ P
  26.         ISB                              ; Reset pipeline now the FPU is enabled
    * e; G* k2 B% [. d
  27.         ENDIF
    % \& ?) O. n& {5 N' t0 h8 |
  28. 8 `- F+ o5 L# C. D/ X/ G& t/ E
  29.         ;LDR     R0, =SystemInit             ;寄存器代码,未用到,屏蔽; z3 ]* w. H  D( Z' q. v9 {
  30.         ;BLX     R0                      ;寄存器代码,未用到,屏蔽
      r, x+ O8 Y( _
  31.         LDR      R0, =__main
    ( z" I7 M, C' |3 |' S# J: u  V) w
  32.         BX       R0( X& I5 `& u) Z$ f+ Q& J: b
  33.         ENDP
复制代码
+ g6 e' j: `) D3 U+ W$ f# H1 n
这段代码,我们主要加入了开启 STM32H750 硬件 FPU 的代码,以使能 STM32H750 的浮点运算单元,并关闭硬件自动压栈。其中,0xE000ED88 就是协处理器控制寄存器(CPACR)的地址,该寄存器的第 20~23 位用来控制是否支持浮点运算,这里我们全设置为 1,以支持硬件浮点运算。关于 CPACR 寄存器的详细描述,见《STM32H7 编程手册.pdf》第 4.7.1 节。另外,寄存器版本,我们还屏蔽了 SystemInit 函数的调用,如果是HAL库版本,可以取消这个函数的注释,并在外部实现 SystemInit 函数。
. S6 |3 Q8 x0 Z4 ?: M- d; G, q特别注意:我们在汇编代码里面使能了 FPU,所以在 MDK 里面,我们也要设置使用 FPU,否则可能代码会无法运行,设置方法如下:选择 Options for Target ‘Target1’,打开 Target 选项卡,在 Code Generation 里面,选择 Double Precision,如图6.1.3.4 所示:
# Z, D5 f' }7 k
1 l$ N8 z/ R' A. F 501ae5395b194fff9013556fb9907b26.png " r; l2 i) y' m$ K7 m
2 h. c9 q# F& `# c
图6.1.3.4 MDK开启浮点运算
6 A$ E# f) ]- [( ~! z关于启动文件的说明,我们就介绍这么多,接下来我们看如何添加启动文件到工程里面。我们有两种方法给MDK的分组添加文件:1,双击Project下的分组名添加。2,进入工程管理界面添加。2 i% [& W7 |: u( t
这了我们使用方法1添加(路径:实验0-2,新建工程实验-寄存器版本\Drivers\CMSIS( o- X* Q1 W+ A& M4 V
Device\ST\STM32H7xx\Source\Templates\arm),如图6.1.3.5所示:
) l3 B3 k8 B$ U& {( W) {- r0 |8 z3 g2 {2 d' l( n
28c2660d1698477a864fa6ce5c85e348.png 8 B9 M# B. \/ {/ b5 f- a" C& x
* m0 e4 m- L: F, \* B: Q
图6.1.3.5 双击分组添加启动文件(startup_stm32h750xx.s)
; A" s6 O" r' Y1 f1 f上图中,我们也可以点击Add按钮进行文件添加。添加完后,点击Close,完成启动文件) u$ ^) z: c8 i5 V) Y4 w
添加,得到工程分组如图6.1.3.6所示:
8 @# l  w. p/ `) Y6 m* r) O! _* r+ |5 G- J+ N2 C7 s* o- Z% D% D# q
35719c26891c442ab684e3c5f5982f3a.png . g1 Y& `! x$ ~

  k8 O+ q) g0 q" j# o图6.1.3.6 启动文件添加成功; K6 m$ n3 J( j; d5 }
+ o* A$ ^+ _& ^. `3 @+ f4 U
3. 添加SYSTEM源码* D& K2 _: f3 t9 o+ a$ {
这里我们在工程管理界面(方法2)进行SYSTEM源码添加。点击:按钮,进入工程管理界面,选中Drivers/SYSTEM分组,然后点击:Add Files,进入文件添加对话框,依次添加delay.c、sys.c和usart.c到该分组下,如图6.1.3.6所示:
+ _0 Z' ?! o0 ~5 _: z" `0 W
. H6 ]& `0 t( ~& K% ` 7fa6e18f95134622a0ba12f34a804ae1.png
* Z5 B+ R6 I+ _* D  S2 M: w4 t  z  x2 R# `% f3 s* d' |: G: O
图6.1.3.6 添加SYSTEM源码
. Z; j2 F' @3 t/ H# m注意:这些源码都是在第6.1.1小节的第二步拷贝过来的,如果之前没拷贝,是找不到这些源码的。添加完成后,如图6.1.3.7所示:3 O. [4 @* x7 k4 r" `# J

, v, M/ A( W+ ^- h. G 0990065871b740369c4cfd1b94100f83.png 9 N6 w0 Q' I/ R* D. r, o9 l7 W
6 x& G# ~! f. V: m: X6 X
图6.1.3.7 SYSTEM源码添加完成+ B! x4 z4 |3 l
$ |( ^3 B1 t6 v
6.1.4 魔术棒设置! I& ^! T' K# S" u: ^* U) ^
为避免编写代码和编译报错,我们需要通过魔术棒对MDK工程进行相关设置。在MDK主界面,点击:(魔术棒图标,即Options for Target按钮),进入工程设置对话框,我们将进行如下几个选项卡的设置。& v" L1 C% `, G, K
2 p8 _) [6 n& k8 X# L* U% Q8 ^% _
1.设置Target选项卡
9 M' X, H3 W7 X7 N在魔术棒Target选项卡里面,我们进行如图6.1.4.1所示设置:5 ~& l$ R* H( h4 T, H; H% g

% z) g$ @- C" \! [$ l 9d749fdd08a64f3fab69aa5da05f1eef.png
' v6 |0 {. l; O* E+ h, C) Q
# n6 e% P- M) e9 T: @! w# g图6.1.4.1 Target选项卡设置- Q3 O( z( E5 i9 D8 m1 p+ ]
上图中,我们设置芯片所使用的外部晶振频率为8Mhz,选择ARM Compiler版本为:Use default compiler version 5(即AC5编译器)。
+ F( S- V% ]: c7 e; [! h这里我们说明一下AC5和AC6编译的差异,如表6.1.4.2所示:
. ^& X5 p6 d8 K% `' m
8 N, C; U1 K5 S1 Z+ X: D ed9756bfc54246f08868dda926a09845.png
$ k9 C7 d6 r8 ?8 [5 h$ M7 b. J/ r& B6 n  ^* e1 p- K6 f0 K
表6.1.4.1 AC5&AC6简单对比
$ J; X/ A( l. s  a2 x3 a由于AC5对中文支持比较好,且兼容性相对好一点,为了避免不必要的麻烦,我们推荐大家使用AC5编译器。为了让大家自由选择,我们正点原子的源码,也是支持AC6编译器的,不过在选项卡设置上稍有差异,具体差异如表6.1.4.2所示:+ h5 ]& h( \" ^9 e: P7 O# N* t

! H9 {+ {! }- ?. O* C. ~% q d630248ef0134601bd580c018d332fa5.png
6 o* Z6 d6 K- f+ z- W) _& {  @+ l8 e+ L& f7 s7 \* Z; z
表6.1.4.2 AC5&AC6设置差异
: ?* G% X6 L) _0 A2. 设置Output选项卡4 Q0 V- f, a/ N. S" a, W
在魔术棒Output选项卡里面,进行如图6.1.4.2所示设置:
) h) N3 b. Q0 z$ W& {9 H0 d0 P7 q- C
483b9f614c394f8399284373848354f5.png 0 `5 f7 ]9 @* Z+ M; {

' w: e& U7 h3 w8 ^图6.1.4.2 设置Output选项卡0 j( H" N0 \( E8 i
注意,我们勾选:Browse Information,用于输出浏览信息,这样就可以使用go to definition查看函数/变量的定义,对我们后续调试代码比较有帮助,如果不需要调试代码,则可以去掉这个勾选,以提高编译速度。" b. y7 R, n# ]2 H! b& J

/ t: Z" p' j9 b' i) j3. 设置Listing选项卡
. Y/ X( b! [* y/ c1 N在魔术棒Listing选项卡里面,进行如图6.1.4.3所示设置:
" Y$ f# W" @  d) L9 ~9 W4 x! m; j2 m0 u$ }; z
814fd210a41149238db33d210c5dac70.png
2 Z) @" d2 ?/ h: U+ k' b; r. f( u, E, P. o  F; T
图6.1.4.3 设置Listing选项卡# ~$ W2 ^. V/ N" t+ \
经过Output和Listing这两步设置,原来存储在Objects和Listings文件夹的内容(中间文件)就都改为输出到Output文件夹了。' K9 e3 D7 {, w7 }# z; D4 t

/ [# @1 P# D: d4 F$ V4 m; F- Y4. 设置C/C++选项卡
: f, h, \7 ]; a' W在魔术棒C/C++选项卡里面,进行如图6.1.4.4所示设置:
, V2 d% i4 o3 g  M1 u, L
- j7 w, b6 Q  N% L8 c+ }; ^. Q' X" O, } d9ffcecf23844052b249ef73ea7a9bfe.png - q) ]+ g1 b' w- B$ ?& W8 A

2 P1 B$ M& j* g图6.1.4.4 设置C/C++选项卡
/ h) Z; ?2 H, w! E8 C( w( c" h在②处设置了全局宏定义:STM32H750xx,用于定义所用STM32型号,在stm32h7xx.h里面会用到该宏定义。
0 C+ Q# f* A7 u5 G7 w8 u, e. F在③处设置了优化等级为-O0,可以得到最好的调试效果,当然为了提高优化效果提升性能并降低代码量,可以设置-O1~-O3,数字越大效果越明显,不过也越容易出问题。注意:当使用AC6编译器的时候,这里推荐默认使用-O1优化。" C. L$ g' w' e, ?; M: f) Z/ V
在④处勾选C99模式,即使用C99 C语言标准。$ y6 e0 h7 c$ y% ~, P
在⑤处,我们可以进行头文件包含路径设置,点击此按钮,进行如图6.1.4.5所示设置:
9 \3 s* B* [. R( u* n: E, s+ e$ \, D% C( c& }; x# Z* x
53446bf5a8cd4a9b9f03a5f351437b4d.png $ Y. O. ^$ f6 O/ f% a; P

4 j- [' b& ^- b0 m9 F图6.1.4.5 设置头文件包含路径
$ q' |+ O! E- I( R" b4 F- ^% r( D上图中我们设置了4个头文件包含路径,其中3个在Drivers文件夹下,一个在User文件夹下。为避免频繁设置头文件包含路径,正点原子最新源码的include全部使用相对路径,也就是我们只需要在头文件包含路径里面指定一个文件夹,那么该文件夹下的其他文件夹里面的源码,如果全部是使用相对路径,则无需再设置头文件包含路径了,直接在include里面就指明了头文件所在。. f2 U2 U& k/ L: j0 ?, ]
关于相对路径,这里大家记住3点:. P$ ?3 n/ ^% Z( ^; a
1,默认路径就是指MDK工程所在的路径,即.uvprojx文件所在路径(文件夹)" p/ j" r' |$ V& {
2,“./”表示当前目录(相对当前路径,也可以写做“.\”)7 k! k4 B' E! |$ }* A$ ^
3,“…/”表示当前目录的上一层目录(也可以写做“…\”)4 o9 n9 Y" F# \! t) E+ e' z  _3 ]% L
举例来说,上图中:…\Drivers\CMSIS\Device\ST\STM32H7xx\Include,前面两个“…\”,表示Drivers文件夹在当前MDK工程所在文件夹(MDK-ARM)的上2级目录下,具体解释如图6.1.4.6所示:4 v; E6 a8 B/ {) m5 H$ U1 V
7 u$ U5 X  ^8 e% P
e4a85b28842d4a1f8e63850283a1b826.png   l% n: n4 Y0 X; g* F
9 `+ }9 m+ d3 O; U
图6.1.4.6 …\Drivers\CMSIS\Device\ST\STM3H7xx\Include的解释
+ \" ]9 O3 U% R上图表示根据头文件包含路径:…\Drivers\CMSIS\Device\ST\STM32H7xx\Include,编译器可以找到⑥处所包含的这些头文件,即代码里面可以直接include这些头文件使用。
! I7 P2 X; Z3 l% [再举个例子,在完成如图6.1.4.5所示的头文件包含路径设置以后,我们在代码里面编写:
6 j* F! ^' \& C$ l  c#include “./SYSTEM/sys/sys.h”' R' m" ?& u1 f$ h; ^
即表示当前头文件包含路径所指示的4个文件夹里面,肯定有某一个文件夹包含了:SYSTEM/sys/sys.h的路径,实际上就是在Drivers文件夹下面,两者结合起来就相当于:4 |8 c5 j0 l2 b( j  R+ P1 t  E
#include “…/…/Drivers/SYSTEM/sys/sys.h”6 f  a6 N5 |! \7 R0 e% D. o
这就是相对路径。它既可以减少头文件包含路径设置(即减少MDK配置步骤,免去频繁设置头文件包含路径的麻烦),同时又可以很方便的知道头文件具体在那个文件夹,因此我们推荐在编写代码的时候使用相对路径。
7 Y: m3 G3 n, w2 Q/ ?关于相对路径,我们就介绍这么多,大家搞不明白的可以在网上搜索相关资料学习,也可以在后面的学习,分析我们其他源码,慢慢体会,总之不难,但是好用。
" n6 X2 T' U: \/ ]' p最后,我们如果使用AC6编译器,则在图6.1.4.4的Misc Controls处需要设置:-Wno-invalid-source-encoding,避免中文编码报错,如果使用AC5编译器,则不需要该设置!!! K  T8 o6 D  F" T/ ^8 x9 |, ~7 M, @5 r- R
1 j1 V; \1 _( y1 @" y" |! o3 u
5. 设置Debug选项卡
- M* B3 W/ U. ^) l5 z  @& R4 }  Y在魔术棒Debug选项卡里面,进行如图6.1.4.7所示设置:5 e4 E3 H) b3 I. e8 \0 N  N
9 }. U/ Z0 N& d* s3 [
5b5a155e65ff42ed9793787102114d5d.png , o3 ?& J6 S! L# R! ^; r, S# y
' [: t( p0 F, ]0 b9 l
图6.1.4.7 Debug选项卡设置
  x. y! y6 i# J: [! X图中,我们选择使用:CMSIS-DAP仿真器,使用SW模式,并设置最大时钟频率为10Mhz,以得到最高下载速度。当我们将仿真器和开发板连接好,并给开发板供电以后,仿真器就会找到开发板芯片,并在SW Device窗口显示芯片的IDCODE、Device Name等信息(图中⑤处),当无法找到时,请检查供电和仿真器连接状况。
9 S' q2 y( G: t. {( O. Y
  t" q$ V% G' l7 U0 n, b6. 设置Utilities选项卡
2 x7 F+ _9 o0 C/ R5 C, u在魔术棒Debug选项卡里面,进行如图6.1.4.8所示设置:
6 y9 J- i1 ]2 ^6 N/ `5 c3 Y+ ?9 P% i7 G3 f- h, D3 j/ A2 I
e87266b475034e129bbaf27880dd66d5.png
$ |+ c+ j6 r) k1 w
& G2 u# t& v' h+ W图6.1.4.8 Utilities选项卡设置
1 n- e  J' }0 M! L图中⑥处下载算法STM32H750,是MDK默认添加的,针对STM32H750系列产品。除此之外,我们还要添加STM32H750VB_W25Q64@ALIENTEK.FLM算法,点击⑦处按钮添加即可。添加好算法后,设置算法使用的 RAM 地址和大小,这里设置的起始地址为:0X2000 0000(DTCM),大小为:0X3000。必须按这个大小设置,否则下载会出错(无法加载算法)。; G0 M% {* t: ~1 t) }- L- D( S
# a+ [; B/ {3 G% s$ F
7. 添加分散加载文件7 O( W) j# ^$ S3 F6 c9 `9 r6 s
由于STM32H750VBT6芯片内部的FLASH的空间比较少(只有128KB)。对于大的工程,这个FLASH空间是不够用的,为了解决这个问题,同时方便后续工程的新建,我们统一使用分散加载的方式来决定FLASH内存的分配,而不用MDK默认的设置。关于分散加载是什么?我们后面8.3小节会讲解,请大家先跟着我们把新建工程完成。" I! |* ?) o/ ^2 F! I
分散加载的文件已经为大家准备好了,可以在实验0-2,新建工程实验-寄存器版本\User\SCRIPT,或者在(A盘)/程序源码/STM32启动文件/分散加载_寄存器版本/SCRIPT中拷贝qspi_code.scf文件到我们的工程User\SCRIPT路径下,如图6.1.4.9所示。
3 a9 V4 ~& N$ M# E7 ?: r
# |: E' e9 q" L 871b7faf48ec4f43b1dd55a7066e89c9.png
' w) L1 _. \) o/ {) [- r! a
' p$ R  P- O$ u- T* G图6.1.4.9 拷贝分散加载文件到工程  R* C# u4 F0 T
注意:这里的分散加载文件寄存器跟HAL库是不一样的,我们建立寄存器工程,所以必需用寄存器版本的分散加载文件。
$ V# q. {# k( M! J6 Q+ o接下来我们需要对MDK进行配置,相当于把分散加载文件关联到工程里。方法:点击魔术棒, Linker选项卡取消勾选:Use Memory Layout from Target DialogScatter File路径选择SCRIPT文件夹 选择qspi_code.scf文件,然后,在disable Warnings一栏,添加:6314,6329,屏蔽6314和6329这两个警告。如不屏蔽,当分散加载里面有某些段(section)没用到,则会报警告,所以我们需要屏蔽这两个警告。如图6.1.4.10所示。5 J4 I. ^& Z5 Z7 g
( \$ h+ j, W- F" Q, i% {
b07d3ab934674dc9986a7dbb72d7b811.png   [4 h. u, \* `/ I

- n- I9 C5 {, }图6.1.4.10 添加分散加载文件' @/ y; m  L5 ]  h4 [
至此,添加分散加载文件的相应操作就完成了。
# E. ~# o. U. [/ v+ y! ~
8 P' ~9 D, I% w" p6.1.5 添加main.c,并编写代码
/ {* \, F7 O! I  b& p% j9 B在MDK主界面,点击:,新建一个main.c文件,并保存在User文件夹下。然后双击User分组,弹出添加文件的对话框,将User文件夹下的main.c文件添加到User分组下。得到如图6.1.5.1所示的界面:! O3 o. g# Z  w' ~/ Z7 U* n

% J) ?: b# X. q! p% g. B: L" g9 R7 N! e 6c5a8a9ba304460593c5193a8f1c4bb6.png 1 b+ N( a% D8 C
+ Z/ S% v) d/ S
图6.1.5.1 在User分组下加入main.c文件: F; V4 I; I- h0 {5 |  S
至此,我们就可以开始编写我们自己的代码了。我们在main.c文件里面输入如下代码:+ O' v$ q9 \% a5 L5 ]3 K
# a: @% ^$ I, L2 q8 X6 I
  1. #include "./SYSTEM/sys/sys.h"
    5 h2 L9 Q' o/ b* E6 _/ o, N4 T0 X
  2. #include "./SYSTEM/usart/usart.h"+ B5 k* F! P8 h9 j5 z- G
  3. #include "./SYSTEM/delay/delay.h"
    ' _8 C5 D# a3 Z) c6 s8 ~( ~" y% h
  4. int main(void)5 q/ {8 f$ d* [8 r5 n* ^: F
  5. {  W9 N% v0 J. P% |, l& ~( C+ G
  6.     uint8_t t = 0;3 L: i& f. w9 j) V$ x
  7.     sys_stm32_clock_init(240, 2, 2, 4);         /* 设置时钟, 480Mhz */" _& }* T/ r2 I0 s" w4 V0 V/ W" {5 d  W
  8.     delay_init(480);                                /* 延时初始化 */, G( H- ?& h, {" _
  9.     usart_init(120, 115200);                               /* 串口初始化为115200 */6 \& M. O4 K% a
  10.     while (1)
    * ^5 a; Y) ]8 |( N1 H6 \& O
  11.     {, w8 K) O# l( k2 m' Q
  12.         printf("t:%d\r\n", t);
    4 L" Z# F2 y; u. ^
  13.         delay_ms(500);/ x8 q6 {5 s: ]- P
  14.         t++;
    . m% H. B9 O( p# `7 u
  15.     }& C- W, x, `5 L! E, i0 Y! ^0 |
  16. }
复制代码

% u* v3 V! S2 n- B) e- \5 M此部分代码,在A盘4,程序源码1,标准例程-寄存器版本 实验0 基础入门实验实验0-2,新建最工程实验-寄存器版本Usermain.c里面有,大家可以自己输入,也可以直接拷贝。强烈建议自己输入,以加深对程序的理解和印象!!
5 ~; J% Z2 {5 @, \$ B$ q注意,这里的include就是使用的相对路径,关于相对路径,请参考前面C/C++选项卡设置章节进行学习。: j0 L( C/ t1 B
编写完main.c以后,我们点击:(Rebuild)按钮,编译整个工程,编译结果如图6.1.5.2所示:  f  {. w7 b# h, |3 w; g
; A! |3 k/ Q, M+ S, `5 b1 Y
ad51db4406df4dda8aeac90bcb01c68f.png
5 I+ ?$ `* ^( S5 I! V4 s! {  g& }. |1 m' P
图6.1.5.2 编译结果1 k2 A0 d, X6 a; e" m
编译结果提示:代码总大小(Porgram Size)为:FLASH占用4508字节(Code + RO + RW),SRAM占用2360字节(RW + ZI);并成功创建了Hex文件(可执行文件,放在Output目录下);编译0错误,0警告。! @( Y) L7 R& L; W
注意:如果编译提示有错误/警告,请根据提示,从第一个错误/警告开始解决,直到0错误0警告。如果出错,很有可能是之前的操作存在问题,请对照教程找问题。) q/ b: v* m5 g5 z+ X* [+ k
另外,我们在Readme分组下还没有添加任何文件,由于只是添加一个说明性质的文件(.txt),并不是工程必备文件,因此这里我们就不添加了,开发板光盘的源码我们是有添加的,大家可以去参考一下。. k- ^) t3 t5 w; _
至此,新建寄存器版本MDK工程完成。
3 j$ x% s  f" a1 A
$ D; t& K% R4 _0 ]3 T( C0 y6.2 下载验证
+ V$ b$ \+ |" a1 d: @6 f; \( F这里我们继续使用DAP仿真器下载,在MDK主界面,点击:(下载按钮,也可以按键盘快捷键:F8),就可以将代码下载到开发板,如图6.2.1所示:( Y  F( `# O5 J: @! |$ C

& E) N# j  E$ L6 x bf93750fae454ed890eb647860352da0.png
" W$ O- `' Y% ^. p( b( L4 ^" O1 Q0 C
图6.2.1 下载成功
" K. s7 _+ ]3 b2 q: _. x1 g8 C上图提示:Application running…,则表示代码下载成功,且开始运行。此时,我们打开串口调试助手,并设置好端口号(COM号)和波特率(115200),就可以看到打印出来的t值,如图6.2.2所示:; M7 H8 ^) C: X" Y; |$ Z/ d
$ R& l3 j" ?7 E( w! U3 O
d0f8f2c218504bb8b98afc2605558da8.png
# L4 P( N  z4 K0 V- w( l& v+ {  j$ \0 _  v5 \4 h
图6.2.2 收到开发板发回来的数据
  A# S; W) v* r8 C# x- B说明我们的程序运行正常,下载验证无误。
, `, w+ v# O/ o: B; J————————————————
+ j! S3 I6 C) f( X版权声明:正点原子2 L, P& f+ P$ h; @% d" u8 D/ x

1 \6 T6 q- f' |7 `$ y0 f7 I2 m7 A8 j0 |* ]9 T
赞 收藏 评论0 发布时间:2022-10-4 18:21

举报

0个回答

所属标签

相似技术帖

官网相关资源

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