硬件方面:IS62WV512166 E. r8 }8 @, {$ u, F
软件方面:MDK" e3 `3 B- y" o
4 @+ Z& j0 V& a% }% \修改startup_xxx.s 堆栈地址并在__main函数前初始化FSMC# m9 n% f' v0 v0 H% G
修改.sct文件(分散加载),添加外部SRAM的使用空间及大小。2 u+ Z6 J; |! f }* f- q
具体步骤如下:% [$ E" q: w4 U s, s' q
- //startup_stm32f407xx.s部分# I [2 j% C2 G& O/ e
- ; Vector Table Mapped to Address 0 at Reset
2 y! V! J3 K. G; } - AREA RESET, DATA, READONLY7 w$ ?: |# A. O1 I4 A0 A# f& Z# ?
- EXPORT __Vectors
* M5 D2 Y1 Z1 \/ @- c! ^( w2 r% \ - EXPORT __Vectors_End
" {5 V, b6 b/ |9 A0 c4 f - EXPORT __Vectors_Size
, A( a. S U$ b" D* c -
~" t, F, \4 r3 c' Q- P - __Vectors DCD 0x20000100 ; Top of Stack
- I7 z0 u x# ]# |/ B; e( f) c - DCD Reset_Handler ; Reset Handler" e( [7 c% Y2 u
- DCD NMI_Handler ; NMI Handler
5 P* j$ c( P( ^ - ...
6 p) i) U6 v( D% ~1 S - .... s6 ]6 D0 s. M
- ...
) o2 t% C7 d9 s4 T# R - IMPORT SystemInit ' _* T, y: y- R7 V6 v6 I A
- IMPORT FSMC_SRAM_Init' q1 R# D9 o+ j1 l
- IMPORT __main
( w/ `5 n |4 ? - LDR R0, =SystemInit) B! _5 M, ~" P6 T. @
- BLX R0
9 ]1 s& I- r7 s4 o# I1 J; o+ { - LDR R0, =FSMC_SRAM_Init
2 E+ X+ l: h# Z9 K M7 @- h( ] - BLX R0
& l1 o) z, d5 U/ a - LDR R0, =__main5 c% ?/ I" d" U2 |) A
- BX R0
- h: n9 h8 B2 Z a% J- e( K - ENDP
a ^2 o Q5 G1 T- ~) R
复制代码 0x20000100 替换 __initial_sp/ p) |: p5 X+ o( u" o! }! y
添加IMPORT FSMC_SRAM_Init
4 u" u) O* t% w$ Y9 H# @8 U- Z添加LDR R0, =FSMC_SRAM_Init和LX R0。敲黑板这两句必须在__main前面
4 z1 D T a# y& t这里的FSMC_SRAM_Init函数是使用正点原子探索者407寄存器版本的,里面所使用的变量只能是创建在内部SRAM哦,一旦用了外部SRAM就会触发HardFault,后果你懂的。所以尽量使用寄存器来初始化配置FSMC。
( X) z. B. w- X4 O! m% f
. a5 y4 m+ s! e/ o, S/ V7 v, K0 X7 U! z7 S( {* t
接下来就是第二部分,配置内存分配空间4 _7 T2 }; x7 W3 z
按上图配置,要注意的是default一定要勾选,不然内存是不会分配到外部SRAM的。当然了你用__atrribute__来指定分配也是可以用的,但是有一个问题就是你不能初始化赋值,管你是非零还是零赋值,通通没用,原因何在,我也不知道。希望高人指点一二
: X) g9 v( c. M! Z9 ?+ ?) E q. g* o/ `
# e1 Q3 j$ w. G之后就可以愉快的使用外部SRAM啦。
( O! W" { a5 ~( T编写代码的时候使用方式与内部SRAM无异。
[1 f$ q0 }/ p+ c8 M. M不过速度嘛…肯定比使用内部SRAM要慢的,毕竟FSMC操作外部SRAM的速度就那么大。
: u$ J" P7 R: \6 r# N: d& A( [( O' J3 o( l8 z+ @+ b8 b) V+ D
; r% z( L% p) P- B# F
最后附上我改写后的纯寄存器版本的FSMC_SRAM_Init4 h; F7 q; U1 `6 _) O( H
经测试能用在STM32F407上,其他芯片请自行修改。
/ Q! E! A, @# v; `$ L L" W- void FSMC_SRAM_Init(void)6 F! i v3 `7 Z
- {* i* i0 s* g, |1 _
- /*-- GPIOs Configuration -----------------------------------------------------*/
4 p8 V* _4 p! ^6 f K- d8 i& u - /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */, g ~$ L$ S$ f3 U
- RCC->AHB1ENR |= 0x00000078;
2 k( l6 Y" R& C! m6 H -
' k% o! a" P! o/ i# l) | - //PD0,1,4,5,8~15 100M AF OUT_PP UP
2 y# b3 t) i* g* D& T. m- }& a - //PE0,1,7~15 100M AF OUT_PP UP9 u6 W6 l7 H; J6 L+ v! h& Z7 E/ f
- //PF0~5,12~15 100M AF OUT_PP UP
/ t0 I8 w' d' a' g$ a - //PG0~5,10 100M AF OUT_PP UP
# }4 U' [$ _# j+ D6 G, m! p% E7 ^ -
$ R. b) T* f6 e6 S0 n, F& c% o( ~' L - /* Connect PDx pins to FMC Alternate function */
0 g @" x( b- W9 s3 T# H; V - GPIOD->AFR[0] = 0x00CC00CC;
5 v: v1 a8 [7 ^' h - GPIOD->AFR[1] = 0xCCCCCCCC;% u/ q, C4 i) _
- /* Configure PDx pins in Alternate function mode */
4 P0 n% I# U8 }, {" ~ - GPIOD->MODER = 0xAAAA0A0A;
3 B/ f* D6 f: d! {* e9 c) T - /* Configure PDx pins speed to 100 MHz */
' @0 R) J$ f* s - GPIOD->OSPEEDR = 0xFFFF0F0F;
5 q" `1 e$ F! I) S( D& U - /* Configure PDx pins Output type to push-pull */
# ~8 D, D' t8 U - GPIOD->OTYPER = 0x00000000;# W' K' N1 N; |" b3 F% e
- /* pull-up for PDx pins */
/ \, O- H( c( M6 t5 d& P. I - GPIOD->PUPDR = 0x55550505;# N% X1 G- N* }0 H$ X
-
) v& H- j3 b4 X& d' r5 [ - /* Connect PEx pins to FMC Alternate function */- K: |" S8 j! ?( H8 N$ ^' l6 u' E: J
- GPIOE->AFR[0] = 0xC00000CC;
/ P& u7 c$ f7 c: N0 @ - GPIOE->AFR[1] = 0xCCCCCCCC;
( p5 \1 t2 G$ T! H, k3 L5 o - /* Configure PEx pins in Alternate function mode */
, L1 @# W- t9 I& ]& r - GPIOE->MODER = 0xAAAA800A;3 h5 y8 |6 \& t; L/ n3 X% b
- /* Configure PEx pins speed to 100 MHz */ % p- e7 c2 T1 ~
- GPIOE->OSPEEDR = 0xFFFFC00F;; C& x, z- n# i; }9 K# Q
- /* Configure PEx pins Output type to push-pull */ 9 G0 X2 l- n- q3 |% k0 Z
- GPIOE->OTYPER = 0x00000000;
- g0 j. t- G' R! j/ ? - /* pull-up for PEx pins */
8 k8 E( u7 m v8 g1 @( n1 q - GPIOE->PUPDR = 0x55554005;* u0 {( I/ @+ }1 R* \. I
- & x0 I# p8 {( U" u. G5 g
- /* Connect PFx pins to FMC Alternate function */. Z T$ P/ k$ O; J2 s8 I) _
- GPIOF->AFR[0] = 0x00CCCCCC;- G% d) f, z# `, I3 k9 N) }
- GPIOF->AFR[1] = 0xCCCC0000;7 e; n( d- d% k& |
- /* Configure PFx pins in Alternate function mode */
% w( H% q5 `& B* Y4 H7 D9 ` - GPIOF->MODER = 0xAA000AAA;
' S6 r; ^5 ?6 m8 l' N - /* Configure PFx pins speed to 100 MHz */ : ?& O! }' {- ^ Z# n& U0 O
- GPIOF->OSPEEDR = 0xFF000FFF;
9 k* K4 G0 Y8 l5 X - /* Configure PFx pins Output type to push-pull */ 1 `: `% ~- q: a) P
- GPIOF->OTYPER = 0x00000000;
9 ~0 p) y, y# D4 G5 u - /* pull-up for PFx pins */
b3 j7 g( j: c" ~3 \$ ^ - GPIOF->PUPDR = 0x55000555;& m# D% q/ v0 n) l: i
-
! T% ?6 `# Q6 H I7 {- L8 q1 C - /* Connect PGx pins to FMC Alternate function *// n( \: ^! Q; c2 w1 S$ ~- I
- GPIOG->AFR[0] = 0x00CCCCCC;
% \& s9 J- i5 h- J4 s - GPIOG->AFR[1] = 0x00000C00;
/ s8 r0 F0 ~" ?. q9 v0 ^ - /* Configure PGx pins in Alternate function mode */
3 |$ C8 T) p6 C2 ]6 y7 W* n: A - GPIOG->MODER = 0x00200AAA;
' t* {" q- N6 D! T. B0 ~ - /* Configure PGx pins speed to 100 MHz */ 6 C0 I# p+ x+ ~
- GPIOG->OSPEEDR = 0x00300FFF;
9 t2 ?2 R# v4 K- M3 H: h5 C - /* Configure PGx pins Output type to push-pull */
5 l) J4 R- G6 F4 [. ~ - GPIOG->OTYPER = 0x00000000;; h" \( r% j% R
- /* pull-up for PGx pins */
) d$ h% D8 ~% M6 { - GPIOG->PUPDR = 0x00100555;/ {% y/ c- d- I" r: q$ L0 U
-
/ Y9 R+ k; }$ i - /*-- FMC/FSMC Configuration --------------------------------------------------*/
- G0 } u# @ [5 K) W1 ~ - /* Enable the FMC/FSMC interface clock */
& y' J- D2 L, x2 H' H; l/ V+ @ - RCC->AHB3ENR |= 0x00000001;
6 t4 @6 ^6 z% s; _ - |/ w8 a+ Z4 }8 F+ ^. |
- //寄存器清零& H; T$ y' ^9 m! ~; z% u+ q
- //bank1有NE1~4,每一个有一个BCR+TCR,所以总共八个寄存器。
, g2 d( v; M F0 j' l - //这里我们使用NE3 ,也就对应BTCR[4],[5]。 & N1 U2 ?. T' t0 l* i, i" C* }0 c
- FSMC_Bank1->BTCR[4]=0X00000000;
s- U9 r8 ]! p - FSMC_Bank1->BTCR[5]=0X00000000;6 _3 |3 ]# [- A7 ?" z; d
- FSMC_Bank1E->BWTR[4]=0X00000000;5 b/ b# Z& X3 b( [- x v
- //操作BCR寄存器 使用异步模式,模式A(读写共用一个时序寄存器)
& F! i) W: e. _& i9 Y/ B - //BTCR[偶数]:BCR寄存器;BTCR[奇数]:BTR寄存器
8 s' w/ `& E6 m/ v. Q. F0 m - FSMC_Bank1->BTCR[4]|=1<<12;//存储器写使能5 V; j, B, I5 i( f
- FSMC_Bank1->BTCR[4]|=1<<4; //存储器数据宽度为16bit 3 b$ T) a0 S6 c) w
- //操作BTR寄存器 (HCLK=168M, 1个HCLK=6ns
, p# _* i9 j2 Z w - FSMC_Bank1->BTCR[5]|=8<<8; //数据保持时间(DATAST)为9个HCLK 6*9=54ns ! u8 f8 C0 o9 V1 m% x3 `
- FSMC_Bank1->BTCR[5]|=0<<4; //地址保持时间(ADDHLD)未用到
" U& |% P. f) G3 a* t3 V- q - FSMC_Bank1->BTCR[5]|=0<<0; //地址建立时间(ADDSET)为0个HCLK 0ns
4 n) K* [3 c+ E5 d5 g k' _/ P - //闪存写时序寄存器 & s# A" i- i; T2 g1 m2 x
- FSMC_Bank1E->BWTR[4]=0x0FFFFFFF;//默认值
4 `9 E9 Z( u* ^1 Y* o( R - //使能BANK1区域3
) N; U- w9 M& n3 N" ]$ _ - FSMC_Bank1->BTCR[4]|=1<<0;) e. ]9 t4 Q$ ~0 P9 C
- }) t+ Y* ~" L1 J
- ————————————————
" g" O" w( i/ ?* Y! Y
复制代码 6 g/ Y1 I: P- \
|