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

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

[复制链接]
STMCU小助手 发布时间:2021-12-6 11:32
应用FPU $ q1 j% z3 m2 ]) W9 ?) ^
, o5 ~: n9 y/ f" L8 e
20190703105214160.png
5 D/ f4 i5 t# R4 @

5 ~2 E+ D1 Z0 [0 R9 k
, D3 q% A0 J8 D3 X& E9 S$ n7 w2 v% h
1、工程文件7 r/ m  V: u% I! J+ P
0 Z. g' K+ W, M7 d) d) \) r0 |3 p
startup_stm32f40_41xxx.s . S1 [/ N% {% c1 Z, B

; r/ H$ J/ c% T& ~7 z' m新建一个 test.c 文件,并保存在 USER 文件夹下
( o/ X, f& s( m7 @4 ~
, r4 a/ E( L( r6 K2、工程文件夹3 @: t0 x$ \) P# K: g  I

) k1 M" {, ]$ P+ N: l6 t! l& qUSER 文件夹专门用来存放启动文件(startup_stm32f40_41xxx.s)、工程文件(test.uvprojx)等不可缺少的文件,6 Y9 Y4 J( z0 C. Z: q/ S" T. I, K
8 m( {1 k1 B3 \
OBJ 则用来存放这些编译过程中产生的中间文件(包括.hex 文件也将存放在这个文件夹里面)- B/ B) u7 f0 U
$ B, E! k* }5 d4 C5 o
SYSTEM文件夹,该文件夹由 ALIENTEK 提供,可以在光盘任何一个实例的工程目录下找到
0 C. j, t8 ]9 q- @! D0 C% L( }) g$ y+ u; F9 \
3、工程分组, `7 |/ M( j; |( F$ e( |7 s
1 c, R9 T; b: `; n3 e) h" p' r8 t* Q
Target 目录树上点击右键  Manage Project Items
! w6 D9 ]( n8 F9 j( B8 W8 H0 ~& [' y$ E, ]* g$ L! F# S& V' G
我没改文件夹,还是用原来Objects,Listings
4 H+ j" u- I* H& k; `  ]2 u5 j; s
2019070311235161.png

8 Y  J3 ?+ i- d+ {" \/ |7 h3 f% v4 k; E

0 d! h  G. b; Q& H9 A" o
2019070311225613.png
5 {; M) a9 h0 ?- N
/ G' R- e+ Y! T' E# I
8 o0 T8 A2 y% O! x' I; ?
4、设置
5 C3 d7 u/ y( P
/ t/ l7 `; v8 ?- `2 ~* U
20190703111442709.png
2 M! c! B( M4 L5 }" r

0 T5 i" W6 ^/ L7 W% w$ |图中 1 处设置的 STM32F40_41xxx 宏,是为了兼容低版本的 MDK(比, P8 Y9 B/ ]* M8 m; _: O) U! D
如 MDK4/MDK3 等)才添加的,MDK5 在你选择器件的时候,就会内部定义这个宏,因此在
' M) r3 ?+ a6 e3 NMDK5 下面,这里不设置也是可以的。但是为了兼容低版本的 MDK,我们还是将这个宏添加
& G  `8 s  D# w( N# r; |% K0 \/ _进来。6 W' S/ ?8 j5 n9 x
图中 2 处是编译器优化选项,有-O0~-O3 四种选择(default 则是-O2),值越大,优化效果
5 A* Q0 G4 Y2 R$ i9 `8 I; W越强,但是仿真调试效果越差。这里我们选择-O0 优化,以得到最好的调试效果,方便开发代
! S+ G1 |' @8 v  L3 D0 z& Y码,在代码调试结束后,大家可以选择-O2 之类的优化,得到更好的性能和更少的代码占用量。0 R- {) p2 N, _9 V+ [8 |
图中 3 处,One ELF Section per Function 主要是用来对冗余函数的优化。通过这个选项,
* W0 d4 B) T* |1 n% v( b- c可以在最后生成的二进制文件中将冗余函数排除掉,以便最大程度地优化最后生成的二进制代' ^" o4 A1 r+ H9 Q& ]
码,所以,我们一般勾选上这个,这样可以减少整个程序的代码量。: h4 U9 O' U7 Z; ^' n* o
然后在 Include Paths 处(4 处),点击 5 处的按钮。在弹出的对话框中加入 SYSTEM 文件
. i# D" R5 |4 M% s0 _3 M夹下的 3 个文件夹名字,把这几个路径都加进去(此操作即加入编译器的头文件包含路径,后. O5 r% L! Z! |; @" z, Z+ D
面会经常用到)。如图 3.2.22 所示:; v/ n- T3 ^; T9 `

8 S' L; Z9 E4 G# k9 M- N: t- z' n5 a* @8 ~2 S

# [3 |, D9 Z" j, C$ X/ S) U编译遇到错误:4 J+ y& ^" }, t) i

( k2 J# w+ G; f; s- m! m0 qSYSTEM\usart\usart.c(38): error:  #260-D: explicit type is missing ("int" assumed)
+ P- L" a1 v# V: X2 j( G3 L4 R9 A; f! l: Y$ x. q! F9 i" b
解决:
) A$ _/ P( Q" _- o; b9 O2 n6 K5 J0 H- G) P- |) q
函数前加void,这是printf函数的相关定义
5 R2 B+ t' r$ t0 I1 t
# c: {6 s3 ?* u; _) Lvoid _sys_exit(int x)
) c  G2 i; f/ z) X; p! \
1 V6 D) X( a) l' [$ W  y" swarning:#1-D last line of file ends without a
5 ~: A5 N) o7 Z2 W" O$ dnewline。这个警告是在告诉我们,在某个 C 文件的最后,没有输入新行,我们只需要双击这个) ^3 F5 f0 v  K
警告,跳转到警告处,然后在后面输入多一个空行就好了。& K" R+ p1 t6 {0 l# a* o+ K, E2 P" c
" U& D- @+ m, \3 J6 @* n/ v
SYSTEM文件夹
; X7 P' R# ^# \4 V' _: {! N1 K7 e# M9 x8 Q7 D
1、delay
# n( H: g- ]5 g8 x8 @+ l2 r, @
0 B+ l4 H  [: u! ^6 w2 T, W& Q* z顾名思义:延时函数文件夹, B0 z1 M; z8 N: {5 g

" s; T& q% f- ~, H% r4 N: a
20190703112603207.png

" o2 A) f  t7 ~8 n$ \8 x( `+ j3 q3 I- g
***************SysTick定时器*****************着重理解' B- u( X2 i6 ]$ @- c) F4 x$ a
/ W9 i* O3 C$ t- J1 w, r/ O
RTOS会用到" Q  D; t7 r9 F- j

* ~( S, Z+ T3 s( [! y# G+ G
20190703112856883.png

9 M3 q. ]. Y! [2 U( M7 x  G; V. d$ d3 i

: U  K9 X; ^0 m  O
! m  _" B( o/ S8 k% G! Y% F7 r+ osys文件夹3 G2 E  j4 J3 W5 D, o( y

* Y5 b4 v% \$ [( x  m5 Y* W
20190703113106512.png

) w2 r: \7 E5 t# U9 A& u* l+ ]! P. N! h# }3 S8 _
sys.c 和 sys.h 是由 ALIENTEK 提供,而其他 6 个文件,则都是拷贝自 STM32F4 的 CMSIS 库文件1 p! C1 _- l& x/ x
# A4 W( r& w2 W$ L- t
sys.h
4 J1 T. w# {8 H2 O7 }; O* F" m, x% o- j! W
实现对 STM32F4 各个 IO 口的位操作,包括读入和输出
: ^/ z& T2 `! A7 F- I, [/ A
$ Y" E5 u- q( B  f9 }1 V PORTA的第七个 IO 口输出 1,则可以使用 PAout(6)=1;即可实现。我要判断 PORTA 的第 15 个位是否
, z# u' M: ]4 _; H2 J9 Z  }2 E+ N等于 1,则可以使用 if(PAin(14)==1)) P4 P( a0 ^7 J, h1 ^6 o
/ D& \1 u$ y+ H9 y0 K! C
  1. //
    ! L: P7 b+ N" M, f* v
  2. u8 Sys_Clock_Set(u32 plln,u32 pllm,u32 pllp,u32 pllq);                //系统时钟设置
    % q: W1 q8 h. `' Z, v& }/ i8 Y5 k  B8 C
  3. void Stm32_Clock_Init(u32 plln,u32 pllm,u32 pllp,u32 pllq); //时钟初始化  
    / u& ^% I: M- d+ g  u2 x
  4. void Sys_Soft_Reset(void);                                                              //系统软复位7 k! y1 _5 Y7 S9 M& d$ K0 _/ B, F
  5. void Sys_Standby(void);                                                                 //待机模式         * O$ M7 O8 E) e! H" Q  `
  6. void MY_NVIC_SetVectorTable(u32 NVIC_VectTab, u32 Offset);        //设置偏移地址1 ~7 o5 t0 U3 n+ D$ `
  7. void MY_NVIC_PriorityGroupConfig(u8 NVIC_Group);                        //设置NVIC分组3 E- A" l! T) Y- \/ w
  8. void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group);//设置中断2 K  P8 s2 x+ t4 b! g
  9. void Ex_NVIC_Config(u8 GPIOx,u8 BITx,u8 TRIM);                                //外部中断配置函数(只对GPIOA~I)
      y2 a1 W6 ~: h; d) \8 j7 v
  10. void GPIO_AF_Set(GPIO_TypeDef* GPIOx,u8 BITx,u8 AFx);                //GPIO复用功能设置
    1 ^! [( v) d, H( U( W9 O
  11. void GPIO_Set(GPIO_TypeDef* GPIOx,u32 BITx,u32 MODE,u32 OTYPE,u32 OSPEED,u32 PUPD);//GPIO设置函数  
    - s% K/ Z. ~$ u
  12. //以下为汇编函数
    6 ?( Z1 e) E; z  Q7 Y
  13. void WFI_SET(void);                //执行WFI指令
    - l, Z7 \6 h0 v6 m4 z$ {
  14. void INTX_DISABLE(void);//关闭所有中断8 t& r, O. R( l+ r! w: J$ U
  15. void INTX_ENABLE(void);        //开启所有中断
    % j) e- P7 w* k9 U  j
  16. void MSR_MSP(u32 addr);        //设置堆栈地址 : @5 K" |! M$ s: E! C, D
  17. #endif
复制代码
: v% j$ b" z. z( v2 a9 }
************************时钟配置************************************: D3 Z) @) I4 ]" h

% G4 ^( {) e2 ?usart 文件夹+ E; \% E# |4 X
3 C8 f0 A+ d6 e  Y7 ^. d
usart.c 和 usart.h 两个文件。这两个文件用于串口的初始化和中断接收
$ P8 H, G# M1 |9 _  m1 v' M- Y2 J/ ?# R. D1 G+ u
usart.c里面包含了2个函数一个是void USART1_IRQHandler(void);另外一个是void uart_init(u32* z. r& ~0 O/ A4 r
pclk2,u32 bound);里面还有一段对串口 printf 的支持代码,如果去掉,则会导致 printf 无法使" e/ r% a" D, |8 \" p
用
& M5 i4 B- A  T% k
. D2 E& M7 h- H6 \* W& V4 _9 e在配置 STM32F4 外设的时候,任何时候都要先使能该外设的时钟!% B8 E6 ~% K& p6 H- W: s$ @
. A6 j* D% J$ G0 h
20190703182927542.png
3 ]9 o; y% U! ^# X
1 \- y4 s! V' P6 V# @( _
RCC->AHB1ENR|=1<<5;//使能 PORTF 时钟
) Z2 P6 T- Y1 h( t
) J: m* a, L; P: O  e$ J7 s$ }  ^6 ]; @' b/ d  F. }" ?
I/O   输出I 输入2 o* `5 `  p5 T! g" d. g2 j
- G  N  T0 B* e. B4 [
1、使能时钟
; m5 z# O2 ~1 s; G1 S% `' `! u8 l( J# M/ l  D- M
2、IO设置   void GPIO_Set(GPIO_TypeDef* GPIOx,u32 BITx,u32 MODE,u32 OTYPE,u32 OSPEED,u32 PUPD)8 z7 H' {9 ?3 \

: p2 l. A& y1 }5 m//GPIO通用设置 . n7 P- k% K$ @) A2 n) r! A) X
//GPIOx:GPIOA~GPIOI.
8 W. M+ w5 p$ j% Q3 \8 ^# Y//BITx:0X0000~0XFFFF,位设置,每个位代表一个IO,第0位代表Px0,第1位代表Px1,依次类推.比如0X0101,代表同时设置Px0和Px8.
$ V6 M; `) G; b( p4 ?% j- k//MODE:0~3;模式选择,0,输入(系统复位默认状态);1,普通输出;2,复用功能;3,模拟输入.. L# `6 H" r+ T2 V( i" {+ T! F  z
//OTYPE:0/1;输出类型选择,0,推挽输出;1,开漏输出.- W) L7 T" F. r" W2 m- S
//OSPEED:0~3;输出速度设置,0,2Mhz;1,25Mhz;2,50Mhz;3,100Mh. . G8 n3 B- J! R, x% `
//PUPD:0~3:上下拉设置,0,不带上下拉;1,上拉;2,下拉;3,保留.
- t2 F: ~/ P1 {4 ~//注意:在输入模式(普通输入/模拟输入)下,OTYPE和OSPEED参数无效!!/ w- f# F8 w& w  i+ [/ R

/ I; _' H/ T9 k1 |; V3、PFout(n)   PFin(n)( }. S' n) I' `% A7 r. T

0 I$ p" c* |  |  b: ~
' l, A" I2 ?3 I) m4 w' S; O' i串口. Z2 E/ T0 l) l5 d% f0 ]6 G) x+ X
0 M0 U9 K0 [* ~. P
STM32F4 的串口使用起来还是蛮简单的,只要你开启了串口时钟,并设置相应 IO 口的模式,然后配置一下波特率,数据位长度,奇偶校验位等信息,就可以使用了,
# M1 I  m' D: a- r4 }& |5 M* v4 G" l% J5 f7 U1 ?% O7 e
uart_init(84,115200);  //串口初始化为 115200  j5 N( l( J/ ~: r9 t; E( \

9 U3 W9 B! n2 H& @; e' f+ U& S; ^4 O6 w& E
赞 收藏 评论0 发布时间:2021-12-6 11:32

举报

0个回答

所属标签

相似技术帖

官网相关资源

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