
一、芯片简介![]() $ m. c+ F- v, z 1.家族 STM32:32代表32位MCU,有32根地址线,可以寻找4GB的地址 STC15单片机是8位CPU,地址以16进制表示:0x_ _ ;- H/ d8 e% s% u STM32: 0x_ _ _ _ _ _ _ _ 容量为 2^32 = 4,294,967,296 ≈ 4×10^9 (其中 1GB = 10^9) 7 q$ D3 a! ~6 g1 l B ^ 2.产品类别3 ?2 G8 P, H7 C0 s G: 支持DSP和FPU指令的可适用信号应用& Z& ?3 {' V9 p l) O) B$ ?* q8 b 像正点原子的F4,F:基础型,通用型 & z. ]1 p0 f/ {) K) ]+ |/ Q 3.特点功能 103 : STM32基础型4 G: r- y) o" J( F( ~9 [$ P 407:高性能,带DSP和FPU 431: 未知4 U1 i( M2 e+ }8 s# X( s' G 4.引脚数' H1 e$ x, }/ w4 W3 X- x R : 64位引脚 5.闪存容量! U4 p' g/ @7 s, i" z B: 128K! V; V8 A0 W% F! e Z/ [ * U; ~9 g7 ]2 o' v3 q8 l3 w 6.封装4 X* G0 Q% S- Z8 _9 \ T:QFP封装 二、Cortex-M内核' \- k8 b8 X8 {) N( ^ 整个芯片的组成 " ^* ]# Q1 }+ v8 J% c5 V$ r7 \ ![]() # u5 t' b5 O) D! v: N& H% `" w 芯片由两大部分组成的:Cortex-M内核(ARM公司设计的部分) + 外设资源(芯片制造商设计的部分)3 M4 F8 {. |* i, f9 _4 L ![]() ![]() Cortex-M家族有一系列的处理器,STM32F103内部使用的是Cortex-M3内核,STM32G431内部使用的是Cortex-M4内核,M4比M3多了DSP信号处理和FPU浮点运算单元 ; k) g' a4 p* I6 i& j M3内核架构简化视图 ![]() NVIC:向量中断控制器,负责中断控制以及中断处理事务 取指令单元:取指执行,通过总线将程序从程序存储器(128K闪存)取出,交给解码器8 D: ?5 u- w" ^" t0 j* F 解码器:指令解码) X$ Y- t: A6 L! O' c ) H; K4 Q' G/ u1 \ ALU: 算术逻辑单元, 是中央处理器(CPU)的执行单元,是所有中央处理器的核心组成部分,由"And Gate"(与门) 和"Or Gate"(或门)构成的算术逻辑单元,主要功能是进行二位元的算术运算 ; B, ~ F* u6 ]5 J0 l0 v 自带追踪接口和调试系统! y0 U' O9 e, }2 u: f 存储逻辑运算的结果放在寄存器组中) ?3 c& u) `0 i- Q/ Z( ] + Q. g8 l+ i4 R; O2 r, O ![]() 想要深入学习寄存器组的作用,参考这一篇:M3/M4内核基础2 v/ m9 S" k/ u1 Z 4 ?) v; K' R! B4 X" u3 x5 r7 Y 三、芯片内部结构2 O; z B" Z' W 1.外设资源 STM32G4系列控制器参考手册:查看开发板外设的资源和资源的数量5 {5 y# p/ d' N9 m& ~1 I! [" T9 s4 h ![]() ' O1 u4 c! Q1 c+ ]# f7 M C3 i ![]() $ C6 {0 l4 N2 P' H5 Y5 T, \ ![]() ) G! L5 T* C$ C+ R$ d, u- N ![]() ! M2 q& Q. m4 o5 @4 U; W* b 2.内部模块框图 STM32G431RB数据手册:查看外设所对应的时钟总线 - O% E$ B/ r3 e9 y ![]() GPIO(A-G) : 挂载在AHB2时钟总线上 定时器1,8,15,16,17 : APB2( t- n2 N& d! X 定时器2,3,4,I2C: APB1 AHB1分为 APB1和APB2时钟总线( g4 {, {8 z; Q3 b& A) G( H ![]() 3.时钟树 STM32G4系列微控制器参考手册: 查看时钟树, |' Q. |4 X+ a% M8 z ![]() , n$ D) r% H4 o7 Y. n( q+ r6 n+ W: ^ 时钟树:6 v% P& N% P' H, c+ q ![]() STM32的时钟源主要有: 内部时钟、外部时钟、锁相环倍频输出时钟。内部时钟、外部时钟又分为告诉高速、低速时钟! [/ _5 t: O; F0 x 系统时钟有三种来源:高速外部时钟(4-48Mhz),高速内部时钟(16 Mhz), PLL锁相环倍频输出时钟 V4 F7 U# r. p4 n PLL锁相环时钟来源有两种HSE和HSI,经过倍频输出" o+ @6 m- P7 v) @9 P & f/ T- ^# L3 L- c4 c# J" F6 w ![]() OSC_IN 和OSC_OUT对应PF0,PF1时钟输入引脚 2 c# ]; L1 e1 y h 配置时钟: & x2 p% q$ `# t" E 1.在CubeMX中配置RCC选择外部时钟HSE,对应引脚起作用 ![]() ; n! N, X; P2 Q8 s 2.倍频设置 & e8 o7 U* i- x/ n$ r ![]() ) D" N6 D+ n0 c( o; R) r+ o 将外部时钟设置为24Mhz,经过三分频变为8Mhz, 经过锁相环乘20除以2,变为80Mhz, 将系统时钟来源选择PLLCLK , 系统时钟就是80Mhz, 再一分频得到AHB总线时钟,最终得到外设时钟。 5 s; H& ^1 V k2 y 对应代码 & s9 X: M- F4 H9 Z( @* m' v
在STM32G431内部结构中,各个模块都是通过总线相连接。Cortex-M4内核相当于心脏,最高频率可达170MHz,它通过总线AHB进行数据交换,AHB分为AHB1和AHB2,AHB1又分为APB1和APB2 5 q8 u7 }1 t7 i& x7 Y ![]() 0 n7 h. V3 H+ z4 S1 n 4.存储空间2 n6 h. p+ w+ B7 E0 @ 查看内存映射地址:STM32G4系列微控制器参考手册5 \- H& t% h8 y* A& v8 M ![]() 内存映射: ![]() 1 Y# q* K, y9 { `; ^. H/ J 内存映射分左、右两侧, 左侧是各个资源地址的大致分化,右侧是对左侧的细化1 u; y2 D# Y- n- h$ u9 Q$ ~ (1)Flash(闪存)( c. r, E P1 g- D; B2 G+ C. [$ D) w Flash:程序存储器,存储代码的地方 起始地址:0x0800 0000 " [- R5 s$ \; a9 @' S0 J 从地址 0x0800 0000 到 0x0808 0000 ,( 8 0000 )16进制 = ( 524288 )10进制,Flash memory被分配到的空间有 524KB 大小,远大于它本身的 128KB $ u, T4 O) L0 O! J (2)RAM3 I# o1 h e% A: G( y4 @: O RAM: 随机存储器,用于存储数据 ,起始地址:0x2000 0000 RAM分为:SRAM和DRAM 1.SRAM:静态RAM(S指的static),静态指的不需要刷新电路,数据不会丢失,SRAM速度非常快,是目前读写最快的存储设备 2.DRAM:动态RAM(D指的dynamic),动态指的每隔一段时间就要刷新一次数据,才能保存数据,速度也比SRAM慢,不过它比任何的ROM都要快6 |' n/ y! g4 ^1 V o ' D% x: c7 ~+ y: H. B (3)外设. z* m3 Y( o5 S! p3 ^ 外设:APB1、APB2、AHB1、AHB2 起始地址:0x4000 00008 G3 m! s( [/ @2 ^) J& C : x M" O T2 Y9 X& ^* a4 o! p 小结: 8 |3 r3 b+ m3 C$ e' D9 m7 ~8 Z7 D 外设起始地址为 0x4000 0000 SRAM起始地址为 0x2000 0000 Flash起始地址为 0x0800 0000; k! I9 P; j+ x; N3 o9 {& l * T+ k! `/ q x/ Y 详细的外设地址(在上一页的下一页) `' r) t1 D4 U ![]() 可以依据蓝色字体查看外设对应寄存器分配地址 5 w% |0 P0 i) j ![]() 四、BOOT启动# x- a# A5 A ~2 v- t STM32上电启动后,程序代码从最底层地址0x0000 0000 开始运行, v, `, Z3 d Q0 D5 N9 T ![]() 前面知道代码存储在 Flash地址0x0800 0000 中,如何让 0x0000 0000 运行的是 0x0800 0000 中的代码? 存储器地址重映射: 将 0x0800 0000 中的代码映射到 0x0000 0000 中 5 e( r% ]* Z5 W' r2 A) P9 Y 映射还可以将SRAM, System memory 等地址映射到0X0000 0000处1 ^3 L/ |3 c6 a; S ![]() 映射方式的选择由BOOT1,BOOT0决定# m' f9 k& I' [" m* _" c; D ![]() STM32G431由于BOOT0接地,所以采用的是从flash启动- I3 t% [+ `; ^$ A Y( d 5 c- _) y0 L5 ?( B; { R8 J" G/ F8 t ![]() ' {. |9 n2 q# i; w* G# e 所以,单片机程序执行顺序 ! K! n( N, M/ U; p3 {# @8 k; _ ![]() ![]() . _* ?# R; F) C4 Y9 R% K 中断向量表: 嵌套向量中断控制器(Nested Vectored Interrupt Controller),STM32向量中断统一由NVIC管理, NVIC的核心功能:中断优先级分组、中断优先级的配置、读中断请求标志、清除中断请求标志、使能中断、清除中断等,外部中断信号从核外发出,信号最终要传递到NVIC(嵌套向量中断控制器)。NVIC跟内核紧密耦合,它控制着整个芯片中断的相关功能( q% n+ @2 |8 l' _ 8 x& k5 D" U, O( Z& C% l ![]() / S/ U. ]4 A+ p1 H- l DCD表示开辟一个字空间,后边的为函数名称,函数入口地址 1.存储堆栈指针位置:先获取堆栈指针位置,告诉CPU,中间变量存储再SRAM中, 从下图可以看到首先获取堆栈指针,然后就跳转到复位中断函数* C" \- _$ k7 C4 K0 t $ z) {; e! f/ {6 t5 X1 l; }( Z# w ![]() 注:按照目录的排列顺序进行检索,并执行目录中地址所指向的函数) r$ |7 ~7 Y& G: w! q) O3 J% a 9 @' A; G# J: d! C 2.复位中断函数入口地址:CPU执行到这里,下一步跳转到复位中断函数$ y ~% W$ [5 u( g 中断复位服务函数6 P' m7 x* K3 x8 K4 }' z" y+ ] & V7 M. A) a5 V W 3.复位中断函数:CPU执行到这,先配置时钟,再跳转到主函数 ![]() 在调用main函数之前先完成了时钟的初始化,再调用main的8 m( G) Q6 I; r( Q 4.主函数区域:执行主函数,进入while大循环 5.其他中断函数入口地址:发生中断后,中断位置自动激发,告诉CPU中断入口地址,CPU去执行中断 所以,在启动文件执行的时候,内核和每个外设的中断服务函数的地址都是已经确定好的,地址就存放在中断向量表中,而且在启动文件里面已经写好了中断服务函数,只是这些中断服务函数为空,而且带[weak]弱定义$ X: m) P! r, H. }, x $ G5 U U- R! O& }3 M' k ![]() - I5 u! e1 L# ~9 f) f7 v 那么需要在C文件里面重新实现这个中断服务函数,用户写这个中断服务函数的时候,函数名必须跟启动文件里面写的中断函数名对应,因为函数名对应的就是中断服务函数的地址,如果中断服务函数名和启动文件的名字不一样,就默认启动文件里面预先写好的空的中断服务函数,而且是一个死循环,程序就会一直卡死在中断服务函数里面2 Y* c. b0 o' ]$ @, } 7 {6 x, s3 k" ] 五、库介绍2 ?- p2 a0 ~: P- ^ 1.HAL库:ST官方推崇的新编程库;HAL是Hardware Abstraction Layer的缩写,中文名:硬件抽象层。HAL库是ST为STM32最新推出的抽象层嵌入式软件,可以更好的确保跨STM32产品的最大可移植性。HAL使用了比较大的Flash和SRAM。9 C7 R; n% E% U4 ` 2.LL库(Low Layer):ST最近新增的库,与HAL捆绑发布,文档也是和HAL文档在一起的LL库更接近硬件层,对需要复杂上层协议栈的外设不适用,直接操作寄存器。其支持所有外设。使用方法:独立使用,该库完全独立实现,可以完全抛开HAL库,只用LL库编程完成。在使STM32CubeMX生成项目时,直接选LL库即可。如果使用了复杂的外设,例如USB,则会调用HAL库混合使用,和HAL库结合使用。编译后LL库只有HAL库的33%体积。1 o5 m6 X. v2 I2 _; z; n0 x 3.标准固件库:旧版本编程库;HAL库是ST未来主推的库,从前年开始ST新出的芯片已经没有STD库了 / e/ ^1 N8 }9 h, R( Y6 U 4.寄存器编程:原始底层编程。HAL库和标准库就是ST官方对寄存器编程进行人性化封装后的产物 + p. c5 U: o2 ?( Z" r 六、编译过程) @0 _# o$ q: E2 x$ J4 M' E" L & o+ i: C' M4 c* D1 F; q4 |) t8 a ![]() * w8 A( S& Z+ e- g0 p$ V ![]() * e( {: t A$ ?& m; c, G 1.将 .c 文件编译和 .s 文件汇编,生成 .o 目标文件 2.将 .o 对象文件和内存映射规范文件 通过连接器 生成可执行映像文件。MDK是生成 .axf 可执行文件 : ~' r8 I7 [# y. _/ S 3.通过闪存编程器将可执行映像文件下载到芯片的Flash中0 N2 Z! q" `# Y3 y. [$ o1 \ 4 G4 J. F6 Q4 X: W# n1 c4 d. N5 E$ ] |