STM32Cube Ecosystem
$ ?1 Y1 K. h( X! L" I+ m7 }7 o/ G# m记得我在ST刚推出CubeMX的时候就尝试过,那时候自动生成的外设初始化代码都会有一些小错误,现在,随着这套系统的迭代升级,Cube生态也越来越完善,并且使用也越来越方便。
$ P0 `# h2 L: D- P7 o0 ~
% V) K" H5 [ A2 x6 [) @ST推出的STM32Cube Ecosystem提供了免费整套的开发软件工具和嵌入式软件包,其中可以从芯片的外设配置,程序开发,程序下载以及系统监视一系列的功能。如下图所示;6 R# v5 N# B) _# P
3 c; a6 n& `" ~
+ b& r! [$ K ZSTM32Cube Ecosystem 4 [ m9 @9 e" ?0 D
9 ^, X( J7 u3 b3 F* u) GSTM32 CubeMX 几乎STM32的设备都可以使用这个工具初始化配置代码,这个是基于Java开发的图形化界面配置软件,可以为Cortex-M自动生成需要配置的C代码,还可以为支持Linux系统的Cortex-A内核生成设备树。7 N2 A2 C9 A3 t; ~( O
STM32 CubeIDE 这是一款ST推出的免费的集成开发环境,基于Eclipse和GNU C/C++ 等开源工具链,可以编译调试代码,并且官方也将STM32 CubeMX集成到IDE中,这样整个软件的配置和开发变得浑然一体,便捷非常。5 E' R, T' h0 a3 T: z! K" O- j
STM32CubeProgrammer 软件编程工具,支持(JTAG,SWD,UART,USB DFU,I2C,SPI,CAN)等方式对设备和外部存储器进行读写。9 E% Y' T2 A [' A! a- O# a
STM32CubeMonitor 系列工具。强大的监视工具可帮助开发人员实时微调其应用程序的行为和性能,这个目前还没有尝试,暂且先相信官方的自夸吧。: A- I' @! q( {
所以使用以上的ST Cube全家桶进行STM32的软件开发,还是有不少坑要在实践过程中慢慢爬,整体的一个流程基本如下;
* O8 x7 ?& X# S, ~+ p' L+ u1 j! \& r
& z2 n" O# z/ I- n7 @( R/ S w
2 L' v+ f8 q5 \- O* s开发流程 0 W* N0 r, G9 G" M* }# E! [
. n4 |2 G7 X, ]% Y
6 K3 \) d8 z4 _% a
第一步:使用 CubeMX初始化相应的芯片外设功能等等;; s( m2 F. q# T. J# L
第二步:使用CubeIDE进行代码编辑调试等操作,当然,如果你喜欢也可以使用IAR,Keil,或者VSCode,这个完全出自个人喜好和习惯,但是据说CubeIDE里集成了CubeMX,这个难道不香吗? 加上如果想使用 gcc编译器,那也省去了很多配置的麻烦;
8 i: b5 F2 `5 h第三步:使用CubeProgrammer进行程序烧录,主要是支持的协议多啊,还可以吧,感觉是吹的挺厉害的;/ E( [7 _/ j" ] n0 J7 o2 V+ ~
第四步:以后可能会出更多的功能插件,目前感觉不是十分必要。
! m# Y( t: v1 g; j# H: @" n% B
1 d. r D' @8 `0 d2 `CubeMX, l" {: @9 j& R3 M$ i' x. b
STM32 CubeMX的安装,十分简单,不过下载需要提交邮箱,基本根据系统提示就可以完成,另外,STM32 CubeMX目前自动生成的代码支持官方的HAL库和LL库,像以前笔者常用的标准外设库就已经被ST抛弃了,最新的STM32F7已经不支持标准外设库了。同时,CubeMX初始化生成C代码项目,最终的工程可以符合IAR,Keil MDK和GCC,所以这里相对来说比较方便,不用对着手册撸寄存器了,也不用对着官方标准外设库demo进行移植,真的是哪里不会点哪里。
8 o" @% H, r: `7 M K' G& C; u6 U% u' q# ?4 E9 _
HAL库的封装相对来说好一点,但是代码读起来相对比较冗杂,通用性和移植性好,符合软件工程的设计思想,那么会牺牲一点效率了。
) X" b0 q0 z! `1 ? oLL库会再底层一点,这几个的选择还是看个人喜好和团队的需要了。5 Y0 w) x% \, A' H7 x; v( ^
q: K' p2 D! }+ b1 _) N
CubeIDE
/ H+ p* @4 j5 i, ?1 F在官网下载CubeIDE这个软件并安装,假设你已经成功安装并打开了软件,会看到;图片
4 E/ a: [7 s3 h: L' v3 _; N/ V+ Y& `' k G' w& n5 {! k
- r5 g0 x& l4 h8 X
6 }0 _9 c2 x+ `" z' RCubeIDE已经集成了CubeMX了,新建STM32工程,step by step即可快速开始了。3 r* F4 G' M8 P' J+ J
2 G: m* v2 P+ H* R& iCubeProg4 C# J$ l3 _3 l: y3 z
整体看了一下 STM32 CubeProg 的介绍,其实有点还是可以的,首先这个软件支持多平台如:Windows, Linux, macOS等等,Java 进行开发的有点,这一系列差不多都是用Java开发的,另外可能对st-link的支持比较好,如果使用jlink的话,用个openocd也无妨,但是毕竟是套装,下面简单罗列一下;
; m: _0 U4 [ T2 O2 l& y) Z/ d( b
支持擦除,读写Flash等等操作;
& {- ?2 Z/ L- _" P支持Motorola S19, HEX, ELF 和 二进制格式;
' o1 `: x1 ~; N! qST-LINK的固件升级;
2 E, j' ~1 Y, j1 v7 n6 E4 ?多平台:Windows, Linux, macOS,其实就看好这一点;) v" Q+ q6 T+ S0 a
. {% }, x& w, w$ ?% t6 e" f; a
CubeIDE进行开发, ?" m) R1 T+ N. j% Y2 W z0 n4 c
使用STM32CubeIDE快速创建STM32的HAL库工程。
0 A0 J; e0 |8 \+ M% [5 d) W* h) I/ ~1 N/ z- `# l
STM32CubeIDE Home
3 ?3 Y& Q; x- b4 Q7 t- K进入到官网的下载界面,选择符合对应的操作系统和对应的版本,下载安装,下载界面如下图所示;
4 J1 u* j4 r9 p/ Y; h: x
. b& K* `- f1 n4 t! b5 `5 j- {
1 `/ n c# {& r" ]# y/ v
* [1 s$ r# Z; H- u安装完成之后,打开STM32CubeIDE会直接进入主页,这里开始创建STM32工程或者导入工程,如下图所示;
1 P' j% m0 g4 l/ F
( Y2 y2 d* c: x6 [: W0 t
* O. U9 o1 P9 W% J. m% s6 ?
6 c0 x6 k' I' `# RRead STM32CubeIDE Documentation有大量的官方文档;可以快速入门,包括;" Y: `2 M+ m3 c, ?0 N( Q1 u' c
安装教程;
. j6 M, s; `$ W1 M; ~ M用户手册;
# C7 K4 F5 }7 W0 x& {
$ H4 o. R! `" y生成工程
, ?, T) Y" `$ F% o$ v6 T* T
) y' M5 C5 }6 @9 N9 K [
( r8 U1 Y( h; e0 D4 s8 C# C9 t
0 f* w, T' p4 }+ M
设置工程名称和路径之后就基本完成工程的创建了,具体如下图所示;: Q8 S' z" K" q' V
. R0 p9 X# u! g J8 Z0 x9 \; u: N0 x+ ?3 A" e, B2 U
" X+ g5 \7 t7 n `/ j
创建工程 2 _6 x2 A# w% t7 @; D$ V0 b! \% C! I
+ I5 W u. K8 c& F8 z/ r E
: _0 y; o/ I9 P4 g- A& l. k" P
+ B3 J. E7 [1 y0 J
在此期间可能会联机下载库文件和相应MCU的外设文件,这里要保持网络畅通,并耐心等待;- p8 w; ~8 t9 k9 @& j/ T6 q6 X) o
; O, Q& W' F5 x: K5 s
成功创建工程之后,如下图所示;
4 ?- p4 b. i, h
* O& h" o) ?+ V* o
, d/ M- G4 H$ X4 T, X& ]$ K D) S, M0 r% ]& E( @5 H
在这里插入图片描述 ! `, f |7 z2 _; d6 t" X+ j9 ^/ N
可以看到左边是HAL库,右边是CubeMAX的配置界面,至此已经完成了工程的生成了,那么下一步进行进行编译和下载。" T' |! {4 M# E) c% Q5 V
5 M' Q* P3 J# X: b另外在文件列表中可以看到TEST.ioc文件,这是CubeMAX的配置文件,相当于一些软件的ini文件,CubeMAX主要通过读写该文件将设备的配置保存和加载的软件中,直接用文本编辑器打开可以看到具体的信息如下所示;
/ @ s0 o" k: Z8 [# K- #MicroXplorer Configuration settings - do not modify V; A" j9 M. p6 d: m) z4 M
- FREERTOS.IPParameters=Tasks01
, [8 ]2 v2 i, G" z+ m' r - FREERTOS.Tasks01=defaultTask,0,128,StartDefaultTask,Default,NULL
# n! c* j* A& N% Y1 X+ C' A - File.Version=6
& \/ C. `; I1 U! m - KeepUserPlacement=false0 ]- K' R6 M4 e; P2 R/ j g
- Mcu.Family=STM32F1+ ^8 K5 W; I2 l* H; N
- Mcu.IP0=FREERTOS
O- v8 C e1 C; b, M! y& ? - Mcu.IP1=NVIC- @. P8 |8 P! V' Q5 h/ ?
- Mcu.IP2=RCC
- _2 U/ P) B- e$ H4 _9 D- I - Mcu.IP3=SYS% U& `# E( b! x# B
- Mcu.IPNb=47 L+ V( h4 {: J2 T' M1 J2 y6 U8 Q% s* G
- Mcu.Name=STM32F103Z(C-D-E)Tx
6 u$ r/ A3 l& k2 c! G+ z- Q3 B - Mcu.Package=LQFP144# s4 W) x- x# D
- Mcu.Pin0=VP_FREERTOS_VS_CMSIS_V1( x; F1 I: B7 X! e9 H
- Mcu.Pin1=VP_SYS_VS_ND
0 g& L$ G0 p; C - Mcu.Pin2=VP_SYS_VS_Systick$ N' \' G* ~ e' ~, o
- Mcu.PinsNb=3" Q/ S/ }" I% L# Q0 i, ^
- Mcu.ThirdPartyNb=09 Z3 j7 B, q' F- P
- Mcu.UserConstants=
- X2 D m0 s3 h) P. B K# J+ O; f$ [ - Mcu.UserName=STM32F103ZETx, F1 _% m2 p( x0 l1 e6 s
- MxCube.Version=5.3.0
/ P. T; n) Y" c' x" I - MxDb.Version=DB.5.0.30, l. Y& [7 s0 X, }9 B) D# q/ Q
- NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false9 m( p) |0 m5 b1 d) \$ y* a9 U8 S
- NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false6 t, o% v7 Y. ]% |
- NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
! m8 N# _; G& x1 X - NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
$ E7 j4 o7 R% i: t2 X4 D - NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false* P7 G6 ~- ~/ R7 i5 H
- NVIC.PendSV_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:false
) E6 k7 X5 a v2 ~2 j - NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
( q3 J4 _7 T( C \ - NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false
0 g0 ~& j5 Y2 j1 Y - NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:true\:false\:true
! ]+ E0 ?2 F4 r! W% f( k2 `% W, L - NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false. \. k: ?% e0 F
- PCC.Checker=false) J! [; |) h" }' C- m
- PCC.Line=STM32F103
) S" W {. s2 F8 ?2 w: D - PCC.MCU=STM32F103Z(C-D-E)Tx
% j2 [% Y c. [2 M - PCC.PartNumber=STM32F103ZETx- N; C8 ?% m$ d. |5 S& }2 g
- PCC.Seq0=0
, O% f% |# {* r" L+ Q3 r" p - PCC.Series=STM32F15 T7 _: K0 P$ I/ `4 d# o3 Q
- PCC.Temperature=257 m+ h: R b& C1 i
- PCC.Vdd=3.3* x, B- T8 H% [; {
- PinOutPanel.RotationAngle=0
* M9 U6 v, Y! [$ i+ S - ProjectManager.AskForMigrate=true
6 \! ~0 i5 f! x( V) v8 k - ProjectManager.BackupPrevious=false
* Y# Q1 _4 l2 }8 h" B# U* ] - ProjectManager.CompilerOptimize=63 r; {: O5 l% |
- ProjectManager.ComputerToolchain=false# f- Q% p a& s+ a* y4 u
- ProjectManager.CoupleFile=false" Y7 ^) a7 v% x
- ProjectManager.CustomerFirmwarePackage=, [8 M3 ?& n5 N8 @) K8 {0 [
- ProjectManager.DefaultFWLocation=true
1 R6 G8 ]7 e: E; e, V - ProjectManager.DeletePrevious=true8 t8 n1 j6 y. q
- ProjectManager.DeviceId=STM32F103ZETx2 g. Y( x- i- t8 \' X: L
- ProjectManager.FirmwarePackage=STM32Cube FW_F1 V1.8.0
0 k: ^( B4 U4 q0 {8 M - ProjectManager.FreePins=false* G5 S* ]. m1 |# {( u( Q' V( a
- ProjectManager.HalAssertFull=false7 x: x ^1 }6 j5 k
- ProjectManager.HeapSize=0x200
- j0 E/ u5 [* L2 B" M0 {# Z- P* E - ProjectManager.KeepUserCode=true/ k' {, ?& D* ]9 @' ?3 X9 M2 k: A
- ProjectManager.LastFirmware=true9 ?; h# P; I! N% Z! E/ U; ]
- ProjectManager.LibraryCopy=1( w4 P" ^. V# S2 c& O% ^# H5 j- v
- ProjectManager.MainLocation=Src0 \* S/ ~% p3 v7 |" t
- ProjectManager.NoMain=false
$ {% M: M+ m0 @! `1 f4 {- u' T8 I - ProjectManager.PreviousToolchain=
6 b+ S6 f& J1 r$ S; A! O - ProjectManager.ProjectBuild=false: m) `& E- g4 y0 r) \* u
- ProjectManager.ProjectFileName=TEST.ioc s9 J1 t; V# L3 h$ z! _1 ]9 ~! b
- ProjectManager.ProjectName=TEST
8 I8 `7 K4 S$ [# R7 x' l0 m8 } - ProjectManager.StackSize=0x400
) T1 O: T. U5 I - ProjectManager.TargetToolchain=STM32CubeIDE
+ B: Y7 j+ S# d8 q f - ProjectManager.ToolChainLocation=
; F( U ~9 _* j6 c# U9 r. _" v - ProjectManager.UnderRoot=true
2 N$ a7 o1 r0 n - ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false
5 N' I: t; s) {- ] - RCC.APB1Freq_Value=8000000
& B( W: {* _: h/ a& j8 w# z" o6 ^4 h - RCC.APB2Freq_Value=8000000" K* p2 t, F7 K& g! l
- RCC.FamilyName=M8 i# h" V. U+ M; q7 G+ G) H
- RCC.IPParameters=APB1Freq_Value,APB2Freq_Value,FamilyName,PLLCLKFreq_Value,PLLMCOFreq_Value,TimSysFreq_Value5 {3 h: d* y( U9 w+ Y# v* T4 h
- RCC.PLLCLKFreq_Value=8000000" b, K, O) U6 `0 N& G+ E# H
- RCC.PLLMCOFreq_Value=4000000
. @' z( ]3 H3 N- g* p - RCC.TimSysFreq_Value=8000000' W. q! y1 _6 M5 p9 Z! _
- VP_FREERTOS_VS_CMSIS_V1.Mode=CMSIS_V1( V' I# e6 f2 u" a
- VP_FREERTOS_VS_CMSIS_V1.Signal=FREERTOS_VS_CMSIS_V1
1 p- I; M) P) Z) e. j: P- N, v - VP_SYS_VS_ND.Mode=No_Debug- w8 }: u+ v8 K
- VP_SYS_VS_ND.Signal=SYS_VS_ND
' W- T/ P6 B# W - VP_SYS_VS_Systick.Mode=SysTick
& M' p) f" ]) ^7 F9 P: _% ^ - VP_SYS_VS_Systick.Signal=SYS_VS_Systick
1 E- u K P7 ]' h' b4 V' X# i - board=custom
; U# n& X( N( b: D" D# o+ W - isbadioc=false
复制代码 1 F( C4 ?$ r4 S% K/ |1 p
这个不用太关心,因为可以通过图形化界面去配置,软件会自动修改这个配置文件的。
: r1 ^0 S9 {6 C/ _& h+ ^/ Q b/ u% p/ g9 @7 |4 b
程序下载
4 L" b, v# [* m. e' d可以在工具栏直接点击锤子
0 {4 {, h) P) _: \7 Z2 {9 R, M- t# S8 c6 ~- r
" y) R( e+ q( i* k) e) I
- }0 z/ m4 Q4 y$ H8 ^# S1 dbuild
' T6 a3 f& v3 Q0 D3 c& }1 N快速进行构建,最终会自动生成elf的文件,也就是仿真器可以烧录的文件;然后可以在窗口直接查看Build的信息,包括报错等等,具体如下;
* }/ F; F% h4 I6 S" n- 12:52:59 **** Incremental Build of configuration Debug for project TEST ****
, ?/ D1 } A' L- e! j% F& S: Q+ z' Z - make -j4 all
' e& F G% H+ |0 d1 }% q& C' l1 f - arm-none-eabi-gcc "../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c" -mcpu=cortex-m3 -std=gnu11 -g3 -DSTM32F103xE -DUSE_HAL_DRIVER -DDEBUG -c -I../Inc -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Drivers/STM32F1xx_HAL_Driver/Inc -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.d" -MT"Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.o", H+ l% _* D0 O2 h$ ]
- ...- S5 E* c( J8 O3 }( i
- Finished building target: TEST.elf
2 B: ~. o$ `# O( H& S% Q/ K -
# D; C% n3 S% J. l - arm-none-eabi-objdump -h -S TEST.elf > "TEST.list"
! l; \2 g, C1 g h; [* c8 \- v - arm-none-eabi-size TEST.elf + }. P. x) g. t# [1 {
- text data bss dec hex filename* x) R( v7 p9 W2 x" W6 |
- 3860 20 8228 12108 2f4c TEST.elf
5 c$ o. W2 T! r x- G" Z3 o - Finished building:
复制代码
3 b: K+ |: Q8 i1 H% C
6 m5 V% ]* ]6 A, q$ C/ z8 R点击工具栏的虫子图标
4 L8 I8 U9 v6 D4 J5 e
6 _8 E; ?' ^( k; E$ T5 \) ~1 c3 B+ w& ~- c7 I
* A8 `) s- s, i3 I; V# h! R
debug
* p0 O' g3 q* D0 I, Y进行调试;
, O4 U: j) y) R# r6 E8 J
6 w/ D p( E! O! @% U% p& \9 O; `- ?: P) [
( \4 o, c$ b% G2 ~+ m# p% Y+ z% F
工具栏
K: z$ B1 d4 F- s在菜单栏Run选项中找到Debug Configuratons,如下图所示,配置调试用的仿真器和接口方式,最后点击Debug即可将TEST.elf下载到target中。
+ w6 ?$ t1 c1 S) {+ e/ u1 D7 C
; B7 Z& n+ M" I% V9 s/ {$ X: g8 ]7 c1 w8 ^! {; Q* X( j: b' Q8 F
, Q3 O) `0 f1 @调试器配置
. l' ~: Z4 h. }$ G成功开始调试之后,如下图所示;
6 p+ E2 g6 u9 V. U% n' j! o5 ]# X# o( j: W( z. y; {6 O; L3 Z4 Q
C8 C; ^' Q" K" [. Q0 Y
. ]3 b |7 R( j8 J1 @9 \, E
开始调试 * Y% T/ v+ M6 u0 u4 I" p( f
结语
' q! e: m: s4 h: G# X0 b" Z对于Cube进行了简单的学习和介绍,目前还有不少坑要爬,建议看一下HAL的封装,有必要LL也可以看看,基本上还是符合CMSIS那套标准。另外关于开发环境,如果需要使用CubeIDE进行开发,它已经集成了CubeMAX,则无需另外下载了,直接一站式服务搞定,如果只需要生成初始化代码,那么CubeMAX还是有必要单独装一下的。1 [- \% G2 ?0 _9 ?* r+ z
4 O# S/ ?/ T. ~4 f/ S
% W% ^' R7 y; f2 p( r转载自:硬件攻城狮
+ F2 J" c. [, x+ W |