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

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

[复制链接]
STMCU小助手 发布时间:2021-12-6 11:32
应用FPU
" c- i% Z, k/ j, P
* {# C7 {: d& ~; `/ W+ m: g1 ]; n; e
20190703105214160.png
5 h; ?, H( {& C( r9 e) @$ d2 T' t8 g$ f

+ k+ f$ X+ P$ V% l4 P
: p8 Z# i3 C) i, q# _" N
6 K# e, k  K/ W8 r1、工程文件
: s3 u. r, R( m' b1 Y+ O& O! A* P& H+ j# Z5 a4 w, `' `: @
startup_stm32f40_41xxx.s
2 s& ~) {2 m3 X0 o5 K6 I& l' B: o' K; ^1 Y' p! \  \
新建一个 test.c 文件,并保存在 USER 文件夹下
5 R1 T: x5 \) X1 w: z; M0 K" Y' h& L! L- g
2、工程文件夹
" T5 L. s, K$ c5 \$ d5 M6 }
# N9 c: Y" s) G8 MUSER 文件夹专门用来存放启动文件(startup_stm32f40_41xxx.s)、工程文件(test.uvprojx)等不可缺少的文件,* A( z0 f, J; |/ ?3 u/ i

& h- J. T8 A* A9 H- jOBJ 则用来存放这些编译过程中产生的中间文件(包括.hex 文件也将存放在这个文件夹里面)
1 Y* \! Z8 `  x0 ]/ ?. y8 a8 S9 }& K2 V3 ~* T# z6 j
SYSTEM文件夹,该文件夹由 ALIENTEK 提供,可以在光盘任何一个实例的工程目录下找到
$ b5 v! w% w3 Z8 |' W/ x' t7 G5 l5 J; k  B" m/ @
3、工程分组( \' X; w+ P: f1 ~! V4 W

% `; t- N! n, u Target 目录树上点击右键  Manage Project Items
7 T3 h! A+ e5 A. t0 m; ?& c2 I; `. J5 L7 C) p- X; M- `2 L
我没改文件夹,还是用原来Objects,Listings* q1 E' j/ u7 I; d4 G, i
# n. K. a2 E  l. R, p5 J- I9 r$ k
2019070311235161.png

+ \  g( E2 |8 u
5 k$ x! M$ Z6 I, E" [7 F( {& k/ ~/ V$ r
2019070311225613.png

8 w) W1 p! s. t& {3 _% p
1 A+ t' ]) A/ i% g7 [# C
1 V" J2 G* r0 W4、设置
7 |: t6 t# T: \1 ~
5 c5 Z& J" T$ v
20190703111442709.png

% f: R8 W- R5 N3 u$ \$ y$ u4 [+ g; q9 p% K5 B: m
图中 1 处设置的 STM32F40_41xxx 宏,是为了兼容低版本的 MDK(比2 k/ J* x9 T- b) Y) D* S1 p
如 MDK4/MDK3 等)才添加的,MDK5 在你选择器件的时候,就会内部定义这个宏,因此在* k- ^$ n. I/ e& ^
MDK5 下面,这里不设置也是可以的。但是为了兼容低版本的 MDK,我们还是将这个宏添加
& H9 r/ c6 ^0 k进来。) V% p1 s, E$ j# x9 ~  p
图中 2 处是编译器优化选项,有-O0~-O3 四种选择(default 则是-O2),值越大,优化效果" z2 S) q. c5 O* Z" ?+ \
越强,但是仿真调试效果越差。这里我们选择-O0 优化,以得到最好的调试效果,方便开发代
4 c* j, v+ }1 x5 [  @码,在代码调试结束后,大家可以选择-O2 之类的优化,得到更好的性能和更少的代码占用量。
; r7 W4 D' ?) m8 A2 e( Q图中 3 处,One ELF Section per Function 主要是用来对冗余函数的优化。通过这个选项,
3 Q4 s" b  i* U4 c/ u+ t7 H可以在最后生成的二进制文件中将冗余函数排除掉,以便最大程度地优化最后生成的二进制代& I1 U! ]: j* z0 `: S# J
码,所以,我们一般勾选上这个,这样可以减少整个程序的代码量。
8 \) ^" h8 D4 o然后在 Include Paths 处(4 处),点击 5 处的按钮。在弹出的对话框中加入 SYSTEM 文件. Q3 J6 {1 Y% g: {2 D. B
夹下的 3 个文件夹名字,把这几个路径都加进去(此操作即加入编译器的头文件包含路径,后  i7 a, l) Q0 a$ c% h$ R+ f
面会经常用到)。如图 3.2.22 所示:% M4 f+ m9 N7 u+ X1 q
3 p( ~4 \8 W# X/ T# G0 K' S# @

; @5 e' U, B& ?
- U6 N; m' ~" s编译遇到错误:' K& u, D( d5 Z7 @  r% J

" q9 W* j$ C  JSYSTEM\usart\usart.c(38): error:  #260-D: explicit type is missing ("int" assumed)
! E: n* P8 N% i6 `) x+ Y7 U
  E5 U0 O& M9 h$ k% G/ J解决:
( w4 r% `8 a' F
$ X8 \/ g6 D' d  ]2 Q函数前加void,这是printf函数的相关定义
/ x$ R4 U. z$ O$ ?3 s7 k- _/ U8 X- P/ C4 A' G: ^$ _
void _sys_exit(int x)
8 x/ q  q: N: K' ^
& u2 t' Z4 N- z6 ?# W, V1 ]% Kwarning:#1-D last line of file ends without a9 D7 E' Y- P* t: V' O  ]) K6 O1 T. \! U
newline。这个警告是在告诉我们,在某个 C 文件的最后,没有输入新行,我们只需要双击这个
; B+ g+ H" F/ q* E警告,跳转到警告处,然后在后面输入多一个空行就好了。
# F# d3 B/ @2 A* X" N; l: h- d' n; X
SYSTEM文件夹
7 W. }4 {0 T! j. v
' O) j' Q) e# y" a( T1、delay% ~) e4 j5 N" y" v
* v( T8 O3 S5 v9 e( f% B. E
顾名思义:延时函数文件夹: r* W4 J, B! E. U: ]

% ~$ E! e" {  f" C; J
20190703112603207.png

; w* B. r$ t- C$ y
, [8 ^! O( Z! Q0 m: O; U***************SysTick定时器*****************着重理解; ?( B% m5 p) W: ]
* ^% B' g9 b% D7 P
RTOS会用到
, L" {1 X. h& n% b: n  T
% @$ E5 k7 A5 Y% S1 t, h
20190703112856883.png
* f9 E' E6 h" I! V

- I! [- _2 K, V( T. z6 h; O3 s* r* R1 l5 I+ x

0 ^- ?0 c0 x% j; P/ |' B7 a2 fsys文件夹
2 R1 c1 p8 q) n+ s/ ~2 j
* p0 E4 W/ J0 d/ C+ w
20190703113106512.png
2 w! ~7 |: n3 |0 O

, x3 F; f* N+ u# p sys.c 和 sys.h 是由 ALIENTEK 提供,而其他 6 个文件,则都是拷贝自 STM32F4 的 CMSIS 库文件
9 |6 S" Q3 @, i: R6 R( h" t  V9 q9 p, q4 H8 I9 C
sys.h , D! I; G; e$ E- F0 j
6 C. c8 E- K. g/ Q1 B
实现对 STM32F4 各个 IO 口的位操作,包括读入和输出
1 [- E9 s1 U( z5 |) Y/ t7 p" v0 _- O* g8 x9 j4 n/ d0 M
PORTA的第七个 IO 口输出 1,则可以使用 PAout(6)=1;即可实现。我要判断 PORTA 的第 15 个位是否8 ]7 ~' X) S; t$ {
等于 1,则可以使用 if(PAin(14)==1), A5 [! L9 d9 J2 X) `
5 Q. R9 A+ p) F# Z
  1. //
    : l8 A" ]: {" t" Q& w% r; q
  2. u8 Sys_Clock_Set(u32 plln,u32 pllm,u32 pllp,u32 pllq);                //系统时钟设置
    0 P4 g* l' C( \
  3. void Stm32_Clock_Init(u32 plln,u32 pllm,u32 pllp,u32 pllq); //时钟初始化  
    - o& T. P  c2 Y0 p
  4. void Sys_Soft_Reset(void);                                                              //系统软复位- R& W0 Y  M2 [' G& v! J2 G
  5. void Sys_Standby(void);                                                                 //待机模式         
    9 m7 t( H0 U# b6 f  x# C7 ^
  6. void MY_NVIC_SetVectorTable(u32 NVIC_VectTab, u32 Offset);        //设置偏移地址" G) c: i$ r( D0 R# f+ u+ v# l  H3 u" e
  7. void MY_NVIC_PriorityGroupConfig(u8 NVIC_Group);                        //设置NVIC分组/ S, _8 l& T( s5 z
  8. void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group);//设置中断" C. R; I$ C- O# u
  9. void Ex_NVIC_Config(u8 GPIOx,u8 BITx,u8 TRIM);                                //外部中断配置函数(只对GPIOA~I)
    9 j7 _5 A7 A6 k8 g- c( J+ O4 T
  10. void GPIO_AF_Set(GPIO_TypeDef* GPIOx,u8 BITx,u8 AFx);                //GPIO复用功能设置
    # j2 ^: r9 h1 w+ f1 W% @
  11. void GPIO_Set(GPIO_TypeDef* GPIOx,u32 BITx,u32 MODE,u32 OTYPE,u32 OSPEED,u32 PUPD);//GPIO设置函数  
      q: \  Y1 }0 Y% _
  12. //以下为汇编函数- ?9 R6 f. q+ P: f% t( t
  13. void WFI_SET(void);                //执行WFI指令* a/ L" m0 M# n  a
  14. void INTX_DISABLE(void);//关闭所有中断+ j# H* T4 J1 Z" _  Z
  15. void INTX_ENABLE(void);        //开启所有中断9 R; m; c1 k5 Q' ]2 D9 A6 p. G  K' c
  16. void MSR_MSP(u32 addr);        //设置堆栈地址
    2 s3 j2 O% S0 |. ~, b* ]
  17. #endif
复制代码
& y1 E2 z5 h* I2 T2 B) V. }
************************时钟配置************************************
' b* X8 F- {2 b" Z
8 u8 E5 y& E8 u$ m: c. Ausart 文件夹
# E# b7 g6 k( ?2 C$ l4 L! V; i0 |( F
usart.c 和 usart.h 两个文件。这两个文件用于串口的初始化和中断接收
$ v( W& W6 ^+ n8 ?) e: S# F1 [- V4 c5 w, N; ?
usart.c里面包含了2个函数一个是void USART1_IRQHandler(void);另外一个是void uart_init(u32. O, N3 A  J' k& G, ~
pclk2,u32 bound);里面还有一段对串口 printf 的支持代码,如果去掉,则会导致 printf 无法使
2 W$ K+ H9 y: U0 E  n$ x# e1 S4 x4 A, c$ n( `: ~2 I2 x8 {" _0 e4 x

3 R. B+ u9 }$ f$ f( r在配置 STM32F4 外设的时候,任何时候都要先使能该外设的时钟!
  Z$ O& k7 _9 b; s
2 H& ~6 F7 t- Z" _8 ~' K2 F
20190703182927542.png

+ ]- F4 n* g& ~$ \/ z( l$ d6 i# h8 {, i
RCC->AHB1ENR|=1<<5;//使能 PORTF 时钟  L. t' N* ?5 J" }2 ~
; T; M3 o, z& @5 z$ v
9 `' j- u1 N7 }% }- ?( J' m
I/O   输出I 输入
' g9 ?& V8 z' t6 D3 r9 L
/ p/ k, h2 ]1 A6 R+ r% x1、使能时钟% k1 ~  E! D' d' Y) a

/ ?: ?0 f$ d* q0 g2、IO设置   void GPIO_Set(GPIO_TypeDef* GPIOx,u32 BITx,u32 MODE,u32 OTYPE,u32 OSPEED,u32 PUPD)9 `& p: z% O% L3 L
* G& I: `5 }& X# R4 U8 G' M/ l- Q
//GPIO通用设置 1 S# X/ z* y! E. F
//GPIOx:GPIOA~GPIOI.
8 _2 v- d5 c6 a//BITx:0X0000~0XFFFF,位设置,每个位代表一个IO,第0位代表Px0,第1位代表Px1,依次类推.比如0X0101,代表同时设置Px0和Px8.4 E; o0 H" s! L) B$ \
//MODE:0~3;模式选择,0,输入(系统复位默认状态);1,普通输出;2,复用功能;3,模拟输入.  O- F. z* s7 c
//OTYPE:0/1;输出类型选择,0,推挽输出;1,开漏输出.
- a  w) [& \! o! O5 i7 n, t//OSPEED:0~3;输出速度设置,0,2Mhz;1,25Mhz;2,50Mhz;3,100Mh. # e' }, V; w! }
//PUPD:0~3:上下拉设置,0,不带上下拉;1,上拉;2,下拉;3,保留.
. t/ q1 l& u5 j) w$ x8 u//注意:在输入模式(普通输入/模拟输入)下,OTYPE和OSPEED参数无效!!
. e5 u; ^9 R# e. d6 F6 @' e/ P" \- W& x$ j, w2 s
3、PFout(n)   PFin(n)
+ J& R$ c9 G5 p9 T( O& {. ]5 Z" n3 S

; T9 C/ G# X: N+ \- J串口
1 p2 A, n1 C* V% I) f; r6 N! C: b3 D. g6 k' {- U- \
STM32F4 的串口使用起来还是蛮简单的,只要你开启了串口时钟,并设置相应 IO 口的模式,然后配置一下波特率,数据位长度,奇偶校验位等信息,就可以使用了,
" @3 M! u0 s. Y- g+ X1 I9 q4 M! M, w1 o* u* q, |8 ~
uart_init(84,115200);  //串口初始化为 1152000 S- b2 M4 E- g0 |$ d! [
  F: ?6 l8 k1 z5 a6 l( W- s$ B2 l

5 p+ R# n/ b" {/ d+ C3 o! n
收藏 评论0 发布时间:2021-12-6 11:32

举报

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