一.库开发的优势
, g$ z) l+ U- }% S; r+ A9 H 开发速度快,便于移植。" r& z* F! K0 x( P% i" i- j
- L6 ?' B9 y5 N- _) p. ]; L
二.stm32F7xx几个重要文件5 P" U8 `. }4 ^! @9 S
1. HAL库关键文件
/ L1 G; {' Q" J9 M; X5 P6 r% m8 l. E7 a5 `7 f7 W
3 v5 Z5 W( E) m& f4 E7 p1 t
' b: b" o$ K+ j9 \0 y9 n2.stm32f7xx_it.c/h
/ Q" `( \6 ^% E( w 中断服务函数。基本都是空函数,我们可以去掉里面的函数,把中断服务函数写在任意可见的文件中。
/ t5 _: K- C9 K% L. l
2 B( j& `8 \' H2 x% g
5 p( c$ [: i3 A& I3 V5 _8 b, Q* W7 _: N7 \) v
3.stm32f7xx.h* p6 n6 I5 G$ Q" ~) _
所有F7系列的顶层头文件。通过条件编译包含某型号的头文件(此宏一般在target——c/c++里面定义STM32F767xx,后面都以stm32f767为例)。& f% C/ t' k, z& r
- t: j$ K* X8 L" Y, I. ~5 ^
- #if defined(STM32F756xx), q% W" @# |# B; }. v% `. F
- 2 q" Z5 H" }2 u* G
- #include "stm32f756xx.h": S: s$ e( F& X1 |
- ! E9 h9 t9 f9 h1 T* h
- #elif defined(STM32F746xx)4 P) i8 t* g7 S8 h/ @
* Q- Z6 u ^# B- #include "stm32f746xx.h"
6 P- I* u' O' X5 Y8 C - 8 c4 C1 x; c) S- B
- #elif defined(STM32F745xx)3 n6 [4 |3 ~4 i2 O* X
- * ]2 a* w) j" ^+ N2 f& H$ E
- #include "stm32f745xx.h"
# _# a5 k4 b+ k$ i - . g' B: ^1 H( Q
- #elif defined(STM32F765xx)
' r' u. C. s) u$ N - ) X/ g3 R2 S1 U7 W
- #include "stm32f765xx.h"
* g9 C9 r" P! X0 K1 [% f
! A! r% v9 F3 M' _1 A- #elif defined(STM32F767xx)
. o" z0 E' z8 z& T
$ H: v. O9 M) J4 C8 k* f9 s- #include "stm32f767xx.h"
4 l1 ?" I7 e F" i0 Z: ? - 8 e' ~. v( U, l) T& S" y2 c$ I* x; V, ^, v
- #elif defined(STM32F769xx)
! Z* u" o) I; [1 t
2 S0 r. |! N8 u: R! P5 R0 _- #include "stm32f769xx.h"2 D" s, @) H9 k% `
- i+ |& _ Z' ?, P. i
- #elif defined(STM32F777xx)
1 E* A3 } M" \" j: V, M
# O% ^, k7 v, O. }- #include "stm32f777xx.h"
- q. f5 I; e E: ?: d
9 s# @* O8 T/ N8 ?( A9 z- #elif defined(STM32F779xx)* Q2 S/ M( O4 r6 ^0 e+ L# T8 s
- ' O# c6 a; s' f2 h
- #include "stm32f779xx.h"
# a9 k5 f# k' i2 Q - 8 Q4 {! f4 V$ l. {' k- L& I
- #else
# J i( ]2 N; {! f, a5 R - $ ~& a1 L8 S/ u+ L/ a% m( {; u
- #error "Please select first the target STM32F7xx device used in your application (in stm32f7xx.h file)"' x5 R( C" Q, d$ t! y
0 l' d/ S. Y x9 z1 W( V+ e- #endif6 e+ T. L; ~8 u2 n9 ]$ A% b% h [
复制代码 7 k+ a1 b8 f. \3 I) _. x# Z+ {
4.stm32f767xx.h
2 }3 m* D$ c9 R- Z 主要就是寄存器的声明(一堆结构体和宏定义)。
6 w2 f) [7 Z9 W& M% Y
! G" v4 Y9 I" P, o+ X5.system_stm32f7xx.c/h5 B$ y( M: _! W/ R
主要定义了SystemInit和SystemCoreClockUpdate两个函数,后续会在这个文件里面加一个SetSysClock()函数. SystemInit主要是时钟系统的初始化和中断向量偏移地址设置(有bootloader的向量偏移需要修改)。SystemCoreClock是一个全局的值(这个在FreeRTOS的时钟配置的时候需要)。4 r/ ^+ ]1 n9 L3 V! ~
+ @5 {; A8 D; [, ^/ Q. J
6.stm32f7xx_hal_msp.c
, t) t" _2 C( D W& W 带MspInit的函数进行MCU级别硬件初始化设置,通常被上一层调用(如HAL_UART_Init——HAL_UART_MspInit)。7 A+ Y$ {1 l e5 b( a' @4 t* b% l2 e
/ y }) L V+ T" u2 @! S1 U7.startup_stm32f767xx.s
. L3 ^0 O+ r: R4 N: j& ]启动文件,上电先运行SystemInit,再运行到main。5 Z- O& U0 P6 O5 r1 x3 ]; y* A) Y
2 `; y) e2 I6 N* f
- ; Reset handler
# v" l' ^3 g$ N3 K' f" U% }- q2 M4 p - 9 |2 {( l8 A1 q# @. k9 n+ ^2 }2 L8 D
- Reset_Handler PROC9 P y- ^) c" n; f& \! X
# w; ^2 D2 b& l( p( O- EXPORT Reset_Handler [WEAK]8 C5 r. b. j( i+ S- E$ j6 T K
- 7 f: K0 @) N! H" X( X3 ?% ?4 D
- IMPORT SystemInit- Z X I( r9 s: o: r, J( g
- . T, \4 c x# p& u
- IMPORT __main
' u1 o+ Z/ A0 J - $ H+ E, n+ N/ _- i% s
- 1 M3 R* g% B* \5 p
6 S, O% c. A! J; r$ P" A0 |- LDR R0, =SystemInit
6 D6 y3 V/ S9 |7 W' t8 ` - * g5 l0 a0 T' v4 q2 m
- BLX R0
% j7 I6 P$ D V& p* v# S
/ ?( z4 Q" P3 R# _- LDR R0, =__main% I4 P8 i6 h; I+ ?8 w4 N* \7 Z
: k: N; ~+ x! b; t9 ]+ @- BX R0
+ p9 g9 L8 n0 ]8 ]
" E! y, F; }: w% i+ h- W3 J- ENDP7 ~$ T j& n$ e& [- p5 E" u
复制代码 % F1 `4 Q1 [/ q: z4 p
/ q3 P( d k* z8 Q2 U! A0 g9 s三.HAL库中__weak修饰符
W+ `4 {' Y% r/ p1 j, | weak:弱。被__weak修饰的函数就是“弱函数”,我们可以在自定义的文件中重新定义此函数(去掉__weak),编译器会执行我们自定义的函数。HAL库中一般在回调函数时用到。HAL中默认定义一个空的回调函数,保证编译器不会报错。
" l8 r* _; u! t0 L. \" K& j/ E8 y* Z7 y
四.程序的执行过程
' l! g5 w$ B; _/ E5 x A Reset_Handler —— SystemInit —— main —— HAL_init —— SetSysClock —— xxxInit…(FreeRTOS:xTaskCreate —— xTaskCreate), ^1 p" \+ I4 ]- f
& x* {8 o: R7 P
五.启动文件2 z% \6 j- [ u# [! ?0 M" x& P
主要指令:
; \+ M/ h. c' O3 x! |8 d& w7 Q
- B/ `& c( }- m* y* R3 V: x" O
9 x" f5 L3 n; l& K% y0 G
/ Q" G! o9 |& O5 A/ v4 B
3 q# r8 |2 X# v" V ]; H5 U5 Q! b9 U8 Y0 @9 l
+ S; P; H j$ i
Stack——栈,Stack_Size EQU 0x00000400 (局部变量,函数形参,函数调用等),值可以人为修改(不能超过内部SRAM)。$ C5 |# H8 B2 y8 |$ I
9 f8 }4 g- V3 Q. ?* K
Heap——堆,Heap_Size EQU 0x00000200(动态内存分配malloc/free)
/ Q% Z, X E% Z0 V7 X% ]. a5 m( z$ g
向量表——中断向量服务函数0 J5 t6 x5 L: o$ `9 \* n0 m8 s
3 M5 c# A/ i2 {( t$ |0 X% C2 L2 Q9 e1 G
复位程序——先进入SystemInit——main
2 `1 ^$ O! U/ w! N+ p- C: j) B' V5 C7 E# g$ H$ Q( H& c" k
关于启动文件详细描述请参考:STM32启动文件详细说明
4 y" |: V5 \7 W" ^* f5 }* i% X) q) g1 k. Y# x0 S3 b/ G$ y6 S1 t7 d
六.时钟设置(设置系统时钟)
* x# n% |3 c. }: e" Y5 f4 a3 R- /************************* PLL Parameters *************************************/" O( n+ \- ^/ r O6 J
- //时钟设置函数
; M( n5 D" A: {" s! x! w - //Fvco=Fs*(plln/pllm);' F r& h* i; V- Z v- [$ X
- //Fsys=Fvco/pllp=Fs*(plln/(pllm*pllp));- Q1 f) [" W6 e* f) c
- //Fusb=Fvco/pllq=Fs*(plln/(pllm*pllq));
9 K% d* _4 |4 q
! t) C( L: T7 H4 w, c: }- //Fvco:VCO频率+ X0 o3 ]. Q, x' A4 S2 Q# A" Z
- //Fsys:系统时钟频率
. J5 h, l% \9 n: M8 x - //Fusb:USB,SDIO,RNG等的时钟频率# ^& ]* t# k5 v9 J# m
- //Fs:PLL输入时钟频率,可以是HSI,HSE等.0 y- k9 _3 {1 ^1 F
- //plln:主PLL倍频系数(PLL倍频),取值范围:64~432. T \$ `+ i% L/ L9 u8 D/ E L
- //pllm:主PLL和音频PLL分频系数(PLL之前的分频),取值范围:2~63.
+ q2 O, d2 T+ L2 n- c5 T( A y, q - //pllp:系统时钟的主PLL分频系数(PLL之后的分频),取值范围:2,4,6,8.(仅限这4个值!)0 p* A3 m) P; S( L Y
- //pllq:USB/SDIO/随机数产生器等的主PLL分频系数(PLL之后的分频),取值范围:2~15.3 X* k+ z3 L* b0 R3 f" x3 D
- S7 I# b; F# ~8 F- //外部晶振为25M的时候,推荐值:plln=432,pllm=25,pllp=2,pllq=9.
) w# b; r" R: w6 p2 u0 [# X - //得到:Fvco=25*(432/25)=432Mhz
2 z' _* t- l7 [6 o6 B - // Fsys=432/2=216Mhz; u1 [8 _ N; X0 {
- // Fusb=432/9=48Mhz; |) i1 o& x& X/ B
- #define PLL_M 25+ p8 ]& O5 {' w6 o7 ]
- #define PLL_Q 9 g, L% G8 n7 ]3 H9 \) d
- #define PLL_N 432/ @# Y: t- K7 p
- #define PLL_P 2
! V1 @% e% N' T# M) N" Z B - $ p" Q# ^$ k" m! J4 K8 p7 ~8 L7 n
- void SetSysClock(void)/ X; Z) \# W4 g! V) b+ s& ?
- {% g+ s! y5 Q; O3 r; @1 o
- HAL_StatusTypeDef ret = HAL_OK;
/ z7 f" k6 Z( |+ g% H, g0 | - RCC_OscInitTypeDef RCC_OscInitStructure;
& J3 |- s. w" A9 k& {8 h - RCC_ClkInitTypeDef RCC_ClkInitStructure;
" o4 M2 j2 O4 E: J$ v- I# ?" X
5 z0 ]; j* S" d1 F( E- // __HAL_RCC_PWR_CLK_ENABLE(); //使能PWR时钟
5 j [' s3 ^3 [" l5 f - & j' Z+ }4 V( C g2 L4 ]
- RCC_OscInitStructure.OscillatorType = RCC_OSCILLATORTYPE_HSE; //时钟源为HSE
* G; z) |( Z# e! W - RCC_OscInitStructure.HSEState = RCC_HSE_ON; //打开HSE
+ k! b/ Y5 b, _8 {' Q - RCC_OscInitStructure.PLL.PLLState = RCC_PLL_ON; //打开PLL
2 q( L/ ]: H% O5 \( U( O - RCC_OscInitStructure.PLL.PLLSource = RCC_PLLSOURCE_HSE; //PLL时钟源选择HSE
6 R$ q H. g, i# y/ z7 D. O2 e2 y - RCC_OscInitStructure.PLL.PLLM = PLL_M; //主PLL和音频PLL分频系数(PLL之前的分频) n( O$ G% [8 T1 C# O5 u
- RCC_OscInitStructure.PLL.PLLN = PLL_N; //主PLL倍频系数(PLL倍频)
/ ~1 D; m+ A* ? `4 \1 ] - RCC_OscInitStructure.PLL.PLLP = PLL_P; //系统时钟的主PLL分频系数(PLL之后的分频)
. ?! C# N( C7 J9 U! K5 e - RCC_OscInitStructure.PLL.PLLQ = PLL_Q; //USB/SDIO/随机数产生器等的主PLL分频系数(PLL之后的分频)
, [7 M& m* [2 p% K* d! q0 R - ret = HAL_RCC_OscConfig(&RCC_OscInitStructure); //初始化
8 B2 }% f# ^9 h6 y - if(ret != HAL_OK) while(1);
2 A, B( z( h" j/ A! n- \) ] - 0 q% X. l" Y7 Q2 N
- ret = HAL_PWREx_EnableOverDrive(); //开启Over-Driver功能; d% I T' T$ P6 }& ?9 `' [
- if(ret != HAL_OK) while(1); g- ` o6 q9 v, w% W# A
9 w3 H$ j N) h& l- //选中PLL作为系统时钟源并且配置HCLK,PCLK1和PCLK2) C4 X7 k% t0 g H, z
- RCC_ClkInitStructure.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);9 F" H" ^3 `3 |) K# p3 B. M& F, @
- RCC_ClkInitStructure.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; //设置系统时钟时钟源为PLL7 _$ P* e. }9 ~- `- A
- RCC_ClkInitStructure.AHBCLKDivider = RCC_SYSCLK_DIV1; //AHB分频系数为11 k: b4 w4 g! J9 ~) f' t
- RCC_ClkInitStructure.APB1CLKDivider = RCC_HCLK_DIV4; //APB1分频系数为4+ i- |+ S$ p* p/ o3 t- f' V6 Y. o5 `8 Y
- RCC_ClkInitStructure.APB2CLKDivider = RCC_HCLK_DIV2; //APB2分频系数为2
! w* r6 l4 k. ]9 ]0 ^, u - 1 ?7 P! b1 Q. N$ c, X6 w4 O
- ret = HAL_RCC_ClockConfig(&RCC_ClkInitStructure, FLASH_LATENCY_7); //同时设置FLASH延时周期为7WS,也就是8个CPU周期。' g$ N# Y, p3 \, X
- if(ret != HAL_OK) while(1); X! S/ A/ ^# i$ v$ [' u
- }
5 _6 p: Y; @8 a
复制代码 ! f& k; v8 L/ X- T3 u7 o; I7 i; N6 K
! j, ~* R+ Z8 d* ^1 E. E: J: N6 J( x+ w- E
+ s4 F" L# G% p J
- \) ^3 a( i- f! Y
|