前段时间将 Cortex-M3 权威指南看完了,现在开始拿块开发板练手。
4 X6 k4 \/ p% ]; A q _- p1 X' D8 T; U. z7 o
STM32F1xx 本身并不难,不过因为第一次用 Keil MDK,还有想在程序中使用最新的stm32f10x_stdperiph_lib V3.5,最后让程序跑通也经历了一番周折。这里简单的记录一下,希望对刚刚开始学STM32的初学者有些帮助。(这篇的内容很初级,高手请绕道)0 s i4 y6 T5 }/ r
: ? \9 Y3 x1 N# J) i% q
首先介绍一下我这里的实验环境,开发板是块便宜货“神舟IV号STM32F107VCT开发板”,听这个名字就挺山寨,不过便宜倒是真的。仿真器是国内山寨的J-Link V8,买开发板时送的。J-Link 用的是 V4.12 版的驱动程序,segger 网站上有新版的驱动,不过我试过了,新版的驱动添加了检测J-Link是否是山寨的功能,装上也不能用,在网上也没有找到解决办法,所以还是死心吧,4.12 版的驱动也能支持挺多的ARM 芯片型号了。
. F8 y7 f' @# s: X+ I' d2 D
/ b% U7 [: @3 m/ o$ D9 QIDE环境是Keil uVersion V4.10,工具链的版本为:RealView MDK-ARM 4.12,当然是D版的。" }! F0 z! y1 P
C0 B* }2 g- g/ F$ y总之,这一套从头到脚都挺山寨。不过我这是非商业用途,仅供个人学习,想来 ARM 和 segger 也不会来难为我。
( v Y7 M$ F. f3 i8 l+ }- {" T5 d, {/ z# L4 x9 @' `1 T1 |
不说废话了。首先讲一讲如何在程序中使用STM32F10x_StdPeriph_Driver。, w7 x. \5 t5 F0 ^5 x" Y, o% ~
" p8 {% @+ H) {, X
(1)新建一个文件夹存放项目文件,要注意路径不能有中文,我这里目录名取为stm32-test1。# |( q3 F3 [) K$ q) L1 T
0 I4 m! b; X# d
(2)打开Keil uVersion,新建一个项目“test.uvproj”,CPU 选择STM32F107VC。$ _2 [4 N& K1 m9 Q" k5 U* ?9 ]
9 d3 R6 J( C/ g8 Y3 P
! E9 |$ [3 K7 |; Y2 ?! @
- K- Q7 J& U7 S& @$ g2 K, L(3)Keil uVersion会提示是否添加启动代码,选择否,因为我们要用STM32F10x_StdPeriph_Driver中提供的启动代码。
8 u" a( Z1 O; d2 f; x
) G$ [1 x: J- b2 V0 _3 d, I0 f) H4 I m) P& j3 a4 D- l; z
$ x" A) Y+ ^2 z(4)给Project Targets 改名,我改的名为:STM32F107。这一步不是必须的,只是默认的名称“Target 1”太没个性了。* ~( I( V6 `, e& X; e# v
" Q' A3 c7 w6 L) ^$ C; L
(5)Groups 中我建立了三个组:Source、CMSIS、StdPeriphDriver。Source中存放我写的代码,另外两个顾名思义存放相应的代码。* c2 L" x4 B8 P) h2 x) k# U3 o
1 v% o, A* {5 j: X; v% d9 o! b! H) ^: \! ~: W
! G7 m* A5 {+ x- t3 h# @ {(6)stm32-test1 目录中也添加相应的三个文件夹:Source、CMSIS、StdPeriphDriver。这时stm32-test1 目录中应该有这些文件(文件夹):. o0 a& U% S* ]- X* d
0 C; X( h+ ]. W: N* [$ W- j7 x
CMSIS
( L) M' E+ n# S# L% f, A3 X+ B, z2 q+ }$ ^2 Y8 _
Source( Y: h+ b1 W) [
/ w, F" C' ?) {2 A StdPeriphDriver
$ G! z( a. C1 n. t! S% P/ r# b" \$ I! ~8 u/ O. s" K
test.plg
, t+ d) \8 H! B5 }
- E# ?9 |9 f* b; B test.uvopt: D3 X- A! c; [, h
# J7 b A; m1 o6 G4 e test.uvproj
9 i1 Y; o6 I* G( K) a! u
9 f' W i& ]& u test_STM32F107.dep
8 d3 b) O+ R% j! X" V
( `$ u5 e- k4 E9 C( G/ R9 g, N test_Target 1.dep
% ~, e6 t' U0 ^ t2 ^8 c. Z/ D U/ h, C$ e5 ?0 o
(7)网上下载的STM32F10x_StdPeriph_Lib_V3.5.0,解压缩后“STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\CoreSupport”和“STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x”目录中的c文件和h文件都拷贝到 CMSIS 目录中。“STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm”目录中 “startup_stm32f10x_cl.s”也拷贝到CMSIS 目录中。这里多说一句,startup_stm32f10x_cl.s 是 STM32F105和STM32F107系列的启动文件,cl指的是Connectivity line。如果用的是其他类型的STM32,需要换用合适的启动文件。
8 `" r) B6 B; e( g& O M* X/ ^) u7 Z- j- V6 d
(8)“STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\STM32F10x_StdPeriph_Driver\inc”和“STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\STM32F10x_StdPeriph_Driver\src”文件中的内容都拷贝到StdPeriphDriver目录中。“STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Template\stm32f10x_conf.h”拷贝到StdPeriphDriver目录中。读者可能注意到我将c文件和头文件都混到了一个文件夹中了,之所以这样管理文件,是为了让项目的目录结构看起来尽量的简单。现在,CMSIS下的文件应该有这些:
2 r7 g, D) Y/ a9 z$ t1 ]3 n/ _
0 w7 R8 A. }! j- z0 w core_cm3.c& ]7 T, ?4 ?# _
2 ~4 ~' D0 W! {. `8 W core_cm3.h7 u$ w1 y0 Q/ Q( V3 [
# [2 c/ K% r0 Z* ^. n: y$ s* o
startup_stm32f10x_cl.s
% i1 ?+ S& Q5 W% h7 M \4 w4 S# a5 `9 h. ~: }1 v
stm32f10x.h% D2 {1 u1 G8 K# G5 D( o- \
6 J1 n9 j0 O; l3 {( s
system_stm32f10x.c
% ~' P6 j* g1 g8 j8 l
. S' L, c. s& H3 ~% t system_stm32f10x.h
* t n. M3 B8 S4 _6 c5 P+ _
+ P4 E5 W$ o, r6 f- I1 kStdPeriphDriver目录中文件应该有这些:
5 T8 l! r9 n; _+ v' e s. o) s/ s# y( T0 D2 \$ ]: R- D q
misc.h# t; U- _# |. j8 A1 k" {) L* ?
+ q6 t# m. p. |; Z5 s- U& r
stm32f10x_adc.c: B$ a* f( Q( h) a' ?& h4 p
5 s2 m; {# z3 G. E; N
stm32f10x_adc.h! V% Z# @6 V( @4 N. U+ p
2 N6 g+ f1 A( v- a. B1 V
stm32f10x_bkp.c( T) w0 X# }6 J% R& J6 R8 A' B! M9 c
' v+ e3 r$ H% q1 T
stm32f10x_bkp.h* i- Z& {3 P! e9 O, ^% N
) j. R: U+ Z8 u) u) w: U% P stm32f10x_can.c
6 K# J9 ?; G* j
! E# K* e6 w% M+ N stm32f10x_can.h) Y6 w2 l4 X9 j& k4 A% U$ k
7 \1 ~9 {% N& x' }% L8 N
stm32f10x_cec.c$ t: o- o% W/ V' y
; u; j8 K- F6 |( l stm32f10x_cec.h% @4 o: b/ H$ H! R3 R
; H1 c+ ?) s, s( Z; N7 o- k1 G0 k, [! r
stm32f10x_crc.c, o7 y. H1 c, @& E
" V, g" D$ \* O5 `0 W
stm32f10x_crc.h9 O( _7 v1 Q2 ?' m
/ \7 e) X( e& W( [. g3 `* y6 }
stm32f10x_dac.c
( ~0 n$ I. Q* b: ?. y+ j9 K. ?+ ^$ K' ]% C- @9 |/ l9 G! @: ]
stm32f10x_dac.h
% w7 u8 V- G. O; h! y* w$ Z3 C9 r! o2 q0 ]2 v' w( b3 B5 y" O, Q
stm32f10x_dbgmcu.c7 X7 D& P% l. H- a0 u, N3 a8 z
7 I7 W- f, |2 O$ T) C8 j& d
stm32f10x_dbgmcu.h
4 P2 V2 a; A- f& M+ P Y& r" X/ l% |* [! Y0 }& ~
stm32f10x_dma.c
) n6 u4 d. A4 T+ V+ \& B. `/ C% S$ [9 o3 o( |
stm32f10x_dma.h: ^; M; [3 H2 C! q/ G# s
, h" L& @) q9 c/ g# R4 m3 k q. s7 m
stm32f10x_exti.c( V$ P. y! O5 f& u9 J% A
U' \( O, x2 M& ^" k stm32f10x_exti.h" j0 M! z5 K& C
& k, S- m* P1 }( S stm32f10x_flash.c
1 j7 p; o# A6 h. _& |
; G: `/ G9 p% ?& A) s. J, V0 ] stm32f10x_flash.h: O* \6 S1 T& q% d
( H. x1 D/ }$ _6 m
stm32f10x_fsmc.c
" X$ W9 E" ]$ I3 I; c, M2 @* K
$ F3 ~. ^$ b. t) H5 @# H# W stm32f10x_fsmc.h
' `6 u% a @8 q' g B
; i. `8 ~- B \, ^8 Z stm32f10x_gpio.c
- T* d/ ` z% n* U5 h' f
* K0 q6 w% t i" Z stm32f10x_gpio.h' Z2 f' [/ t: @* P7 @
( B1 p8 y( B- x4 j
stm32f10x_i2c.c
{& m) ^9 V' O7 i: G u; J- Y* t" f: ^
stm32f10x_i2c.h; Z# M D1 ^$ @+ E4 g, ^3 z5 h# g
, {* x) G8 g, x6 n& l stm32f10x_iwdg.c( |0 f) Z# M3 y7 b( x
' I) J1 C3 Q& F
stm32f10x_iwdg.h
# {1 `0 }" q- i4 j& K+ N, }- o2 l$ L( m: V: h$ Q3 m' }4 ^* T& B
stm32f10x_pwr.c: I8 O9 X/ l* K ?; I1 w& Q- b" c
* j7 V5 x* _, W1 k8 d: I2 i stm32f10x_pwr.h+ F+ L/ j! d2 z8 A7 \
j2 W0 v" Z1 a5 O+ T% ]- V
stm32f10x_rcc.c
! M' K6 h- `# C1 U) p2 M) ~) Y9 x* R3 e
stm32f10x_rcc.h
4 y' I8 j( }! K6 F, r1 Q f3 Q7 U X/ M& r* {: O3 D
stm32f10x_rtc.c7 X0 w, ]/ c+ y2 j
+ M/ \! U0 X. \1 z: E stm32f10x_rtc.h+ t0 q% L5 o5 b9 {- f( n
& e6 q1 G- Q. b5 |* E0 V+ j1 s
stm32f10x_sdio.c- u1 [' K- e! A
6 Q) J; M" s" c) f% h stm32f10x_sdio.h; B, p6 b& s8 u* l) o
k2 z0 N5 {4 i7 \- r/ ~1 A( R
stm32f10x_spi.c
6 e# c, n) M- V# K
" R: g- F0 ~% E* Q, P$ x8 S* E stm32f10x_spi.h
0 `: V0 ~8 K8 N- v9 \; w& j7 R# s: r! k. |; z
stm32f10x_tim.c
8 d3 g! w9 e6 P- K! Z b* [4 n# f* K
* U, ^: a! {( @. o* z+ T6 c stm32f10x_tim.h- s, \& u2 C/ `" k
. `' M4 I& j7 b1 p stm32f10x_usart.c& C4 e2 X* f {2 u4 Q/ \
r7 N7 C$ C E stm32f10x_usart.h
& i4 l8 B# _, L. M! F
% z1 H# m' I2 j stm32f10x_wwdg.c9 v+ `2 N. J! i' l Q, P
9 j8 d8 p8 v$ T
stm32f10x_wwdg.h
5 Y( {1 m9 d% E% k$ y, P$ E! o+ `' Y: K) \2 R2 U/ ~- O; Z' d1 P
stm32f10x_conf.h& K2 @7 ?& s$ t5 w# q/ S, V
6 i" X1 Q" r3 T2 a对于某个具体的项目,这些文件不一定都会用到,不过放在这里也没什么坏处。
$ ?( f* d |$ p/ B) K
. n5 F8 D. x; @4 e. C' D& B(9)将.\CMSIS;.\StdPeriphDriver 这两个目录加入到头文件的搜索目录中。
+ n- j& @5 e, O3 u2 G& v+ G7 T9 K! q6 A5 q4 H4 q
6 u# l* @2 b/ P- \% |( o
8 D! |5 Z7 Q7 A* K+ D(10)将 startup_stm32f10x_cl.s 添加到组 CMSIS 中,新建个main.c 文件,加入到组 Source 中。
9 K* Q+ L; p( j' L/ R7 o! M
, t4 R' j: @; |3 v6 b(11)修改“stm32f10x.h”文件。在文件中找到这一段:8 u& j) P r0 O8 E( `% M6 W
- #if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD) && !defined (STM32F10X_XL) && !defined (STM32F10X_CL) 4 {" k, I% `9 j& }& K. Z
- /* #define STM32F10X_LD */ /*!< STM32F10X_LD: STM32 Low density devices */& Y( z x7 B0 z* F E
- /* #define STM32F10X_LD_VL */ /*!< STM32F10X_LD_VL: STM32 Low density Value Line devices */ ' c6 N& u, o* a1 V
- /* #define STM32F10X_MD */ /*!< STM32F10X_MD: STM32 Medium density devices */
c* H" N# T* W- Q% K f - /* #define STM32F10X_MD_VL */ /*!< STM32F10X_MD_VL: STM32 Medium density Value Line devices */ & x+ b5 W0 p7 m
- - v' o; e8 O4 K
" B. S" A: `% h3 J* a. B- /* #define STM32F10X_HD_VL */ /*!< STM32F10X_HD: STM32 High density Value line devices */7 ^& h4 a' P/ f; ~. b- Y
- /* #define STM32F10X_HD */ /*!< STM32F10X_HD: STM32 High density devices */! s. h& p1 D) g( M: C1 I
- /* #define STM32F10X_XL */ /*!< STM32F10X_CL: STM32 XL-density devices */
! M# W2 s) }5 }) ^' E; z0 l+ N - /* #define STM32F10X_CL */ /*!< STM32F10X_CL: STM32 Connectivity line devices */
# e1 ~7 P! K G, b* G1 J - #endif
复制代码
, P% |6 D% x+ U1 N+ Z! D将对 “#define STM32F10X_CL”的注释去掉。9 S# {! T, n7 Y0 w' h( J9 u4 t
3 I' T# z5 m0 L) F1 w6 Z8 H
找到“#define USE_PERIPH_LIBRARY ”将注释去掉。
" b2 k! a# g) A6 @7 g# v* H
+ `: I: m: {6 ?! m" E9 ]9 U(12)将“system_stm32f10x.c”加入到组“CMSIS”中,找到如下代码:8 ~5 |3 R# A! f7 Q
9 l4 f% ]$ t# N
- #if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL) 2 e3 @/ {$ ?6 V. _
- /* #define SYSCLK_FREQ_HSE HSE_Value */
5 b# \3 Q; C# k: ? - #define SYSCLK_FREQ_24MHz 24000000) V$ ~8 |4 ^- s* m8 P' I
- #else* k3 Z$ M9 O* M5 y6 a
- /* #define SYSCLK_FREQ_HSE HSE_Value */( J! |+ Q6 @( b$ v: Y5 p
- /* #define SYSCLK_FREQ_24MHz 24000000 */
8 b( w8 k: l) u. c" w% p - /* #define SYSCLK_FREQ_36MHz 36000000 */% \* L+ q {% W+ ]8 y S
- /* #define SYSCLK_FREQ_48MHz 48000000 */# }; A# J6 m/ E1 X
- /* #define SYSCLK_FREQ_56MHz 56000000 */$ J- l, t/ c0 L7 P: S1 M3 z
- #define SYSCLK_FREQ_72MHz 72000000# w, N, M; f) G9 A6 j6 O. Y
- #endif
复制代码 ( K1 p% y4 g1 h! U7 [* u8 W% x: s$ T
根据板子上的使用的时钟系统来确定SYSCLK的频率。
; k0 N3 v+ ~" G5 B1 x) e$ c) q& S1 d: b Z+ [/ L
至此,该设置的都设置的差不多了,可以开始写应用代码了。我这里以闪灯程序为例吧。我的开发板上有四个LED,分别对应的GPIO端口D 的 PD2、PD3、PD4和PD7。
9 a0 I8 X/ s* y, D5 }
) A1 G( m( c# t* u下面先给一个不利用STM32F10x_StdPeriph_Driver 中库函数,只利用STM32F10x_StdPeriph_Driver中给出的外设寄存器的定义。下面是main.c 的代码。
) I$ W! z E/ R
# \( {6 A0 {6 Z {" E* k- #include "stm32f10x.h"8 r, @3 G& f! q" a u2 h
- 7 @$ i% a% m- I) A; k
- void delay(void)
' Q6 t6 V+ d: c/ Y& }" n% K/ r - {
. O |3 t$ j" R; k - uint32_t i;
: t7 C0 M; ^: c4 |* i. }; Y! k - for(i = 0; i < 3000000L; i++)+ b' @; u; x! @
- {4 P) _- @/ U+ h
- }! a/ F! ?. w& M% ~2 ~: S4 i
- }5 L. q: L2 V4 U! B. A8 Z- [9 ?
- int main(void)9 B$ j- h7 o0 {/ S1 j' e- ]4 @
- {
! u! }. m2 _$ n# x
; E+ J+ z+ r1 {2 y" O" z4 j T
2 ]+ d, T+ Z' S( ]4 j. V- RCC->APB2ENR |= 0x00000020; 6 f5 q6 s. R( b( B- s) { J
- GPIOD->CRL = 0x24422244; //PD2 PD3 PD4 PD7 Set to Output mode # ~& C3 t3 z" {2 o
- for(;;)1 l3 L. Z0 o* o: L* M
- {
( E5 V( x3 [$ ^ - 0 j. E9 ]) P0 M& g7 e
- GPIOD->ODR = 0x00000000;
$ I2 _, `# T# N1 | - delay();
+ I* U) Q8 C1 f7 M* ?0 M/ Q' s - GPIOD->ODR = 0x0000009C;
3 @0 u# @$ g' ^ - delay();
3 o8 J" w) n- P# N - } $ t4 Y5 d6 |8 _
- }
复制代码
! r( A# ^5 u) n6 q! l下面再给个利用TM32F10x_StdPeriph_Driver 中库函数的代码。+ A/ D$ M* M, e& ^5 H
- ~; k& c+ h* ]7 q5 X6 a# x+ t3 U$ _/ P
- #include "stm32f10x.h"6 D& p$ r( j3 R
- 8 `3 b5 _) Y8 L4 z( v: l
- #define RCC_GPIO_LED RCC_APB2Periph_GPIOD# N. l7 |% g: Q' M- S
- #define GPIO_LED_PORT GPIOD $ F4 m3 \" V& e
- #define GPIO_LED1 GPIO_Pin_2 ! L; f3 p7 p) w K1 E- r6 f
- #define GPIO_LED2 GPIO_Pin_3
' N5 ?& w/ z7 ?! `+ l! M/ a - #define GPIO_LED3 GPIO_Pin_4 % W: k$ w4 s& R5 Q3 I& l9 W. s
- #define GPIO_LED4 GPIO_Pin_7
% V7 Y2 C% E6 K, P* M! T3 B - #define GPIO_LED_ALL GPIO_LED1 |GPIO_LED2 |GPIO_LED3 |GPIO_LED4
( o7 ] ]5 M" ?$ {9 E - void delay(void)% H$ D7 ~+ g& p5 s, Z
- {
/ J9 _/ D5 w4 ] P) c$ d% m8 Q - uint32_t i;
[" {4 E* i$ T, p3 D) s$ v+ ~ - for(i = 0; i < 3000000L; i++)# b) I* t; a" Z: [( y- R: U2 r
- {3 [/ N( v# l6 G/ C" L
- }( N, J1 L$ @) F5 a5 k$ c' B" }- @
- }5 F/ g8 G+ J7 B4 Z3 l4 \
- int main(void)% i) B2 w- V4 ?1 T" N) j
- {
' r7 n _- H/ B @! B - GPIO_InitTypeDef GPIO_InitStructure;
- t/ A! R; @% y1 N- ?' z - SystemInit();1 U0 X# Y; u! C; _& E% y
- /* Enable GPIOB, GPIOC and AFIO clock */
) J% g! [! ~. r+ ~7 z# i1 [3 j* A3 p - RCC_APB2PeriphClockCmd(RCC_GPIO_LED | RCC_APB2Periph_AFIO , ENABLE);
, W3 p6 C; v1 c - ( h# r; F3 P+ A! \
- /* LEDs pins configuration */
$ }3 V2 m# S0 _! E5 J) h/ |- ~" U- `6 u - GPIO_InitStructure.GPIO_Pin = GPIO_LED_ALL;
" L3 ]: o! U2 z - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;* x! T% L, C. v; X( e) q4 Z% {+ `
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
. n/ P {2 F+ C+ k% g' u8 A0 b - GPIO_Init(GPIO_LED_PORT, &GPIO_InitStructure);) [( O8 y' z6 Z
- ( B% e5 g# j( S0 t) h7 r
- for(;;)
5 a* F; _2 J3 I+ B7 H0 I/ u" P3 l - {+ s/ E7 c7 j! e/ R+ f* W3 S# Q
- GPIO_SetBits(GPIO_LED_PORT, GPIO_LED_ALL);0 E( o( N3 W! R# ?
- delay();1 D2 n& q% D9 m" V, w0 R& ~- Q
- GPIO_ResetBits(GPIO_LED_PORT, GPIO_LED_ALL);/ n b. [$ [7 Z5 }
- delay();* b1 c2 n% Q) e+ K0 `6 g( g
- } . X9 ~8 f) O: \5 N9 G5 t
- }
复制代码
# s: [2 l/ J4 N3 h: X g编译程序,在链接阶段报错了,错误信息如下:
6 t. O$ x3 K5 o) Y4 i4 w! L N9 c" ~- M
- Build target 'STM32F107' p; {& Z+ k) `- a+ l# R: O
- linking.... }6 v- O; I# j a
- test.axf: Error: L6218E: Undefined symbol GPIO_Init (referred from main.o).
6 V0 q6 h9 a6 w7 G - test.axf: Error: L6218E: Undefined symbol GPIO_ResetBits (referred from main.o).9 f3 o3 E" @1 v9 Q- q) l
- test.axf: Error: L6218E: Undefined symbol GPIO_SetBits (referred from main.o).. a" Y% j( h ] T8 q2 J' ]4 X
- test.axf: Error: L6218E: Undefined symbol RCC_APB2PeriphClockCmd (referred from main.o).
9 E$ l- b e1 R. C - test.axf: Not enough information to list image symbols.! m) e; Z, h5 F9 y
- test.axf: Finished: 1 information, 0 warning and 4 error messages.
9 _, {3 _. a( A% ?+ i" n/ J - Target not created
复制代码
" b# x5 k0 t/ z2 G: f" w
; ~" ^3 e5 B/ @) [0 O5 V
! V0 z3 e! W$ t! n9 _- @
& R1 E+ ]1 c' ^" q说的很明白,GPIO_Init、GPIO_ResetBits、GPIO_SetBits、RCC_APB2PeriphClockCmd 这几个函数的实现没有找到。解决的办法显而易见,将“stm32f10x_gpio.c”和 “stm32f10x_rcc.c”两个文件加入到组“StdPeriphDriver”中,再编译就通过了。将程序下载到板子上,一切正常。8 ~. R6 p, U6 S" Z# `. @3 X7 ?
* o" g7 ?; x+ k/ r+ @上面只说了个大概的流程,还有些如何设置J-Link 一类的都略去了,因为介绍这些的文章实在是太多了。4 k# e- b" W/ l' ?3 ~) K
6 Z( L4 z( D6 c" { t# V& I! ~ Z% f6 {5 T E8 ?$ U3 D& e
2 x: P/ t( B) ^9 S! [% {3 G
, t$ L3 o D' @3 f$ h
|