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

【经验分享】正点原子STM32F4笔记

[复制链接]
STMCU小助手 发布时间:2021-12-6 11:32
应用FPU ! F8 I* t' |' G
  K% Q$ n6 E( D5 D
20190703105214160.png

+ ?- u1 f% f  e9 h! O2 n# m) ^' G: t2 v" z2 U, h; E

0 }; N; X2 O9 R. Z1 }- d$ `3 W& z7 X! O; m, I& K
1、工程文件- J+ a+ k; ^1 i2 {5 X
+ i' c$ ]# n2 t' X1 Y% H( a
startup_stm32f40_41xxx.s
6 d0 ]: A; G: |. p2 |3 S
6 S( l' e' w" K7 n1 H新建一个 test.c 文件,并保存在 USER 文件夹下( ~4 v, r: S. j) I" ~7 x! J
$ Z' W& T" s$ Y8 ]7 l) z
2、工程文件夹
) Z" [; |" h+ y" O* {6 r
7 E) k- b, X1 K; X; UUSER 文件夹专门用来存放启动文件(startup_stm32f40_41xxx.s)、工程文件(test.uvprojx)等不可缺少的文件,
' N5 X# Z: U% v7 N0 T4 B6 [7 C- R. X
OBJ 则用来存放这些编译过程中产生的中间文件(包括.hex 文件也将存放在这个文件夹里面)# N$ r- [+ O8 P9 o/ |$ y% h$ H

0 I, {8 u7 v; L SYSTEM文件夹,该文件夹由 ALIENTEK 提供,可以在光盘任何一个实例的工程目录下找到' C! U' D9 a" C/ f# j& J6 P6 W
$ u( Y6 N& F# K4 r4 A) B6 k+ f7 c
3、工程分组
7 m# R8 z$ p. ?6 ^/ ~' W7 U) V
- R1 f3 z& A& Z- x' z' Q$ ? Target 目录树上点击右键  Manage Project Items
! w1 Q' F' k$ R9 k9 Z/ Q1 |
6 V- w2 P" {8 H( @我没改文件夹,还是用原来Objects,Listings
" A- I7 {5 ]) `
' N) L6 l; c6 D3 w9 ?* A
2019070311235161.png
, W0 X/ P  K. T& Z( l9 W3 r

. f0 a9 x- P6 H$ m1 n% b, l
5 m5 v$ v5 W4 d, H  h$ D. D) D* z5 t) J
2019070311225613.png
: L' p; u- E# N6 B" g3 F0 z$ T3 q( s2 T
5 y1 T# @0 c6 d9 \: l$ X6 J
- a. i7 O! ~' G8 F+ b
4、设置/ B! C5 X  X' _( E* f$ N/ n  a
9 ^% j  z: O9 k% A  L
20190703111442709.png
; m) W5 C$ M: d/ S& z- q4 ?9 o

6 K* P) w8 c- G5 K7 ?0 O. s图中 1 处设置的 STM32F40_41xxx 宏,是为了兼容低版本的 MDK(比, M0 a, ?/ P# {! M# P3 x
如 MDK4/MDK3 等)才添加的,MDK5 在你选择器件的时候,就会内部定义这个宏,因此在/ e' z2 B) B& I1 \
MDK5 下面,这里不设置也是可以的。但是为了兼容低版本的 MDK,我们还是将这个宏添加
4 T1 O) H& C3 W9 Y& S: L; B- I进来。" U# s- y8 q: d- u& u% J; o
图中 2 处是编译器优化选项,有-O0~-O3 四种选择(default 则是-O2),值越大,优化效果6 }' a3 i8 M8 p- `, }
越强,但是仿真调试效果越差。这里我们选择-O0 优化,以得到最好的调试效果,方便开发代8 i' h& Y- y. l1 g) l
码,在代码调试结束后,大家可以选择-O2 之类的优化,得到更好的性能和更少的代码占用量。
9 ?" e8 U  t. i9 j! n1 c+ i) ^图中 3 处,One ELF Section per Function 主要是用来对冗余函数的优化。通过这个选项,
# j+ H$ a/ i2 d' L1 J& d( H可以在最后生成的二进制文件中将冗余函数排除掉,以便最大程度地优化最后生成的二进制代
4 ~. r" Z7 y2 L% W0 {$ U码,所以,我们一般勾选上这个,这样可以减少整个程序的代码量。
% O, }0 Y. G6 h* {然后在 Include Paths 处(4 处),点击 5 处的按钮。在弹出的对话框中加入 SYSTEM 文件9 ^: I" i. T8 z6 P
夹下的 3 个文件夹名字,把这几个路径都加进去(此操作即加入编译器的头文件包含路径,后
7 d* v9 N' }$ o4 @面会经常用到)。如图 3.2.22 所示:
1 N; p2 f) z2 M+ V. r' i  {6 a/ ?) M4 m
& v9 ?/ U, E' q  r" [
; a( ]* f! Y2 ^2 _( T
编译遇到错误:
. N' X; ]1 m! z, D, T. }4 ^; ^* m* t  \" C
SYSTEM\usart\usart.c(38): error:  #260-D: explicit type is missing ("int" assumed)/ d& E, h! }4 k- Y
4 b0 y$ E" R4 v5 r
解决:3 `9 D. Q2 R) W" n

6 E3 y+ E3 Z( `+ R6 L1 w, g  J5 W( \函数前加void,这是printf函数的相关定义
) L+ s" f" H2 W) ]: v  v& T. T! m" m- l' a. Q( M3 H
void _sys_exit(int x); r0 M0 l0 S4 u! L: _; O, k
! }' c0 X* c( K* s  w4 T+ _7 S/ U
warning:#1-D last line of file ends without a. M$ U4 h% Q! S" N
newline。这个警告是在告诉我们,在某个 C 文件的最后,没有输入新行,我们只需要双击这个3 `5 H6 Y2 e0 P
警告,跳转到警告处,然后在后面输入多一个空行就好了。% P- O# O% Q0 ]

1 o* x1 _5 @: G% x0 f- q2 LSYSTEM文件夹
0 O: q/ m' N! t; R- e: Z1 Z$ u* {7 p' \" }! ~
1、delay
& ]& X9 c" e# R: J( ~: u) k; X" R5 Y8 U8 p9 I
顾名思义:延时函数文件夹2 F5 j: o' |4 f0 H
/ k7 T+ O1 r: o* s
20190703112603207.png

7 _# c6 U& b+ m9 Z* g0 @( @; _) ~6 O' K( K! r* l: c
***************SysTick定时器*****************着重理解
; a+ o& D/ L: a$ C5 k; D9 v/ v& w& @7 c/ \; V" p, _# Z
RTOS会用到
4 E- ?( h8 V' ~" z  \- ~! P( ^4 r( E
  V4 S) o. g4 N; ]) n
20190703112856883.png

$ y1 {8 e# r7 k; @7 X7 W! A4 F$ K7 f4 j) @7 |
- {" @& l- {! y2 U

# D, ]5 P6 _) @  G% Nsys文件夹/ a! h. e9 h. ?+ b

8 A+ n! m* E! E# }: v. y& a
20190703113106512.png

, k1 S7 o; `5 e7 \  f2 S6 t7 O+ j2 [6 K) s7 E1 \8 m. S' V+ |' W
sys.c 和 sys.h 是由 ALIENTEK 提供,而其他 6 个文件,则都是拷贝自 STM32F4 的 CMSIS 库文件5 |5 f8 S$ i) X/ s; q3 ^

. Q5 d* e: e& f( M/ k1 ]3 V8 ] sys.h : z8 G6 y; [* B) n6 |

# N9 b! J+ v% ^7 ]/ `4 K- L7 V5 X实现对 STM32F4 各个 IO 口的位操作,包括读入和输出
7 ]2 W* \6 r, M# B7 s! j% G! P0 Y$ z5 H! Y  e
PORTA的第七个 IO 口输出 1,则可以使用 PAout(6)=1;即可实现。我要判断 PORTA 的第 15 个位是否
2 b: h5 |+ K& }2 f' o$ I7 c  E% v等于 1,则可以使用 if(PAin(14)==1)
! @& x5 @% I' N& B' g- s$ _. g/ ]# D) A! o2 k6 H8 R$ H9 Z  k
  1. //
    + |; E6 i- g; T; H9 [/ K0 l+ B
  2. u8 Sys_Clock_Set(u32 plln,u32 pllm,u32 pllp,u32 pllq);                //系统时钟设置
    ; V, P+ Y3 `5 U. m- z# ^5 F
  3. void Stm32_Clock_Init(u32 plln,u32 pllm,u32 pllp,u32 pllq); //时钟初始化  - M. @3 T7 l4 ?
  4. void Sys_Soft_Reset(void);                                                              //系统软复位
    . |: |# r( P2 I
  5. void Sys_Standby(void);                                                                 //待机模式         % J( n. l8 {4 X9 }
  6. void MY_NVIC_SetVectorTable(u32 NVIC_VectTab, u32 Offset);        //设置偏移地址
    ; _3 f  V; O- s8 i7 ^; P" e, q4 n
  7. void MY_NVIC_PriorityGroupConfig(u8 NVIC_Group);                        //设置NVIC分组
    ) _! D. o( u9 ?5 }: s# z( c
  8. void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group);//设置中断1 s, {* s0 G/ h- i& a
  9. void Ex_NVIC_Config(u8 GPIOx,u8 BITx,u8 TRIM);                                //外部中断配置函数(只对GPIOA~I): n7 p$ K7 ?( N1 P. I+ i
  10. void GPIO_AF_Set(GPIO_TypeDef* GPIOx,u8 BITx,u8 AFx);                //GPIO复用功能设置* K, Q7 M; x0 g; I
  11. void GPIO_Set(GPIO_TypeDef* GPIOx,u32 BITx,u32 MODE,u32 OTYPE,u32 OSPEED,u32 PUPD);//GPIO设置函数  
    ( p6 X! i0 J) @7 K- n8 b! G4 D
  12. //以下为汇编函数
    # F$ S( n1 P% E2 G3 U
  13. void WFI_SET(void);                //执行WFI指令, |2 v+ q. z3 c3 K. ?
  14. void INTX_DISABLE(void);//关闭所有中断
    % D4 ]9 C; m: ?, O! v* c
  15. void INTX_ENABLE(void);        //开启所有中断3 P3 l& U, I7 d5 {2 J
  16. void MSR_MSP(u32 addr);        //设置堆栈地址 8 Y# |) B- X3 K- z
  17. #endif
复制代码

# ^9 w2 i7 `; I************************时钟配置************************************
' x# M2 e% X0 h# |" s4 Q& U8 |
usart 文件夹. v( u4 ]- x1 Q- G

. U% N5 M8 n( ` usart.c 和 usart.h 两个文件。这两个文件用于串口的初始化和中断接收# J, `/ M& `# a
/ R# F! n' M. ~" Z
usart.c里面包含了2个函数一个是void USART1_IRQHandler(void);另外一个是void uart_init(u32$ M* z/ C' D6 M  Z; b1 o! L
pclk2,u32 bound);里面还有一段对串口 printf 的支持代码,如果去掉,则会导致 printf 无法使
; ], c# N* D2 ]# w7 B7 c& i! p( O3 S, u8 J& P$ ?

; S$ M, s) t0 m% Y; z9 v; ~在配置 STM32F4 外设的时候,任何时候都要先使能该外设的时钟!4 p: J+ Q8 w" j4 q7 n  f( ^- ~9 \

; W0 R0 A+ I% x1 n( X1 }" `2 p6 q
20190703182927542.png

2 F% Z# ~$ W# r+ X7 p( y8 l; A
" {7 ]- ]; |4 V+ s; }. qRCC->AHB1ENR|=1<<5;//使能 PORTF 时钟
; y; B3 m6 f+ o1 c& e5 M% S# f* h4 f/ |. H' `8 D" L+ S
: F: T. u  X4 S' A
I/O   输出I 输入
  t# i4 H/ w0 ]/ c& {& J6 f; |
1、使能时钟
- f' N& H; j6 }  P$ k8 q8 Z- P) C3 l2 w: n6 j( Z% A1 g4 z3 y
2、IO设置   void GPIO_Set(GPIO_TypeDef* GPIOx,u32 BITx,u32 MODE,u32 OTYPE,u32 OSPEED,u32 PUPD)/ i& f- S+ m% d* q/ l
' D$ a% i  g  [& K2 m6 J% Z
//GPIO通用设置
& z4 _% I( b0 t//GPIOx:GPIOA~GPIOI.
* C, `+ G) ?4 Y0 d$ o2 M- d# G//BITx:0X0000~0XFFFF,位设置,每个位代表一个IO,第0位代表Px0,第1位代表Px1,依次类推.比如0X0101,代表同时设置Px0和Px8.5 `/ k5 `) H* @: l1 D
//MODE:0~3;模式选择,0,输入(系统复位默认状态);1,普通输出;2,复用功能;3,模拟输入.
: _( e  ^- I! P" @% ]% n) K//OTYPE:0/1;输出类型选择,0,推挽输出;1,开漏输出.) ~0 T; ?5 r7 F2 e4 [) Z2 l/ s- X9 A! [
//OSPEED:0~3;输出速度设置,0,2Mhz;1,25Mhz;2,50Mhz;3,100Mh. $ G/ _6 h1 u3 B1 o* A
//PUPD:0~3:上下拉设置,0,不带上下拉;1,上拉;2,下拉;3,保留.( P5 b4 s# j7 u) T% S" i
//注意:在输入模式(普通输入/模拟输入)下,OTYPE和OSPEED参数无效!!8 ?& A1 M* j8 v& R% o6 _/ l
* Z1 t; u& h1 L# F
3、PFout(n)   PFin(n)
$ Q1 F9 H) {! E7 a
' H+ @4 r" r3 g0 \- h4 I) ]
7 g4 d6 D# ^% i- U* b串口/ `# c3 r# T' k( {

+ f" |6 B# G  H) b+ Z) S; `) PSTM32F4 的串口使用起来还是蛮简单的,只要你开启了串口时钟,并设置相应 IO 口的模式,然后配置一下波特率,数据位长度,奇偶校验位等信息,就可以使用了,
9 r* V9 Y# V2 @- w( ]3 L/ U5 u! n& i5 e/ h! w
uart_init(84,115200);  //串口初始化为 1152000 s1 E' ?* e8 D! s8 Q

' O) e( U( M# V# U
  n) ?% `' x7 i, y" Z/ U, k5 Y
收藏 评论0 发布时间:2021-12-6 11:32

举报

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