
一、芯片简介5 d. P1 A% I$ B5 t; [# k* e - ?; i9 Z9 ^# i1 J, p# G, k ![]() + w6 t( o1 W, K 1.家族 STM32:32代表32位MCU,有32根地址线,可以寻找4GB的地址 STC15单片机是8位CPU,地址以16进制表示:0x_ _ ;% ~' g7 i$ e. e9 H STM32: 0x_ _ _ _ _ _ _ _ 容量为 2^32 = 4,294,967,296 ≈ 4×10^9 (其中 1GB = 10^9)6 I: p4 K& e. J h+ v: q& J6 }# l . R5 o* g8 R/ u" L; m0 g) N8 x 2.产品类别, M! R. B7 C! h0 f' N* ]& { G: 支持DSP和FPU指令的可适用信号应用 4 i% C; P- u& {: b l1 t6 _ 像正点原子的F4,F:基础型,通用型8 W) k$ h: q3 E* d 3.特点功能 103 : STM32基础型 407:高性能,带DSP和FPU3 l3 E9 b( J9 _) g 431: 未知& N. A7 f/ r% x, N 4.引脚数 R : 64位引脚3 e- K( G$ `' I5 y 5.闪存容量 B: 128K& ]$ H9 T* F9 |1 ?% Y7 C" L: O% \ 6.封装 T:QFP封装 $ v. q! Q1 J* A, W 二、Cortex-M内核) u p6 a: X" m% i, e 整个芯片的组成 * v$ V' M3 h0 S% b3 p ![]() ) y) s& p9 C' v( M& l3 a0 K 芯片由两大部分组成的:Cortex-M内核(ARM公司设计的部分) + 外设资源(芯片制造商设计的部分)( r- y0 d* X ~- D( I1 C ![]() ![]() $ o& v! d% t% M. C Cortex-M家族有一系列的处理器,STM32F103内部使用的是Cortex-M3内核,STM32G431内部使用的是Cortex-M4内核,M4比M3多了DSP信号处理和FPU浮点运算单元 M3内核架构简化视图% v8 ]+ Q/ J% l1 y. c% b3 m ) b) W" `8 h2 ]9 m/ H ![]() NVIC:向量中断控制器,负责中断控制以及中断处理事务 + Q/ u! ^0 ^* k 取指令单元:取指执行,通过总线将程序从程序存储器(128K闪存)取出,交给解码器 解码器:指令解码; g' _+ X( \+ I ALU: 算术逻辑单元, 是中央处理器(CPU)的执行单元,是所有中央处理器的核心组成部分,由"And Gate"(与门) 和"Or Gate"(或门)构成的算术逻辑单元,主要功能是进行二位元的算术运算! C, ]7 t& |: a) k 自带追踪接口和调试系统% O* X% G* C: M& V0 D+ V+ r' m8 R 存储逻辑运算的结果放在寄存器组中3 F; x. X) d+ }% F9 x - o2 g8 O$ ~7 Z5 z% m ![]() 3 z \" X! D; a3 l- |! S 想要深入学习寄存器组的作用,参考这一篇:M3/M4内核基础 . u" k {& U3 S) ]5 l 三、芯片内部结构 1.外设资源 STM32G4系列控制器参考手册:查看开发板外设的资源和资源的数量 * K! p% H* Z- w; G7 k* a3 s# K ![]() ) f# p7 u) P$ Y# J' s ![]() ![]() ![]() ; E% y. Q* |, H 2.内部模块框图 STM32G431RB数据手册:查看外设所对应的时钟总线 ![]() GPIO(A-G) : 挂载在AHB2时钟总线上 定时器1,8,15,16,17 : APB2 定时器2,3,4,I2C: APB1 AHB1分为 APB1和APB2时钟总线 ![]() 3.时钟树 STM32G4系列微控制器参考手册: 查看时钟树 2 I( J' }' P- t( ]4 K9 U ![]() 8 Z3 K9 X! B& o7 l 时钟树: . ?% \- A' ]3 P' @ ![]() STM32的时钟源主要有: 内部时钟、外部时钟、锁相环倍频输出时钟。内部时钟、外部时钟又分为告诉高速、低速时钟 3 Y3 {5 s2 d; F% Y. N. U, i 系统时钟有三种来源:高速外部时钟(4-48Mhz),高速内部时钟(16 Mhz), PLL锁相环倍频输出时钟 PLL锁相环时钟来源有两种HSE和HSI,经过倍频输出/ o6 X* Q7 G- h% d ![]() / q( {2 O- |" M1 n4 y1 |$ F OSC_IN 和OSC_OUT对应PF0,PF1时钟输入引脚* b. \9 W9 k& e% d# q; ^2 v 配置时钟: 9 k+ t% s [! `" ` 1.在CubeMX中配置RCC选择外部时钟HSE,对应引脚起作用 ![]() 7 R0 W' M* P2 u2 d s7 u, m 2.倍频设置* ]& B# |+ {( I0 P# d$ B / v4 R k8 U- j& M7 l ![]() 将外部时钟设置为24Mhz,经过三分频变为8Mhz, 经过锁相环乘20除以2,变为80Mhz, 将系统时钟来源选择PLLCLK , 系统时钟就是80Mhz, 再一分频得到AHB总线时钟,最终得到外设时钟。 % \# w. T( [4 ~/ M 对应代码 7 C4 J5 x) B5 e' y
在STM32G431内部结构中,各个模块都是通过总线相连接。Cortex-M4内核相当于心脏,最高频率可达170MHz,它通过总线AHB进行数据交换,AHB分为AHB1和AHB2,AHB1又分为APB1和APB2 ; {7 U* F. g* q# Q% {9 o0 n$ \ ![]() * p U6 y! q6 G6 I' I 4.存储空间) x/ r: s) h7 E0 F! n 查看内存映射地址:STM32G4系列微控制器参考手册+ Z/ Y8 q+ t5 T( b6 ^+ h7 `( r / v: X, M" ]3 O. N1 K% P ![]() 内存映射: ![]() & a/ ~0 D( a( T7 f! W 内存映射分左、右两侧, 左侧是各个资源地址的大致分化,右侧是对左侧的细化+ A' ^2 O0 |" z3 q1 \ (1)Flash(闪存)* s5 |2 s3 r3 z& C) z Flash:程序存储器,存储代码的地方 起始地址:0x0800 0000 从地址 0x0800 0000 到 0x0808 0000 ,( 8 0000 )16进制 = ( 524288 )10进制,Flash memory被分配到的空间有 524KB 大小,远大于它本身的 128KB # t1 Z3 [0 s* W4 O: b' }; B4 M (2)RAM; T. L P% ]/ S: G2 s: I4 Y RAM: 随机存储器,用于存储数据 ,起始地址:0x2000 0000$ C0 }0 P4 X% v) p: N RAM分为:SRAM和DRAM* N8 r( a! `5 x. I1 d0 r( f ) _7 W: K2 R9 Q4 F 1.SRAM:静态RAM(S指的static),静态指的不需要刷新电路,数据不会丢失,SRAM速度非常快,是目前读写最快的存储设备 2.DRAM:动态RAM(D指的dynamic),动态指的每隔一段时间就要刷新一次数据,才能保存数据,速度也比SRAM慢,不过它比任何的ROM都要快% @7 a. T% ^6 H (3)外设 外设:APB1、APB2、AHB1、AHB2 起始地址:0x4000 0000 b" K m. T8 A1 O 小结:5 J! f' d" A8 [0 D' V9 ^3 O; k# w( G 外设起始地址为 0x4000 0000 SRAM起始地址为 0x2000 0000* u/ _, |6 `+ ^4 V! @9 w" J Flash起始地址为 0x0800 0000 ]8 Z5 T) d. t 3 v& c8 |9 n/ Z; e! D0 d ` 详细的外设地址(在上一页的下一页)* z" A* F1 D1 d5 {$ [* v ![]() 可以依据蓝色字体查看外设对应寄存器分配地址 8 F! |4 U4 I/ u ![]() 四、BOOT启动5 g. x1 }2 A3 a8 [6 w STM32上电启动后,程序代码从最底层地址0x0000 0000 开始运行& T( i) D/ J5 q2 Z: B; s' {9 ^! y ![]() ! Q4 M7 p- k" a* L, g 前面知道代码存储在 Flash地址0x0800 0000 中,如何让 0x0000 0000 运行的是 0x0800 0000 中的代码? 存储器地址重映射: 将 0x0800 0000 中的代码映射到 0x0000 0000 中. {" w) A+ D: }% W : } _5 q- N5 g/ J" O- D 映射还可以将SRAM, System memory 等地址映射到0X0000 0000处 ![]() 映射方式的选择由BOOT1,BOOT0决定 P' h, D+ R. e. W5 |0 u' ~ ![]() 9 @9 n7 k. T, x7 }* H" h8 d STM32G431由于BOOT0接地,所以采用的是从flash启动 3 {7 y1 A! [; q; ^ ![]() 所以,单片机程序执行顺序' m2 Z7 p) E( X) c* e" U) q 7 o5 u; W0 f6 k I9 w ![]() 6 Z' e C8 `: D: }) y ![]() 中断向量表: 嵌套向量中断控制器(Nested Vectored Interrupt Controller),STM32向量中断统一由NVIC管理, NVIC的核心功能:中断优先级分组、中断优先级的配置、读中断请求标志、清除中断请求标志、使能中断、清除中断等,外部中断信号从核外发出,信号最终要传递到NVIC(嵌套向量中断控制器)。NVIC跟内核紧密耦合,它控制着整个芯片中断的相关功能1 \2 I; E7 F6 m7 r # ]" H- E! Y/ @3 ]% m ![]() " `* [% ?. F- O9 d DCD表示开辟一个字空间,后边的为函数名称,函数入口地址 1.存储堆栈指针位置:先获取堆栈指针位置,告诉CPU,中间变量存储再SRAM中, 从下图可以看到首先获取堆栈指针,然后就跳转到复位中断函数8 i$ k, h. E4 O5 M z( n1 G ![]() 注:按照目录的排列顺序进行检索,并执行目录中地址所指向的函数8 d5 {/ |/ \# f$ r ; R3 ^( B' m1 G& T' v7 H) U7 s8 ~ 2.复位中断函数入口地址:CPU执行到这里,下一步跳转到复位中断函数! t% @. \( o6 r' q3 s1 { 中断复位服务函数: M7 M9 L! E4 `* y, U% b. h 3.复位中断函数:CPU执行到这,先配置时钟,再跳转到主函数$ g" }" M3 F9 v9 { 4 U7 L+ B3 s5 b" k ![]() ' `. |1 w; T! _; ?1 l6 @9 @ 在调用main函数之前先完成了时钟的初始化,再调用main的 " ~2 f0 w7 X8 ?' C 4.主函数区域:执行主函数,进入while大循环9 {) m0 [0 c; I( ^7 _! R& ] 5.其他中断函数入口地址:发生中断后,中断位置自动激发,告诉CPU中断入口地址,CPU去执行中断 # y( t6 l, k. r( q' m& R2 @ 所以,在启动文件执行的时候,内核和每个外设的中断服务函数的地址都是已经确定好的,地址就存放在中断向量表中,而且在启动文件里面已经写好了中断服务函数,只是这些中断服务函数为空,而且带[weak]弱定义 ![]() 那么需要在C文件里面重新实现这个中断服务函数,用户写这个中断服务函数的时候,函数名必须跟启动文件里面写的中断函数名对应,因为函数名对应的就是中断服务函数的地址,如果中断服务函数名和启动文件的名字不一样,就默认启动文件里面预先写好的空的中断服务函数,而且是一个死循环,程序就会一直卡死在中断服务函数里面 ) D6 u, ~- J' w/ j W1 _& Q 五、库介绍 1.HAL库:ST官方推崇的新编程库;HAL是Hardware Abstraction Layer的缩写,中文名:硬件抽象层。HAL库是ST为STM32最新推出的抽象层嵌入式软件,可以更好的确保跨STM32产品的最大可移植性。HAL使用了比较大的Flash和SRAM。 2.LL库(Low Layer):ST最近新增的库,与HAL捆绑发布,文档也是和HAL文档在一起的LL库更接近硬件层,对需要复杂上层协议栈的外设不适用,直接操作寄存器。其支持所有外设。使用方法:独立使用,该库完全独立实现,可以完全抛开HAL库,只用LL库编程完成。在使STM32CubeMX生成项目时,直接选LL库即可。如果使用了复杂的外设,例如USB,则会调用HAL库混合使用,和HAL库结合使用。编译后LL库只有HAL库的33%体积。3 o% m! Z+ z% Z% {6 _ E 6 g5 {2 W0 X3 `- S# }7 Y 3.标准固件库:旧版本编程库;HAL库是ST未来主推的库,从前年开始ST新出的芯片已经没有STD库了 , c; K" S9 J- Y, {0 O 4.寄存器编程:原始底层编程。HAL库和标准库就是ST官方对寄存器编程进行人性化封装后的产物 六、编译过程1 {& b3 I4 J8 M9 P' q; A: k7 F ![]() ![]() , r+ W' t4 H/ h' | 1.将 .c 文件编译和 .s 文件汇编,生成 .o 目标文件 2.将 .o 对象文件和内存映射规范文件 通过连接器 生成可执行映像文件。MDK是生成 .axf 可执行文件: R' v; H8 G6 I9 I- r0 e 3 O! C% s: y. c* Q 3.通过闪存编程器将可执行映像文件下载到芯片的Flash中 9 l/ b8 J# y% r |