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

【经验分享】stm32和cortex M3学习内核简单总结

[复制链接]
STMCU小助手 发布时间:2022-2-9 21:52
Stm32综述
这可以说是我第一款认真学习的单片机了,学完这个就要开启我通往arm9的大门了,接下来把我学到的东西做一个系统的概述:

- l3 f6 G7 Q- [! n1 E' f1 S5 ]
842584-20160308203600538-146886588.jpg
2 B% q7 z6 B4 w  v3 m4 o# x
上图是stm32的系统结构。
5 X; c# u) x0 D) J  g3 I
使用哈弗体系结构,取指和取数据分离,
5 G) d- |8 b7 D) Z) }5 K4 a, F' f1 F
ICODE指令总线连接到flash闪存指令存储区,这个存储区的地址在0x00000000-0x1FFFFFFF之间,负责取指操作。
# Z* I- E1 _4 w& n' o- N6 N+ d
DCODE数据总线负责在0x00000000-0x1FFFFFFF之间的数据访问操作。这个数据存储区可以是SPRAM也可以是闪存和外设。

' E. U( j5 |" f7 B
系统总线:负责在0x20000000-0xDFFFFFFF和0xE0100000-0xFFFFFFFF之间所有的数据传送。
, J" `7 j$ [- i8 i$ U& f
注:看到这你可能会迷惑,M3内核不是只有指令总线和数据总线吗?对的,但是指令总线和ICODE指令总线不是一个,选取一张M3内核样例处理器的图就明白了:
6 V( I5 g- y& _# [! ?
842584-20160308203603975-767604832.jpg
2 T  L4 U- A1 @+ [; h0 ]6 O+ c* ^* X
个人理解,D-code总线和系统总线都是来源于M3内核引出的数据总线。
6 e) ]: G- z9 N$ `+ t/ P
DMA通过总线矩阵直接和内存相连。
9 U* W) S8 A! ]$ V" ]3 M. m  h8 g- z
总线矩阵协调内核和DMA对SPRAM,闪存,外设的访问。
; I& [4 n; K) c! |5 t, o, y+ _7 b
AHP总线桥接两个APB总线,两个APB总显得最高速度不同,APB1最高速度限于36MHz,APB2限于72MHz。两个APB总线上挂接着不同速率的设备。

5 f, r# C3 O, f
Stm32f10系列的静态SPRAM为64K,起始地址为0x20000000.

& v3 P* g+ ^) h- q+ y
2 y! z# \; o6 K- ~$ q+ n, \2 i( ^* h+ p4 t+ p3 ^  t

7 `) R0 C5 x7 d- F3 ~  e* L
- o# O# f8 h# v: r! M9 `. P
Stm32的启动方式有以下几种:

  g1 J0 }* {3 ^4 K2 q
842584-20160308203606647-820585976.jpg

5 z3 |0 [6 f: x- K8 f4 [* o5 V& j

4 ^( h+ Y6 {9 d9 i
- `* e3 f4 B8 i4 {& g$ ^
( u6 j8 I0 Y9 F3 w: g2 f9 j
0 T: y* @  R2 |  P2 f5 I  r) J
  p( N, a( u0 @1 Z# U( W
4 f# |5 g8 I3 ?  ]8 |# ~! l
  ~7 Z! T, w5 J; n+ Q: {5 ~' b) a' v. c9 L: D' C. x6 _( v6 c; |
. Z; ?) u9 Y. O0 \' Q: P
) A1 x9 u4 _  d" K
下面的是stm32的时钟树,stm32有四个不同的时钟源:
1.HSE时钟:高速外部时钟信号,来自于外部晶振:可作为系统时钟源,也可被PLL倍频之后宫系统时钟使用。
2.HSI时钟:高速内部时钟信号,来自于内部RC振荡器:可直接作为系统时钟,或者二分频之后作为PLL输入,倍频之后供系统使用。
3.LSE时钟:低速外部时钟,来自于外部晶振:为定时时钟或者其他定时功能提供
4.LSI时钟:低速内部时钟,来自于内部RC振荡器:在停机或者待机的模式下,为独立看门狗或者自动唤醒单元提供时钟。

- H3 v" w6 |: K8 B- y7 q/ K
+ C4 ?9 A  _5 c& \
经过一些列倍频,分频得到了几个和开发有关的时钟:
1.SYSCLK:系统时钟大部分时钟的来源
2.HCLK:由AHB预分频器输出得到,高速总线AHB的时钟信号
3.FCLK:由AHB预分频器输出得到,自由运行时钟。
4.PCLK1:外设时钟,由APB1预分频器得到,最大36MHz
5.PCLK2:外设时钟,由APB2预分频器得到,最大72MHz
时钟树如下:
! q* C$ v/ F" Z5 e9 i3 w( a
842584-20160308203612960-2102733665.jpg

1 |# v' X7 O) V. [' ]

! D, b$ Y* S$ @
2 x' U7 a: y/ C" e) [0 R4 S( F$ B1 [" l& w6 T

% \3 T  `" D# t9 e  n) q* d* u  A- [# W4 u1 \$ G9 `
Stm32的GPIO的8种模式:
(1)GPIO_Mode_AIN 模拟输入 " O5 g) \( W4 w* Z$ ^
(2)GPIO_Mode_IN_FLOATING 浮空输入3 s4 A3 p( F, _5 l2 R0 m5 T
(3)GPIO_Mode_IPD 下拉输入
( w& j: `8 c( r  q; y) r2 B(4)GPIO_Mode_IPU 上拉输入 9 |+ J7 @9 y+ ^* Y0 ~6 ~8 d3 i
(5)GPIO_Mode_Out_OD 开漏输出" O" q6 w' H5 m, q% X* e7 i
(6)GPIO_Mode_Out_PP 推挽输出7 v/ s6 P1 p; [: R
(7)GPIO_Mode_AF_OD 复用开漏输出
9 Q3 m* [' _# {" L4 S2 w' \$ R4 r! b(8)GPIO_Mode_AF_PP 复用推挽输出

  q, Z1 W  K; g  G
4种输入:模拟输入和明显接受模拟信号,比如用于ADC,上拉输入和下拉输入就是默认时高电平和低电平。浮空输入在芯片内部既没有接上拉电阻也没有接下拉电阻,引脚电压是个不确定值,输入阻抗较大,常用语I2c,USART。

1 v1 {' H2 c# y: S$ Q) @* \9 x6 N
4种输出:分复用和非复用,复用为分配给片上外设,非复用为用作正常的IO口。推免输出为正常的输出,而在开漏输出模式,IO口可以由外部电路改变为低电平或不变。所以开漏模式可以读IO输入电平变化,实现C51的IO双向功能。

; u3 i8 w: O7 Z7 d; f
* U, ^  v3 Q" u- @$ d3 q; R9 v7 B$ i5 J. x
5 U3 b& n6 f$ k" L3 @' ?3 O

) X; Q" Z' a$ F5 n
" u; l7 X8 J* D7 v8 O
1 j4 h7 z/ J; t" b! u" _* ~
# Z+ h. l; B. q. H
. \. F7 u4 y+ C1 L: ^3 d; M# T0 }4 r7 ^0 H$ S6 |& [

% k* s7 P% X, k2 O* E( n; N* k/ U3 C* D% q' x1 Q* B

# U& }" `9 g4 M1 N7 Q5 z$ @" d+ M: f. `$ q

5 J( N" K$ \: Z8 c5 p. O5 ]
8 z1 G) h2 i( U8 s  A# s$ N
7 P& d) z0 K; f+ r) P$ ?! Q0 e
' u/ o$ j, F" E  e7 z5 {. \7 b7 K" O: D' e, s1 z. N5 l; a

, _; a/ d% }7 b; c- W: y( d' W2 Y1 H' o7 s, C' ]" d, l

' j, _2 @) }  v. s8 P& V6 V  \' I0 e; l
; C7 G+ N# Q) a) Q8 O
当年看不懂的东西,现在越发清晰。
2 T& D4 r- l  b

2 `1 F- H6 `( U5 S寄存器组
这一部分就属于M3内核中的知识了。
M3内核中的寄存器主要如下:

; g( @  d8 m/ r
842584-20160308203617757-828635669.jpg
, v" F9 x1 z, a' j! V
842584-20160308203621522-2107100479.jpg

: `) k6 Z* p( s4 E
下面挨个解释
4 W7 E8 S5 F  B) F
842584-20160308203623929-995530750.jpg
7 }  W, ]& m( _: n9 A  k! \
842584-20160308203643897-1571275885.jpg
  A' I# i2 ^( P5 g
842584-20160308203645850-58036291.jpg

( G# ]: |; }$ _5 J, F2 `
) G  w' S& x* O6 {4 I# q
M3使用的是双堆栈,复位之后默认使用MSP,默认是特权级,如果想要切换需要手动修改。而上面的MSP和PSP的用途只是一种推荐用途,并不是一定要那么用,比如说复位之后你可以不修改,那么你的常规代码就一直是特权级,使用MSP(我就是这样滴。。方便至上)。
% m/ _/ J( G5 H( G% j
842584-20160308203646897-302961918.jpg
* ^: `+ C* x4 m' q! Q5 _7 _
      这个寄存器又叫LR寄存器,那么当函数是一级调用的时候,就可以将返回地址直接存到LR中,省去了访问内存,提高了效率,当函数调用高于一级,则需将前面的LR中的值压栈,以便存储新的值。
( y9 u" ]  |# u+ a9 z/ ?& f0 A
      当进入异常的时候,LR寄存器的值更新为特殊的EXE_RETURN:
      
842584-20160308203700319-812289253.jpg   

" a& W% b* N7 C6 M& \
842584-20160308203702288-2133184213.jpg
! ?2 m! M2 K, K9 }. J0 d5 L8 m- b
842584-20160308203704272-329667468.jpg

( p# s1 z7 l3 X; ~8 A2 J! i
842584-20160308203705319-1090289122.jpg

" f9 e% w2 w5 V
就是PC嘛。。。。

3 _; E" A, d% }. C- Z# C9 P/ R
842584-20160308203706975-1238474005.jpg
      
1 W, s! B/ [( l( G% I! A/ R3 e
) i6 b% j3 a6 X0 G7 o! j/ Y
     特殊功能寄存器一定要在特权级才能被访问(使用MSR和MRS指令),至于是Thread    模式还是handler模式无所谓。
     详细功能如下:

  J- ^2 o6 g; h) z! f( D
842584-20160308203709460-1683866030.jpg
& g; N. ^. A/ \5 w+ w
    xPSR属于三合一寄存器,可以分出三个子状态寄存器

- N" O. H5 h5 i
842584-20160308203710022-1723143888.jpg
9 R2 s' s- y' E. @! n
    通过MRS和MSR这三个寄存器可以单独访问,也可以两两组合访问,也可以三合一访问,这个寄存器大致如下(看下就好):
: p% [; A) c, A- x3 W& w
842584-20160308203711335-412320091.jpg
* u8 V0 j- K( k  e  Z3 R

7 \' e4 w: P; B# b4 U: V. p7 E0 F% J0 D' l6 p/ N6 X$ A
    其实除了修改上面的寄存器可以开关中断,M3还有专门的开关中断指令:

1 I! @& J. s) I- k- N  G
842584-20160308203712804-1286990269.jpg

; |1 o8 z8 j) F) G" l

$ K" x( b/ B! O) b! T& F: L" J0 R

& }- o$ y& l  n2 `) _, Q
    CONTROL寄存器功能如下:
& A2 r; R/ R+ q& x9 Q
842584-20160308203715163-502120058.jpg
% I9 l! j; [; y* u9 t

& s% y# ?; V  r9 l/ a! K

+ K9 ?; L5 ]$ A+ L; ~5 ]. g1 e4 i4 L3 M1 R
$ b: m) ]- A) a% M) I* O
  P, \# Y! a! S! S; u1 ]
: F  ~1 E8 P  j5 S2 _7 L
+ ~& ]% Z, z$ Y5 }* G

6 t2 A8 f) ~$ `7 R! z
, W% _' Q# K( d4 u0 R" v& J' Y, f% l5 \1 g4 M' ~5 p7 S+ o; R" @

- |2 U! T: n! G6 M( z) A1 ~. Z& k

5 z0 `4 p& [, c# S5 P! t3 d  z! a6 M* j& b8 p

0 z' C$ l( l, D. g8 @6 o" a
+ D1 g% S9 v* A0 ^
7 n) @( V8 A& C; n
2 |9 Q6 C' L) u2 Q2 ?( }
( L6 O3 a+ V2 z& a' B2 `+ }4 l% A* v$ x; J% I0 Y1 @4 h" x
! V6 ]( v( g  N/ [

0 n9 [3 r# `" u/ {3 i2 T/ @% c4 \. f% n8 X
- E( d( @0 ?( Y0 G

8 T5 m7 Z" m. A7 K6 F; Q3 }( q. h8 M; z, W( H- k

& s. n: F9 @) h7 s3 o! @9 |( C5 F% o
5 G3 s3 f; X7 S& b% [1 ~* ~
. i, B8 M" s: b: r; V
操作模式和特权等级
操作模式分为Thread模式和Handler模式,特权等级分为特权级和用户级。用户的程序代码一定是Thread模式,而异常一定是handler模式,用户程序代码程序代码可以是特权级和用户级,但是异常只能是特权级。

5 _7 ~# O+ n# W& F5 M
842584-20160308203716163-892187985.jpg
6 K+ ]* @' ?. D

) z/ R8 I5 A# h: ]3 r$ r
Thread模式+用户级,就不能访问系统控制空间(SCS)和特殊寄存器(除了APSR)。
2 G  P" [( a* s, ]) }. \6 \' {
特权级切换到用户级很容易,修改下control寄存器就好,用户级切换到特权级的方式只有触发一个异常,切换到handler模式,这个时候是特权级,然后修改control寄存器的零位,再返回就是特权级。
* ~' O& `  D* A0 w
下图是一个各种切换的示意图:

. F. {5 J/ h4 T9 g8 O! _
842584-20160308203717600-1039192697.jpg

' F: C) L5 @. ~  R; f

( K' s! n# }* I7 B1 `. J" h
这种设定的大致用意就是我们写普通代码的时候设置为用户级,这样的话可以防止对SCS和特殊寄存器这种敏感地带的误操作,想要访问这些的话就只能通过进入handler模式一步步去访问,而且这样的话异常是特权级用MSP,普通的用户代码使用户级用PSP,不会出现数据意外互相干扰和破坏,这样的话整个系统的可靠性就会很好,当然我们写小程序的时候不必这么拘谨,反正我一般都是一直特权级小程序。

$ @) T9 m7 g0 t0 o) n  f
/ b  z6 v. J+ c% @. M* B: G2 i
2 r- k  G* \% w1 G  ~$ ?" U! w' @$ {' @3 p! }5 `! T

# E( s% r0 A8 C9 @1 _. T( @. _/ N+ n$ u

2 I/ ~  K6 ^4 C' \9 N, q
. g, H6 T; v+ d! P9 d2 K) O- ~0 i4 Y7 k! }8 `# B5 t% P

4 p1 Q0 y; S" K+ D6 R) ^存储器映射
      M3将内存分为8个主块,每块512MB,先上一张M3内核的存储器映射:
; F6 v* h- j/ N/ P4 C( m
842584-20160308203721866-479801403.jpg
. I) [8 |. t9 e( S8 q* b! U/ c
     所谓的SCS如下:

, u) W% l. }: @# F% N- m( P1 L
842584-20160308203724022-54566331.jpg

/ K: q: O: g! I* f
9 d* q% w9 q$ q: @! L4 N
% e& G$ {7 a- Q9 H! V! E
     所谓的位带就是将位带区的1bit膨胀为位带别名区的32bit也就是一个字,通过访问位带别名区就能达到访问这个bit的目的,优势如下:
+ ~3 R; D* y5 \' Q% {* P% s
842584-20160308203726288-728254178.jpg

; K; X7 m% O6 \2 t
     当然位带还有一个明显的好处,就是在多任务的系统中,两个任务同时去修改一个共享寄存器其中的两个bit的话可能会出现“紊乱现象”,所以就需要将“读-改-写”三条指令加上临界区等手段,但是有了位段,M3直接去写那个bit的位带别名区就可以了,这样就成为了一个原子操作。

/ |3 I( V4 ~& a) V/ H# m
     不过上面的图确实是粗线条,下面上芯片手册的详细图片一张:
6 U! n. O1 a8 X9 y) D
842584-20160308203736350-1162441161.jpg

$ h) I6 g2 e% v1 h7 E
6 _2 ~# R% A. N; q' N6 B

4 T7 o8 z1 e* P& O
   M3有些数据传送指令支持非对齐数据传送,如LDR/LDRH/LDRSH。其他指令不支持。
对按字传送来说,任何一个不能被4整除的地址都是非对齐的。而对于板子,任何一个不能被2整除的地址都是非对齐的。

/ o8 [5 k) D9 u! l5 D2 p% Y1 T
   M3支持大端模式和小端模式,但是推荐使用小端模式。M3的大端模式是“字节不变大端”。

7 P; G# g5 y6 a/ {; t3 o1 J& Y5 X, p" F: s$ f

+ e- ]7 Z( @: t# M
( |) X1 O+ {8 X- H
$ c& s: G/ Q+ i' A% p  ^4 |; M% H7 I; U/ S2 Q
' d6 x, ?5 A6 \6 P  H8 C- \. \

2 I, ~4 t5 [1 n3 [6 i5 k( e" g3 V% t
' o, {5 u, @. }+ ^) M- I! S6 [

" ]4 G% J* r5 H$ c0 x' ]  G, A6 l  u2 B  j' Y$ l. h
2 l# A( z. t& x6 }5 s6 B
2 V$ I# p- y5 r) Y2 q* M/ u. m
) F8 g* a8 _* L7 Q

. y* E4 w  U/ i
$ @2 D6 }% ]* o. b, V% ?# ~0 h* w' w: ]- M
5 h5 {6 L: O# s  A9 u% t
1 \- |. i2 B9 A
- q" O( r; F& M  L
! ]3 S) f9 A8 ?+ T8 j* [5 P5 C
! k" z; ]! o# L/ {- k

7 E0 l5 t/ F/ s
! r( J- @5 _! a0 q$ k+ \# I% r  [" k4 x: r

! U% _% G( N/ b9 }: m$ A7 Z# M; O* @  ?7 ]6 s3 G. B1 A

7 [2 X1 {7 q9 |' M7 r+ y3 U) g  D5 h
+ `- V1 n% {$ C, x1 C6 O

# O* K2 W: D3 Q2 m4 b  Z/ f1 P% b. O

' d/ M8 k8 Z3 e# y! j: J1 z: I( A+ L* v: _# ]

8 m4 t6 C" l( y6 Q) I( O& e# _4 u
( ^; b& o! C/ G0 d% [+ l6 F
+ s/ a5 C$ C6 [' f) X
) ~" y# U( M( ~% @中断和异常
异常是指任何打断程序顺序执行的事件。在很多时候,中断和异常这两个概念是不做区分的,所以我以下也就不作区分了。

; h! W- n4 ]0 i' B) m
M3的异常系统简直就是它的精华所在。

* E+ J6 N1 T/ e. Y2 w) d5 a/ Y
M3的异常分为系统异常和外部中断。
系统异常如下(stm32沿用):
2 T. `' e/ \, R2 e, p( J8 c
842584-20160308203741335-291544513.jpg

: W- h, g, B! O, R$ B* l1 r+ f. g
842584-20160308203743944-1399280562.jpg
3 ^( l8 a1 S, v4 p7 F; f: G
外部中断M3内核支持240个,stm32只使用其中60个:
6 E1 d: ~" F0 q1 r' i' a
842584-20160308203745350-80903858.jpg

- T1 ?+ {) h* }- [: h: [; s/ P
9 Y' J; u& ^" F& L; }) @. `
所有的异常,除了复位,NMI,硬FAULT优先级为-3,-2,-1固定,剩下的都是可编程优先级。
3 C& F' R; X2 q& J" I" C- [) p1 d

7 r& Y8 `* ]6 e  a2 b% k$ v, I; K& U- z" \) h
优先级:
M3内核中优先级寄存器为8位,这8位不用全用到,最少用到3位(MSB对齐),stm32只用到其中高四位,所以stm32总共有16种优先级。
M3内核中对于外部中断有抢占优先级和响应优先级,高抢占优先级的中断可以打断低抢占优先级的中断。抢占优先级相同的两个中断同时到达,响应响应优先级高的中断。如果两个中断一切相同,那么响应序列号更小的那个。
因为外部中断的优先级寄存器总共八位,所以需要对其进行划分,响应优先级至少有一位,所以M3中外部中断抢占优先级最多其实是有128个而不是256个。下图是从bit5开始划分,总共用到三位设置优先级:

7 u3 |. @9 |8 s' \& }4 t) V" _! ^5 h
842584-20160308203746585-2104768633.jpg

: e6 F6 m* \7 Z( [* p
; C# e: v4 J$ q
' _% D+ \4 I5 J' o, R% m! D; T
具体的芯片决定优先级用到多少位,以及从哪一位开始划分抢占和响应,stm32用到4位设置中断,有5种分组:组0从7bit划分(全部都是响应优先级),组1从6bit划分,组2从5bit划分,组3从4bit划分,组4从3bit划分(就是只用到抢占优先级)。
8 t/ q& }1 z+ X& n, C3 q

. y. t* d) H. V9 J0 q6 o
向量表:
当发生了异常需要响应的时候,M3需要定位其服务例程的入口地址,这些入口地址就存在所谓的“向量表”。缺省情况下,这张表存在0地址处(当然也可修改NVIC中的向量表偏移寄存器来重定位向量表),每一个表项占4字节。
如下:
7 _6 X& J* B" U3 J
842584-20160308203748538-1244447523.jpg
; m* g' K1 x& v5 Q" d2 g* {( d: M
$ j. u  p& w# k; M" Z
首先向量表的开头是主堆栈的地址。

  {# B& y: p9 p; S- k9 C5 f: Y
可以看出,不论如何一个向量表至少包含下面4个表项:
1.MSP初始值
2.复位向量
3.NMI
4.硬fault服务例程

- w7 D: _8 i0 }1 `: M: O# k$ ~8 ]
中断的输入与挂起:
当中断输入脚被置为有效后,该中断就被悬起,到了系统中它的优先级最高的时候,就会得到响应。
    但是当某个中断得到响应之前,其悬起位被清除,则中断被取消。(所以stm32都是在中断服务程序的最后清除中断标志位)
当某中断的服务例程开始执行的时候,就称此中断进入了“活跃”状态,并且其悬起位会被自动清除。  

- A: a1 f) L$ U+ g$ V  ]. t: ^0 Q3 l7 @1 N' P( `! Q" v3 Z3 b
SVC和PENDSVC:
首先SVC(系统服务调用)和PENDSVC(可挂起系统服务调用)的区别在于SVC异常必须立即得到相应,而PENDSVC则不是,他可以像普通中断一样被挂起,知道其他重要任务完成才执行它,挂起PENDSVC的方式为:手工写入NVIC的PENDSVC挂起寄存器。
SVC的用途:操作系统可以不让用户直接访问硬件,而是通过触发SVC异常来使用SVC系统调用来让用户程序简介访问硬件。好处:1.OS负责具体硬件,用户程序不必花费心思控制硬件。2.OS的代码应该是经过充分的测试的,所以整个系统可靠性高健壮性好。3.用户程序无需在特权级下执行,无需担忧因误操作让系统瘫痪。4.通过SVC机制,用户程序与硬件无关。

8 b2 T% g2 j! g, U; e0 I2 i1 B' U+ Z: U
842584-20160308203750179-1918128768.jpg
) g& r/ [" Q% g# @" g
6 U; u4 [- N0 g* ~# Z
PENDSVC的用处:上下文切换,如ucos上下文切换就是用到PENDSVC的。

) [. F& e3 s# W4 y  D9 O1 o6 c! U( [0 J' R4 [3 S

* t6 B. X) S* M4 w; ^, o' c  n8 A
NVIC:
中断向量控制器,也就是控制中断向量的地方,每个外部中断(系统中断由SCB控制)都在其中的寄存器占有一席之地,寄存器列表如下:
   
842584-20160308203751163-1669040342.jpg
% l- e& @( ^0 T  M6 \% ]  H" x4 T8 ?; B
1 R6 }, v0 k( j) f6 {. @, Q
     其中悬起寄存器可以系统自动设置,也可以手工修改以悬起一个中断。

7 w2 M7 q3 V3 Z  ^3 I5 J
     软件中断寄存器也蛮重要的,如下:

  f8 R( H4 b, s1 ^, |" x
842584-20160308203752913-1691985558.jpg

- X( T' v- T" a: R$ K  u  b* c& k5 F3 b1 F5 P" F6 Q  j
4 r& ~, g) G1 t( h

' ?# y( F) G# @3 X2 y  s  y% I1 ?* [+ H9 F3 {

- V' j! r9 K) E; R& |7 d2 p& F6 e8 z! W( D7 H  x4 @+ N
中断的响应和返回:
     中断的响应:
; p4 ~& g- D8 C- I
842584-20160308203754100-2025311353.jpg
      
        8个寄存器以及入栈顺序如下:
$ m/ d4 ?. f6 [. G3 D8 L
842584-20160308203755960-1610934562.jpg    

0 u4 N* E) ^3 b8 P6 ]
     中断的返回:
         首先触发中断返回的指令有三种:
         
842584-20160308203758647-880846930.jpg
8 G* V; z" ~2 n+ q8 P
          返回了之后,做如下两件事:
          1.出栈,回复现场
          2.更新NVIC寄存器
) n+ Y' A2 B, }6 X8 _

* |8 ^1 a2 ~% F" ~
+ [" c7 g& I7 g0 A9 b. t6 B9 V+ R3 Y0 c& w2 Z" d
咬尾中断:
   一图以蔽之:

8 A5 ]& @/ F. U
842584-20160308203759804-415386378.jpg
, `- I: t" |0 }2 F
其他
总结了一天,终于到了这一步,还有些零碎的知识点写上:
3 L! {# P8 ^$ R8 c; f/ k  {
M3的堆栈是向下生长的。

  S0 e0 g$ h& R  u
M3取指,解码,执行三级流水,因为其采用哈弗体结构,所以取指和访存可以同时执行,M3内部有解码模块,所以构成了三级流水。

  `8 J8 J  _$ L$ J* @) A' X4 |
1 f+ x2 s0 f- n7 l/ c& n+ o- J
) I, J9 q/ t! ?
6 b/ ~. ?4 x3 x) b9 I( L
收藏 评论0 发布时间:2022-2-9 21:52

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版