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

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

[复制链接]
STMCU小助手 发布时间:2021-12-6 11:32
应用FPU
. \9 M/ m' g, G, e* A+ c
$ x' x' B( p$ t0 F+ i5 v
20190703105214160.png
6 i; v! n- u8 y  r2 |

9 i. B/ J$ W. a. T, l$ k1 p. g- s  A

" \: o1 O# p- ~# S4 G6 p1、工程文件# K- u* {- h1 v/ Z; T6 g+ e
$ o$ q: R; a" v7 u& W' C+ H
startup_stm32f40_41xxx.s ' E5 }/ v8 i" e) P
4 B4 A) ~8 ~" ]( ]1 F' a9 V. g
新建一个 test.c 文件,并保存在 USER 文件夹下. c& R3 n/ E7 t4 I/ G# ]
2 b4 B- [/ T5 ^% M+ e- F
2、工程文件夹" Y) C+ @4 L5 G( ?
6 z, X+ Y" B' I1 k
USER 文件夹专门用来存放启动文件(startup_stm32f40_41xxx.s)、工程文件(test.uvprojx)等不可缺少的文件,% K( ?, b% A* s2 y- o( {
6 X3 k1 Y! n9 v& i4 L
OBJ 则用来存放这些编译过程中产生的中间文件(包括.hex 文件也将存放在这个文件夹里面)
/ G% _6 d7 R/ ^1 A5 Y3 z2 \; @' w% ^( S; Z% _
SYSTEM文件夹,该文件夹由 ALIENTEK 提供,可以在光盘任何一个实例的工程目录下找到) N9 O: X! Y2 O5 Q) V1 \+ c

, y) G% V6 }) I3 Q9 c5 I3、工程分组
0 Z3 U7 M* ^  r3 W
5 x' @' H! K0 [& D/ f5 B# g4 j Target 目录树上点击右键  Manage Project Items
6 v" N# ~, c( h( w
" @  ^) D: W7 _# x8 t7 S8 P我没改文件夹,还是用原来Objects,Listings
0 S: F5 ]9 i* e9 [7 m1 T# k9 |- o
& s" i- J3 X) h, G; y# D
2019070311235161.png

& B, E/ s0 R* P; E; a$ U/ [' X+ q- {1 }3 p9 P; o
9 }; H4 V" p- F. y4 V6 S6 O
2019070311225613.png

) `8 v/ Y) F/ p9 s# _
2 |6 P* p( Z7 Z' ~% x+ I" j/ t6 U" l$ d1 A% [( s, s
4、设置
# `: r$ r- \4 `0 w# }4 d9 b6 _' ^0 I1 [
20190703111442709.png
* K- C4 n/ C: ^- m3 c8 W* S

# r) J& F, W2 ?  g% t: X图中 1 处设置的 STM32F40_41xxx 宏,是为了兼容低版本的 MDK(比
4 O& C# C: I* Z如 MDK4/MDK3 等)才添加的,MDK5 在你选择器件的时候,就会内部定义这个宏,因此在
8 d' `# O0 _$ N3 Q  I. k3 M2 ]9 G' h1 O  CMDK5 下面,这里不设置也是可以的。但是为了兼容低版本的 MDK,我们还是将这个宏添加% w' p# {( Z$ U, K
进来。& Q9 M2 z: H2 }$ c: M9 M' f; M
图中 2 处是编译器优化选项,有-O0~-O3 四种选择(default 则是-O2),值越大,优化效果  x- W0 i) @; U! d" D
越强,但是仿真调试效果越差。这里我们选择-O0 优化,以得到最好的调试效果,方便开发代
' @+ N1 n: k% Z! t4 u码,在代码调试结束后,大家可以选择-O2 之类的优化,得到更好的性能和更少的代码占用量。8 Y; N. e2 t6 U
图中 3 处,One ELF Section per Function 主要是用来对冗余函数的优化。通过这个选项,
. D4 J* w% b# K3 _4 ]! A5 K可以在最后生成的二进制文件中将冗余函数排除掉,以便最大程度地优化最后生成的二进制代  I. ]" [' d! R8 N* r6 [" X
码,所以,我们一般勾选上这个,这样可以减少整个程序的代码量。* i% p$ `% ~8 O- p3 m
然后在 Include Paths 处(4 处),点击 5 处的按钮。在弹出的对话框中加入 SYSTEM 文件% B& \6 A, @; Z& c
夹下的 3 个文件夹名字,把这几个路径都加进去(此操作即加入编译器的头文件包含路径,后
, i9 V# }! P1 i" ~1 C: v面会经常用到)。如图 3.2.22 所示:
. `; c) f( ]  E4 ?9 ^. J. \# J4 _7 H/ x% a4 x# a

; {1 q5 e2 e6 V4 I! S5 I3 R/ Z6 ~) w
编译遇到错误:
+ x$ b7 y" r5 X/ F3 |( n; X) B- w0 m, W2 G/ U% I3 ~
SYSTEM\usart\usart.c(38): error:  #260-D: explicit type is missing ("int" assumed)
+ p! Q- T: B! L% l; F" m4 t  D7 j
) t  X, N6 d1 w: r3 [解决:
+ g/ k  e2 e" u& @( }/ l3 e' R
0 K. X2 K0 T1 i函数前加void,这是printf函数的相关定义( G6 L8 H! D  q+ J+ ]4 b$ T

2 d4 @/ g% i0 U( xvoid _sys_exit(int x)
7 N8 Y/ x) ~5 }7 c5 W- x! Y0 l, r
; ^! w# _( m# m9 G: ?# ~$ fwarning:#1-D last line of file ends without a
% b! D5 z; n! Y9 wnewline。这个警告是在告诉我们,在某个 C 文件的最后,没有输入新行,我们只需要双击这个
2 f# y3 Q: p' S2 j. A7 E" d# `警告,跳转到警告处,然后在后面输入多一个空行就好了。
+ X* U) a% i3 j! u% q0 c& @* k: X$ E1 \% D& l
SYSTEM文件夹
8 x, ^) |2 u" f$ T4 C! I
2 W3 I2 E3 ^' v! r0 X$ G9 M1、delay- I( N. P3 l: x! H) ^5 e
8 o1 R- O, l4 J+ c
顾名思义:延时函数文件夹& o  Q; z1 j( ^4 f/ g) X# q* j  H
" G& P. B, a: L! f1 D
20190703112603207.png

! O+ p- \" R( f  x" k" v1 H* B! |* i% f* R% s! D; t
***************SysTick定时器*****************着重理解
* D! w8 ]8 a* m( v1 b: N) R5 _. M2 q6 ?, x6 E. B
RTOS会用到
$ b2 z# v1 L- J4 L. F
# c7 k4 _% |2 a0 T2 R
20190703112856883.png

( c* H. i5 o. o1 U9 }5 W! Q* p
! T0 K6 n" ~# z5 E$ Z# ]! D5 e9 w' q

! p* k: y7 N) Lsys文件夹
& A5 K5 ?' G4 B: _# h" M) K) [$ O) M+ ]% {* e
20190703113106512.png
* {; ?, S: ?9 R' }  I2 |4 Y0 i: b

9 ?  w1 V# {+ g# C  u( K; P sys.c 和 sys.h 是由 ALIENTEK 提供,而其他 6 个文件,则都是拷贝自 STM32F4 的 CMSIS 库文件* l9 z- s, H8 V4 Z
4 L' E. B+ [# O3 J% M
sys.h
+ y$ t+ e  ]" l) K/ i$ L4 R9 h# |0 [) s0 B# n
实现对 STM32F4 各个 IO 口的位操作,包括读入和输出
# h5 V4 u2 O9 i
' U- F5 O! m- X* ^ PORTA的第七个 IO 口输出 1,则可以使用 PAout(6)=1;即可实现。我要判断 PORTA 的第 15 个位是否
* _# S2 X4 w' `. j等于 1,则可以使用 if(PAin(14)==1)/ I0 l0 c9 U* m* u6 z

2 y0 u0 d2 s! ^% |5 A, \0 V" n# r
  1. //
    % i" _) a4 {# o  c
  2. u8 Sys_Clock_Set(u32 plln,u32 pllm,u32 pllp,u32 pllq);                //系统时钟设置; B, M1 g/ ]8 b# [# ~) J/ {
  3. void Stm32_Clock_Init(u32 plln,u32 pllm,u32 pllp,u32 pllq); //时钟初始化  
    4 h5 Y$ J, _) o
  4. void Sys_Soft_Reset(void);                                                              //系统软复位
    " A1 E6 L. h3 F& I7 I$ Y
  5. void Sys_Standby(void);                                                                 //待机模式         
    " C. x& I( l4 M! F; W
  6. void MY_NVIC_SetVectorTable(u32 NVIC_VectTab, u32 Offset);        //设置偏移地址
      _; T" m- F' Q$ f! I
  7. void MY_NVIC_PriorityGroupConfig(u8 NVIC_Group);                        //设置NVIC分组
    - l* M! j6 T( z* ]$ p' G* Z9 J3 e* v
  8. void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group);//设置中断( H* {6 ~8 G8 l! _
  9. void Ex_NVIC_Config(u8 GPIOx,u8 BITx,u8 TRIM);                                //外部中断配置函数(只对GPIOA~I)$ C' F) t$ Z4 s- u3 @% f
  10. void GPIO_AF_Set(GPIO_TypeDef* GPIOx,u8 BITx,u8 AFx);                //GPIO复用功能设置
    ( S1 |0 A$ d. f# F% v& a' [: S
  11. void GPIO_Set(GPIO_TypeDef* GPIOx,u32 BITx,u32 MODE,u32 OTYPE,u32 OSPEED,u32 PUPD);//GPIO设置函数  
    7 e" ?8 ~) i' ]
  12. //以下为汇编函数
    * b' I' G- i8 q% w
  13. void WFI_SET(void);                //执行WFI指令
    2 y5 k7 @9 c5 J+ L1 l% X2 G% j6 a/ I
  14. void INTX_DISABLE(void);//关闭所有中断5 `' X* N/ @; D3 }) S6 _  d
  15. void INTX_ENABLE(void);        //开启所有中断8 H% M2 O7 s4 B1 n: i+ r1 |
  16. void MSR_MSP(u32 addr);        //设置堆栈地址 % z6 C: b& _! ^
  17. #endif
复制代码

# _; U( a9 k3 n, P5 @) Q************************时钟配置************************************
: G9 B- Y1 C( m, f( _0 D8 }/ Y! R
* v& m; \) A. ]2 y  I/ n" nusart 文件夹8 C5 {; G0 y0 ?' S! W1 D: Z
" d" m4 l; k. N/ x0 r& Y( b8 F/ w
usart.c 和 usart.h 两个文件。这两个文件用于串口的初始化和中断接收/ q( L  L( z1 P3 g) U# C9 K

  t) t9 W* W: J0 Y; U7 D: ousart.c里面包含了2个函数一个是void USART1_IRQHandler(void);另外一个是void uart_init(u32
! Z" g8 Q9 D. @pclk2,u32 bound);里面还有一段对串口 printf 的支持代码,如果去掉,则会导致 printf 无法使  u9 r1 _  L' m! b, e- z3 h

3 e4 W; o* G2 d0 k
) d# }$ ]" s9 z' A: c9 @; j在配置 STM32F4 外设的时候,任何时候都要先使能该外设的时钟!
+ [& \8 }, M/ b1 t& G2 k8 w% i/ b- j! c; Y3 z- t  q
20190703182927542.png

# ~/ E& T0 \% r" l( U6 H* }8 _' Q  K3 }
RCC->AHB1ENR|=1<<5;//使能 PORTF 时钟
: l  N$ Z. W  M" D% ?6 u$ c5 r  A% m, }* T, _- R- ?

0 _6 t# n, ], J7 K8 aI/O   输出I 输入# _2 C0 U+ k5 {/ D  F; u" _$ ?

2 z: q" e/ A5 B! l- @+ M1 B1、使能时钟5 r9 u! K5 S) k$ X( Q
* \) C! T0 g& M8 U0 W0 r
2、IO设置   void GPIO_Set(GPIO_TypeDef* GPIOx,u32 BITx,u32 MODE,u32 OTYPE,u32 OSPEED,u32 PUPD)+ A& ]; n. G9 L% i/ N
  q! u' R  F+ R0 A; B
//GPIO通用设置 3 n" l4 p0 j* r
//GPIOx:GPIOA~GPIOI.
! G2 C. f: g0 o7 [+ d' S) B& ?//BITx:0X0000~0XFFFF,位设置,每个位代表一个IO,第0位代表Px0,第1位代表Px1,依次类推.比如0X0101,代表同时设置Px0和Px8.  ?) q! {9 N7 o. P
//MODE:0~3;模式选择,0,输入(系统复位默认状态);1,普通输出;2,复用功能;3,模拟输入., {, H+ r$ _; H4 M
//OTYPE:0/1;输出类型选择,0,推挽输出;1,开漏输出.
" n& Q) U7 c0 c$ Q6 _+ l//OSPEED:0~3;输出速度设置,0,2Mhz;1,25Mhz;2,50Mhz;3,100Mh.
2 y; r, k+ Z1 H2 Z  J, h//PUPD:0~3:上下拉设置,0,不带上下拉;1,上拉;2,下拉;3,保留.. g0 ]& c9 z$ g; M) F
//注意:在输入模式(普通输入/模拟输入)下,OTYPE和OSPEED参数无效!!! Z! v) }6 [/ Y7 W2 d" I; s7 A5 I8 G, @3 h

9 v5 G3 [# e3 X2 Y. C8 l7 w' J3、PFout(n)   PFin(n)
& s& @# T/ A) B; m+ G+ X- y9 Y# m2 A' O- y' j- d9 B( h- A
" I) l1 E& k) O& N; F6 k
串口
* g; Q% |5 t: e9 i8 W& z0 _% ?, Q( a& H- M) ~  ~; b$ c
STM32F4 的串口使用起来还是蛮简单的,只要你开启了串口时钟,并设置相应 IO 口的模式,然后配置一下波特率,数据位长度,奇偶校验位等信息,就可以使用了,; p4 D! @! t" k8 `) @
2 k* O9 ~$ ]& b. }" }* F2 L5 y
uart_init(84,115200);  //串口初始化为 115200$ n4 p6 L0 B: h! p: I
- Z' E2 \. h0 M# B
  N1 m% Y7 X, {- [- w* V
收藏 评论0 发布时间:2021-12-6 11:32

举报

0个回答

所属标签

相似技术帖

官网相关资源

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