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

【经验分享】新建基于STM32F40x 固件库的MDK5 工程

[复制链接]
STMCU小助手 发布时间:2022-6-10 19:41
02. 创建工程步骤1 c* z) d* j* F9 S8 z8 I2 X2 _
2.1 创建对应的文件夹

  p" J6 H& H( z  t! V8 T新建下面 5 个子文件夹:CORE ,FWLIB,OBJ,SYSTEM,USER。至于这些文件夹名字,实际上是可以任取的,我们这样取名只是为了方便识别。对于这些文件夹用来存放什么文件,我们后面的步骤会一一提到。( T# D! `% {/ V5 k: n# T/ q

8 W9 S& A: Y9 {# Z* d' q/ c Q@614TS)JN$RX77GB}}P7L9.png
* ~2 x9 }- k/ f: w; p! Q+ _. Z4 q- T3 I9 ^, }* H
2.2 创建工程项目
( {7 o( g: X0 ]" ?5 I4 p& Q
) m/ h9 _: q% M: V1 s打开 Keil,点击 Keil 的菜单:Project –>New Uvision Project ,然后将目录定位到刚才建立的文件夹 Template 之下的 USER 子目录,同时,工程取名为 01Test之后点击保存,我们的工程文件就都保存到 USER 文件夹下面。2 y) D. _+ {; E! E) Q4 Q3 R
! N$ j8 S$ {- N+ \- P
PLN[3]TV]7[T}`1GT[@$@XE.png " \9 \3 E3 l" Z" H6 J9 x

# C( B9 S, `1 s) t" b/ b& `2.3 保存工程文件名2 T" u4 R( e1 H) w
, q7 A# B5 \; S1 `+ e
工程取名为 01Test之后点击保存,我们的工程文件就都保存到 USER 文件夹下面。
% I4 I7 Q$ Y) i: S" z# Y/ q8 D3 R- b- r
0]Y(NR7_(VQXE4W`JPD(`U3.png $ z% S: |9 b: o
' b4 K* O  }0 n7 ]- V
2.4 选择芯片型号9 h, p" F* ~4 z; j; l
3 F% `/ V: m8 o% G/ L
定位到STMicroelectronics 下面的 STM32F407ZG( 针对我们的 ExplorerSTM32 板子是这个型号)。这里我们选择 STMicroelectronics→STM32F4 Series→STM32F407→STM32F407ZG
+ }1 Y2 o3 K4 p, _- V6 A9 ^2 M7 `/ g6 \; A- h3 L
M~2Q(LZAWG]9L5U4B~[V.png 9 R& P$ a2 L; t2 O, X# J$ t" E
+ A! ?, k, n- V4 {! J5 C
2.5 管理运行时环境
2 }1 r( o  U! t# v1 i
, W) M8 E; k) k) F" }' W6 tMDK 会弹出 Manage Run-Time Environment 对话框,这是 MDK5 新增的一个功能,在这个界面,我们可以添加自己需要的组件,从而方便构建开发环境,我们直接点击 Cancel即可,取消之后得到的界面如下:
; a' q) X) D3 S" e; i2 Y+ P
7 R4 b! D! ~$ u/ S* Z- W XK@R4)QA6`EX2~~SAFW73OD.png
5 o7 w6 d# a7 l; q
# C' V$ m6 p8 d* ~. y9 Q3 c2.6 复制固件库源码文件& X" q  a/ r' g; J& u  \! i

- e& D" q! y$ w: Y% S$ \' j. D7 m打开官方固件库包,定位到我们之前准备好的固件库包的目录:\STM32F4xx_DSP_StdPeriph_Lib_V1.8.0\Libraries\STM32F4xx_StdPeriph_Driver 下面,将目录下面的 src,inc 文件夹 copy 到我们刚才建立的 FWLib 文件夹下面。
8 m# r( `9 j( @8 j) U2 a& l* m1 x$ V: V1 m1 _: }' R* F9 c" r
src 存放的是固件库的.c 文件,inc 存放的是对应的.h 文件,每个外设对应一个.c 文件和一个.h 头文件。
! D/ ^- h- Y" ?3 u( N4 d
9 K5 m- Q$ b" Z; c" I 20200818152936112.png ! X/ Q! p! g. k7 s7 }" n/ o" X

. j0 g# ^4 M" n) L" \% m2.7 复制启动文件
0 i5 [# M  r, G9 r2 {7 F; M6 ]
  F, U# d* N) g9 c  }+ \
将固件库包里面相关的启动文件复制到我们的工程目录 CORE 之下。4 ?! u6 R3 K  j! }6 p. E3 Q. K) ]
9 r$ f. ^5 Z& t0 Q5 p
\STM32F4xx_DSP_StdPeriph_Lib_V1.8.0\Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates\arm 下面,将文件 startup_stm32f40_41xxx.s 复制到 CORE 目录下面。然后定位到目录\STM32F4xx_DSP_StdPeriph_Lib_V1.8.0\Libraries\CMSIS\Includ , 将 里 面 的 四 个 头 文 件 :core_cm4.h 、core_cm4_simd.h 、core_cmFunc.h 以及 core_cmInstr.h 同样复制到 CORE 目录下面。现在看看我们的 CORE 文件夹下面的文件,
6 e) G" p0 a) R) t% s3 k. s) l
1 a4 X+ M% Z' K$ H/ Q# _" q# s F2AJF4PCD9;F55{S~YA.png # R' k! b  J) [1 O/ F5 p  |

# Y5 b3 d, ]: t4 A3 _) Z2.8 复制其它头文件和源文件

+ J) D( T+ @/ r5 M6 \2 I, g) i" n) J; k6 B% t) ~) p) g
首先定位到目录:STM32F4xx_DSP_StdPeriph_Lib_V1.8.0\Libraries\CMSIS\Device\ST\STM32F4xx\Include 将里面的 2 个头文件 stm32f4xx.h 和 system_stm32f4xx.h 复制到 USER 目录之下。这两个头文件是STM32F4 工程非常关键的两个头文件。后面我们讲解相关知识的时候会给大家详细讲解。然后进入目录\STM32F4xx_DSP_StdPeriph_Lib_V1.8.0\Project\STM32F4xx_StdPeriph_Templates ,将 目 录 下 面 的 5 个 文 件 main.c , stm32f4xx_conf.h , stm32f4xx_it.c , stm32f4xx_it.h ,system_stm32f4xx.c 复制到 USER 目录下面。% u' E- l7 A4 ?2 Y

: P/ Z  \0 p% f# q8 w$ r 0P(9O8%]X0Y4Z~[UL191{V3.png
( [" s# u) _2 S& g- B+ `1 f& P6 ~  n; I
2.9 添加文件到工程中, G, \# f; O* e# h& E9 f

* q) X! c, Y6 ~前面几个步骤,我们将需要的固件库相关文件复制到了我们的工程目录下面,下面我们将这些文件加入我们的工程中去。右键点击Target1,选择 Manage Project Items,
' B& z5 c* n/ f$ K9 C6 U/ I4 K. C* Q8 g. B
SFHXUW$WM4_E5`H2DN]1_D5.png
$ W9 {: p, Y; V, m
4 E$ B! G, G1 F; h; F2.10 设置项目结构: O. V* j0 R8 ~- q- V

0 H, S/ c2 Z' qProject Targets一栏,我们将Target名字修改为01Test,然后在Groups一栏删掉一个SourceGroup1,建立三个 Groups:USER,CORE,FWLIB。然后点击 OK,可以看到我们的 Target名字以及 Groups 情况如下图:* e0 \, M+ b8 b- H- a0 G
  e3 R6 v6 _3 D# a( F
[~9N2P58R(O0`J9A_43`SYJ.png 9 r7 {( o' d: F

9 b. F2 q1 l5 T选择OK,出现如下界面:
6 S$ A+ M) d5 @- C5 K7 {3 _9 o9 s# g* i( F& n8 w2 w

( B' ^  R" d2 p& D3 {, a
6 F$ [" [9 B$ q" G+ L( K5 _  Q2.11 添加FWLIB目录下的文件
2 E( J6 C1 a0 S3 K! q5 R+ S# K) T$ d  u0 d0 A2 r3 O$ o
右键点击点击01Test,选择 Manage Project Items.然后选择需要添加文件的 Group,这里第一步我们选择 FWLIB,然后点击右边的 Add Files,定位到我们刚才建立的目录\FWLIB\src 下面,将里面所有的文件选中(Ctrl+A),然后点击 Add,然后 Close.可以看到 Files 列表下面包含我们添加的文件
7 P5 x% x- U% o) j6 w5 m* F! z
)222{JR5WB@]1WW82RVZBDT.png
; L4 d$ y$ P$ I7 r" J$ y8 _5 _# S6 ?+ q# ^+ a
对于我们写代码,如果我们只用到了其中的某个外设,我们就可以不用添加没有用到的外设的库文件。例如我只用 GPIO,我可以只用添加 stm32f4xx_gpio.c 而其他的可以不用添加。这里我们全部添加进来是为了后面方便,不用每次添加,当然这样的坏处是工程太大,编译起来速度慢,用户可以自行选择。
; n' Z  @, b3 r7 C- g% T! I
. c8 R- N6 t1 a0 t; Q+ p这里有个文件 stm32f4xx_fmc.c 比较特殊。这个文件是 STM32F42 和 STM32F43 系列才用到,所以我们这里要把它删掉(是 注意是 stm32f4xx_fmc.c 要删掉,不要删掉 stm32f4xx_fsmc.c)。
. n4 g: o  d6 g% W9 {5 G' q
( W* t% d$ o3 |4 K) I- G# b LBK_WK9FW@P(MWP8SUU9J5L.png
7 D, ]6 S/ h# m  F% v, M
: v- T" G! B  \/ D1 s2.12 添加CORE目录下的文件

$ z( ?' G! X& M( @2 j0 y& e. h4 X, D, }
% Y+ }* z. X; m; Y7 R% _4 u0 }5 L用同样的方法,将 Groups 定位到 CORE,添加需要的文件。这里我们的 CORE 下面需要添加的文件为 startup_stm32f40_41xxx.s( 注意,默认添加的时候文件类型为.c, 也就是添加 startup_stm32f40_41xxx.s 启动文件的时候,你需要选择文件类型为 All files件才能看得到这个文件),
( H( d- G- \. u- i1 `/ V7 m
  ^3 U! l) _/ W2 W _TUC${`OBX@_TOL@}M`T4C4.png
5 p& ^. N* b0 x- b" Q  _* |7 Y1 I
+ a5 k2 l) x2 j4 \2 D) w) y$ b0 h2.13 添加USER目录下文件

0 D+ W! U& O/ a# c! c
" H" l8 l. A3 D& [6 ~USER 目录下面需要添加的文件为 main.c,stm32f4xx_it.c,system_stm32f4xx.c。 这样我们需要添加的文件已经添加到我们的工程去了,最后点击 OK,回到工程主界面。
3 y! ~1 i' k/ V3 Y
, A1 R2 c. c  p7 w5 J 6Z}TFPFU6M_S@$`(`[C)X.png 2 C( `/ |7 x  l6 ]) ~( }
3 P, b$ ~9 z/ M. Q
主界面如下:
; |$ M- E% O+ N$ L) [, M, z. I" t7 \5 v2 J$ N) w
E(7UO7`%B~)CKIQQ[@,~U.png
  e/ Q" B9 x6 c+ k
( n  v+ I7 ^  c8 S& t! ], c2.14 设置头文件路径, Y5 j0 M3 U6 n; j
7 B; i' J9 X# V" R
我们要在 MDK 里面设置头文件存放路径。也就是告诉 MDK 到那些目录下面去寻找包含了的头文件。这一步骤非常重要。 如果没有设置头文件路径,那么工程会出现报错头文件路径找不到。, C# l4 G; W8 f1 v

$ O( j& n, g. f- l0 | NXKWAB3@W_56W1UT0KW[S]O.png
# ?7 ~2 y% g. ?. T+ |4 R6 y+ u! }) k  @- Z3 X
这里我们需要添加的头文件路径包括:\CORE, \USER\以及\FWLIB\inc。这里大家务必要仔细,固件库存放的头文件子目录是\FWLIB\inc,不是 FWLIB\src。
- ]6 N' |7 v0 k6 _  k% `
) g6 w6 z. V# `! H# v  Z$ v, ^ 57XMP9HARLI~7PFC7J}T}.png
/ Z, w: e8 S/ Q4 U# W9 s2 S( k( d& t* h8 p9 g4 k/ @
2.15 添加宏定义
# x5 g- o  P( f9 w# R$ S8 a& H* ^# ~- U8 J
接下来对于 STM32F40 系列的工程,还需要添加一个全局宏定义标识符。添加方法是点击魔术棒之后,进入 C/C++选项卡,然后在 Define 输入框连输入:STM32F40_41xxx,USE_STDPERIPH_DRIVER。注意这里是两个标识符 STM32F40_41xxx和USE_STDPERIPH_DRIVER, 他们之间是用逗号隔开的,请大家注意。
1 g: O- ~- e+ o1 _4 ~, ^
4 `% M8 p$ M3 `2 k; ~3 L Q17YALQ)(32D{Q052[CD2N8.png $ r( O! L$ P5 m4 w
& z9 L; |  S7 {! |* B. Y
2.16 设置中间文件存放路径
! }8 ?% m& x* @& e8 M" Z# m/ g  g; p1 _4 D- Z& C
然后选择“Output”选项下面的“Select folder for objects…”,然后选择目录为我们上面的 新建的 OBJ 目录。同时将下方的三个选项框都勾上。
3 o8 ~  g4 \  U( g- h
  ^1 U5 U8 k$ C% x1 y ${HKDXEL`EHPKV]4IX6S0@A.png 5 T" }- \/ D! Y

: S; J: Y+ G, M/ F- V9 U& \7 `Create HEX File 选项选上是要求编译之后生成 HEX 文件。Browse Information 选项选上是方便我们查看工程中的一些函数变量定义。0 ^3 |' ~& w; f5 A7 L

) C& o0 D& k9 s6 C" a2.17 修改主函数代码
- f& L1 ~9 v, M& v: k4 D
  1. #include "stm32f4xx.h"
    ! T1 w5 w, P. G- L7 v

  2. 6 E! c7 C% s" k) t
  3. void Delay(__IO uint32_t nCount);# K! e" A- v$ }/ H2 K4 N

  4. 1 |; I  u! D" @2 }9 r! U+ D
  5. void Delay(__IO uint32_t nCount)
    ! ~( y' }/ }4 {( t
  6. {
    8 a) `7 R7 y- w( R7 a8 |1 Q
  7.         while(nCount--){}
    9 N3 y: {$ e% f9 k! J( P5 ?
  8. }6 _) ?; u- |% F
  9. int main(void)+ I& \; |5 y" s
  10. {1 M* r6 K- r. g8 G$ q
  11.         GPIO_InitTypeDef GPIO_InitStructure;
    1 A! Q. U, j; M
  12.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);8 l" ]+ b. M2 o$ ]' x7 |: l
  13.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;3 L! U1 i9 K1 f4 o9 n7 Y
  14.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    * R8 I5 t4 @# i6 ^, l) k6 x) {% F
  15.         GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    7 D( w+ R- u' e* i! M+ Y/ N
  16.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;, \; |$ W" x2 g2 M3 i. G
  17.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;7 o2 L1 S( g" d. f4 G
  18.         GPIO_Init(GPIOF, &GPIO_InitStructure);
    0 T) x, Y% @! e" B& E
  19.         ' h0 i2 F' y& d
  20.         while(1)
    1 Y& ?  w. r: a* I
  21.         {2 u( Y' F4 P2 m  t/ m
  22.                 GPIO_SetBits(GPIOF,GPIO_Pin_9|GPIO_Pin_10);- x: f6 y8 Q. }4 J
  23.                 Delay(0x7FFFFF);
    ) f! w, |# e3 ?/ Y3 i
  24.                 GPIO_ResetBits(GPIOF,GPIO_Pin_9|GPIO_Pin_10);
    - @3 a& v8 `  T9 p8 Z, y
  25.                 Delay(0x7FFFFF);
      I  T8 t$ Z! |
  26.         }) w) n* W; w( C" M. p) J
  27. }# o. O! A' Z! F6 M6 M1 g* Y
复制代码
$ p% D1 ~  ^; P. V5 o% o
与此将 同时,我们要将 USER 分组下面的 stm32f4xx_it.c 。 文件内容清空。的 或者删掉其中的 32 行对main.h 头文件的引入以及 144 行 行 SysTick_Handler 函数内容,
3 a8 X4 c! n: e  c4 O2 V' V5 k4 }- S
2.18 编译工程5 j* k; T" l; `" i) @8 J
% [6 j8 V. {& F! J1 f2 k: m( o. A5 R
可以看到工程编译通过没有任何错误和警告。/ j7 D9 O4 U3 _; E  R& V+ A

7 u* X$ Y" s4 L" E6 s5 R7 f FBF3Y~IAMT4{F4VRAVUX}YS.png
. d+ p0 {" u  F8 `4 R" a$ B4 V* X2 n$ I+ c! J2 p
到这里,一个基于固件库 V1.8 的工程模板就建立完成,同时在工程的 OBJ 目录下面生成了对应的 hex 文件。3 e0 X  J; v8 l: B
0 i( {2 e" _" n0 T  E9 B
03. 系统时钟配置+ j* M+ O, H3 `1 j- S
我们要修改 System_stm32f4xx.c 文件,把 PLL 第一级分频系数 M 修改为 8,这样达到主时钟频率为 168MHz。
* @' V2 w& K* M: Q2 W  A! O1 i' V  N, e- t! `, M
  1. /************************* PLL Parameters *************************************/
    5 N$ b% u6 d0 K5 E; _3 U* n  r
  2. #if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F401xx) || defined(STM32F469_479xx)
    $ L+ j- m* S& Z/ T$ c2 T/ {- D
  3. /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
    " w& F/ X# q; }
  4. #define PLL_M      8        //之前是257 P( S: G. S- [
  5. #elif defined(STM32F412xG) || defined(STM32F413_423xx) || defined (STM32F446xx)
    ! M3 n& W, x0 _5 k* d6 L
  6. #define PLL_M      8
    * ^' c9 l* V; G3 P2 b
  7. #elif defined (STM32F410xx) || defined (STM32F411xE)% V" q: c9 G( c9 l
  8. #if defined(USE_HSE_BYPASS). Z, g6 q; k) R+ E# q0 E' O
  9.   #define PLL_M      8   
    1 q$ r% \% \0 S  F
  10. #else /* !USE_HSE_BYPASS */; C9 {# b  G2 y" @6 t
  11.   #define PLL_M      16
    ) z7 \% m4 h. i6 @1 l/ B" _
  12. #endif /* USE_HSE_BYPASS */
    0 x. u6 x: ?1 t" X
  13. #else; S4 y% b3 y, C, W
  14. #endif /* STM32F40_41xxx || STM32F427_437xx || STM32F429_439xx || STM32F401xx || STM32F469_479xx */  
复制代码

$ P3 q# Q- O' ~8 I3 T同时,我们要在 stm32f4xx.h 里面修改外部时钟 HSE_VALUE 值为 8MHz,因为我们的外部高速时钟用的晶振为 8M,具体修改方法如下:5 [$ D( G5 T# C3 }+ y

$ x1 O! O" L! e, h; r$ g
  1. #if !defined  (HSE_VALUE) 2 ?, Q: u- u: v  }
  2.   #define HSE_VALUE    ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */% x; @. C7 f# b# @5 {
  3. #endif /* HSE_VALUE */
复制代码

: `3 L% ~! \' F& q  ?一定要在对应的配置文件中,找到相应的代码行,修改为符合我们硬件的值即可。! o- M' K' ~. f% q, b. ?! S

' M, f. W) i: k: ^04. 添加其他功能函数

+ B% i& I4 k. W5 |( M+ h% }可以看到有一个 SYSTEM 文件夹,进入 SYSTEM 文件夹,里面有三个子文件夹分别为delay,sys,usart,每个子文件夹下面都有相应的.c 文件和.h 文件。 我们将 SYSTEM 文件夹 和 里面的三个子文件夹复制到我们工程根目录中。 如下图。我们接下来要将这三个目录下面的源文件加入到我们工程,同时将头文件路径加入到 PATH 中. c& d; u0 ?+ z8 Y; a6 ~& J

; h- i  _& L) \) P: p, q I`FK~K(RGY}AVM]7DGZAU5S.png
! U, I* H6 q+ B' c' D  h! T: f) r5 j
然后点击“OK”之后可以看到工程中多了一个 SYSTEM 组,下面有 3 个.c 文件。# E+ E/ }, }5 {! F; B0 V7 X

6 q' P, B& G$ c" O  q/ \5 _) {接下来我们将对应的三个目录(sys,usart,delay)加入到 PATH 中去,因为每个目录下面都有相应的.h 头文件。0 Y9 j: o1 a8 @7 }8 @9 W
* w# t. K9 T+ ^8 p
(92R]SAJ}C)UA8G81U63.png 6 K) L3 S6 `# d/ ^1 P

% X5 J, V' g3 X: Z) q9 j; k修改主函数如下
, l. Q, m/ r& ~' P4 l5 Q9 F% Y7 |3 ^+ e; W  T: G& `+ u' f
  1. #include "stm32f4xx.h"* o9 x5 S) h( h0 R* j: s5 c
  2. #include "usart.h"
    - x+ F# V1 L7 y. n0 ]1 p
  3. #include "delay.h"
    : S1 ?$ N/ u- k

  4. , V9 z" c4 U" M5 W$ `  n0 z
  5. int main(void)" [! V) [! J* ?) s  h
  6. {
      ?' X3 w; a; U5 k( r+ l
  7.         u32 t=0;$ r9 t$ L5 }! R- w7 e
  8.         uart_init(115200);
    7 }5 C& I1 u' e  s2 D# I/ m" G
  9.         delay_init(84);7 {9 a, N% [: }9 @
  10.         while(1)$ k. ?% Z2 E$ P" i7 \0 y
  11.         {
    9 C/ D! Q& p( G& I; J, }1 ?
  12.                 printf("t:%d\r\n",t);/ w4 ~+ h4 g7 L. D: n
  13.                 delay_ms(500);1 N* X, R+ O* Y* T3 N
  14.                 t++;
    8 \2 X& j8 c0 a) ~( Y
  15.         }
    2 O! U+ `: v9 C0 ~
  16. }
复制代码
7 q! j0 A' U  i4 z0 W
编译结果* ^, Z  m6 C& ?! a

3 V+ {5 L& F4 { RX~AnYA4)HSQ[LD$FO`}X.png $ }+ E1 y  F9 L

1 n# }  h* c: q1 m! n
, ~& d7 O$ ?3 Y3 k, B6 k3 H/ B+ e9 B5 M
9 y/ j9 C+ T" e/ r- ]  I9 `8 a6 D, r$ G
6 s3 F5 g' t8 u: x- d
收藏 评论1 发布时间:2022-6-10 19:41

举报

1个回答
Xalen 回答时间:2025-1-25 15:32:55

你好,请问第四步SYSTEM 文件夹,里面有三个子文件夹分别为delay,sys,usart,这个SYSTEM文件夹是哪里的文件夹呀,具体路径是什么呢?

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