硬件方面:IS62WV51216( K0 `& [" C/ ~% y7 K$ j. }5 s1 D
软件方面:MDK' O& [! N# d! E8 e
# ?; t ^- l. a7 [# \0 D7 B* V
修改startup_xxx.s 堆栈地址并在__main函数前初始化FSMC7 E) S$ l" L4 z! u3 N% u0 f4 A! P+ D
修改.sct文件(分散加载),添加外部SRAM的使用空间及大小。
! C$ u5 W/ }, A8 u+ O* T+ U# a具体步骤如下:
5 N. `+ E" t6 n; Y; t* T- //startup_stm32f407xx.s部分$ X! }8 z+ Z% X7 W. m1 L K
- ; Vector Table Mapped to Address 0 at Reset. u4 z6 z$ ^, K9 s# N, q: O/ K
- AREA RESET, DATA, READONLY0 k: ^8 X# v) \. Q) i( {& Z
- EXPORT __Vectors5 v) S" }' X6 g0 `* E/ X' J
- EXPORT __Vectors_End; Q; ?! i0 b$ f7 i6 {* g3 F
- EXPORT __Vectors_Size
9 V1 s, U. b3 m U5 W -
9 W6 p* K$ Z! k6 r& ^6 C - __Vectors DCD 0x20000100 ; Top of Stack0 D7 d0 W8 J8 M
- DCD Reset_Handler ; Reset Handler- j7 v2 w# G; x L# i* p# _0 D
- DCD NMI_Handler ; NMI Handler
5 T; f( A1 R0 M2 N% N w5 j+ M& N - ...) f. X1 z% ^" \2 z% ]% s( c
- ...& t2 W# U8 V V) G* G5 y+ d2 ^9 F
- ...+ I* ~, D+ g t
- IMPORT SystemInit
& g! |* _2 o& D6 c+ ` - IMPORT FSMC_SRAM_Init
3 h: ? [. k) a0 M# Y0 E3 v1 Q/ f! z - IMPORT __main& J! R7 f4 O" g
- LDR R0, =SystemInit
$ B4 A' j. V) T; b - BLX R0$ O. _1 }- |$ B3 R6 Y" G5 C! G% d
- LDR R0, =FSMC_SRAM_Init
' e6 i0 }- R6 U& { - BLX R0
; _& s" c" z2 S. l# V$ f - LDR R0, =__main0 @: P* t9 ^' b% L
- BX R0
) b0 d- J2 G E/ Z. t - ENDP2 O* j& d/ S/ B1 O/ v
复制代码 0x20000100 替换 __initial_sp
4 n! i4 G) L1 J' g" T* r/ a添加IMPORT FSMC_SRAM_Init
( r0 x" A* S" w6 m添加LDR R0, =FSMC_SRAM_Init和LX R0。敲黑板这两句必须在__main前面
/ \; H, o/ C9 i* Q. l这里的FSMC_SRAM_Init函数是使用正点原子探索者407寄存器版本的,里面所使用的变量只能是创建在内部SRAM哦,一旦用了外部SRAM就会触发HardFault,后果你懂的。所以尽量使用寄存器来初始化配置FSMC。
) c6 n' n4 G9 N) g; g& D8 t( u [
' M* _ d6 W1 @7 S2 L* b
接下来就是第二部分,配置内存分配空间9 }% y6 A+ E4 e1 b7 c2 N
按上图配置,要注意的是default一定要勾选,不然内存是不会分配到外部SRAM的。当然了你用__atrribute__来指定分配也是可以用的,但是有一个问题就是你不能初始化赋值,管你是非零还是零赋值,通通没用,原因何在,我也不知道。希望高人指点一二
9 Y2 `7 T* A& k+ V6 Q' J* k# U8 A: }+ m0 q; i$ ?6 R) W% w- l
3 q F5 Y: B5 Z! J K3 F" B4 O
之后就可以愉快的使用外部SRAM啦。5 y* j6 w `3 n, t' |
编写代码的时候使用方式与内部SRAM无异。
9 e4 U8 X1 q7 j9 n) Q8 `不过速度嘛…肯定比使用内部SRAM要慢的,毕竟FSMC操作外部SRAM的速度就那么大。0 K) ?" U5 ]6 `* ]4 |
# f# z4 v9 u8 V. ^6 u' H; @' i' d2 l6 I0 M
最后附上我改写后的纯寄存器版本的FSMC_SRAM_Init
% ~3 [3 B% i1 w$ {( y经测试能用在STM32F407上,其他芯片请自行修改。! O/ O; p2 \1 I' V
- , e# o8 D+ Z4 |: R2 j+ l( T1 W
复制代码- void FSMC_SRAM_Init(void)
. x# c3 |4 s$ j7 O @. j5 t - {
0 d- X7 t2 b; ?+ j0 F" n/ y% Y - /*-- GPIOs Configuration -----------------------------------------------------*/4 J5 l% ^' X) w1 \6 ?/ Z
- /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */1 _! S) _- M- K2 W
- RCC->AHB1ENR |= 0x00000078;2 \6 b8 V& i7 a6 M
-
8 n4 @$ h* M. J6 W8 q - //PD0,1,4,5,8~15 100M AF OUT_PP UP
0 ~9 q- b* K6 ~# L( n E - //PE0,1,7~15 100M AF OUT_PP UP* `' t8 b% T/ y6 w/ e
- //PF0~5,12~15 100M AF OUT_PP UP( z3 N% Q$ D' L+ J' q4 d
- //PG0~5,10 100M AF OUT_PP UP. O% \7 l8 G, _/ ~
- % {3 \3 b$ @/ a* S) R4 _7 W
- /* Connect PDx pins to FMC Alternate function */! x3 q2 D* p% z
- GPIOD->AFR[0] = 0x00CC00CC;. k) _( n7 T* c6 j& @6 E
- GPIOD->AFR[1] = 0xCCCCCCCC;
1 V) P9 T* x. i' L - /* Configure PDx pins in Alternate function mode */ # Y/ d; X6 Y6 x
- GPIOD->MODER = 0xAAAA0A0A;" @+ t C( c: s) [, }
- /* Configure PDx pins speed to 100 MHz */
% A2 T, F* J0 N: a; z - GPIOD->OSPEEDR = 0xFFFF0F0F;9 ^2 h7 J) g e% ?4 m+ O5 a
- /* Configure PDx pins Output type to push-pull */
" q' @% d$ }8 q% d* \1 ` - GPIOD->OTYPER = 0x00000000;
" i+ _1 P. i5 d) J# Y/ n - /* pull-up for PDx pins */ & q8 v. C$ [3 G3 f9 p6 R! v6 G6 B
- GPIOD->PUPDR = 0x55550505;/ M: H# ]4 j2 Y+ ~% u
-
% U4 A: X; P( g; C1 F1 l - /* Connect PEx pins to FMC Alternate function */1 F- @; D9 E% K# H, R9 ^% x) S8 H7 \& ~
- GPIOE->AFR[0] = 0xC00000CC;7 J; S4 ?- i# f- @6 y
- GPIOE->AFR[1] = 0xCCCCCCCC;
; n# k6 x% z% m t, X1 T - /* Configure PEx pins in Alternate function mode */ 8 i4 U& a! U3 U, t2 {
- GPIOE->MODER = 0xAAAA800A;& V, A$ B: v7 t2 ~
- /* Configure PEx pins speed to 100 MHz */
3 P4 \% f! j) W# u - GPIOE->OSPEEDR = 0xFFFFC00F; `5 j+ i8 k# b
- /* Configure PEx pins Output type to push-pull */
7 o, w' I: ^; U7 s1 |( [+ p - GPIOE->OTYPER = 0x00000000;! U1 C- Z+ `+ K
- /* pull-up for PEx pins */ 6 ^ m' c# `1 |7 w" y0 H
- GPIOE->PUPDR = 0x55554005;
: C0 u* C( a8 C0 U - 2 i# B& ?/ ~1 V3 f+ ]
- /* Connect PFx pins to FMC Alternate function */
3 k; S8 C2 W; m5 X: M8 c5 ] - GPIOF->AFR[0] = 0x00CCCCCC;
1 @! }6 T3 }' y8 Z* P7 ^7 M' r - GPIOF->AFR[1] = 0xCCCC0000;# B' X7 W L( K; |$ s2 z
- /* Configure PFx pins in Alternate function mode */
9 S1 W; C3 Q7 R' b7 H+ w, {1 {/ S - GPIOF->MODER = 0xAA000AAA;
: o+ X1 t$ _4 E1 e$ h9 r/ j4 y8 w& x - /* Configure PFx pins speed to 100 MHz */ $ |4 U, d( h4 |" g; G+ i
- GPIOF->OSPEEDR = 0xFF000FFF;- w+ k. h( O) u4 Z
- /* Configure PFx pins Output type to push-pull */ ( g d+ |6 i1 Q* {8 y8 G5 h5 u
- GPIOF->OTYPER = 0x00000000;
/ X! O4 K6 `# B. T - /* pull-up for PFx pins */ - x3 \( P% A3 _# R" I
- GPIOF->PUPDR = 0x55000555;
- s, g- r% i! `# b" Q$ K, m - % F5 ~/ R* S% d' f
- /* Connect PGx pins to FMC Alternate function */8 r7 e0 a& v/ ]3 G& R% k8 O, J! ]
- GPIOG->AFR[0] = 0x00CCCCCC;# D9 L4 ^( h r0 `
- GPIOG->AFR[1] = 0x00000C00;
: X2 U' ^1 N2 J( B& H - /* Configure PGx pins in Alternate function mode */
7 Y- A1 @: u; X7 a - GPIOG->MODER = 0x00200AAA; N8 s: o1 N% j' B* O- d# h
- /* Configure PGx pins speed to 100 MHz */
' }- f# i; h# L# l2 s: H6 N# h6 G. U - GPIOG->OSPEEDR = 0x00300FFF;
) V1 b7 z9 X% ?3 g! U8 a - /* Configure PGx pins Output type to push-pull */ ! b( V1 Q ? E. i. r' u) g& a# m
- GPIOG->OTYPER = 0x00000000; P2 W' c4 |- w4 o7 S( V; W
- /* pull-up for PGx pins */ % e) m" y+ r3 d( }3 x3 d" j. H
- GPIOG->PUPDR = 0x00100555;2 w/ Q4 }) L% _' }- W8 s
-
6 E7 }* r$ U9 M9 A7 X - /*-- FMC/FSMC Configuration --------------------------------------------------*/1 i, @8 R; f' v9 _* x) `
- /* Enable the FMC/FSMC interface clock */" m' q! {7 U$ ^3 w( v$ N
- RCC->AHB3ENR |= 0x00000001;
" O( x2 [, l. z- T -
" {6 t; S# s7 \' g! y, T; \/ D - //寄存器清零
0 j8 v3 h! y/ x8 d% M# T - //bank1有NE1~4,每一个有一个BCR+TCR,所以总共八个寄存器。
8 q. m3 `& ~: _ C- [; J - //这里我们使用NE3 ,也就对应BTCR[4],[5]。
4 D" X! {" \6 P& \; P5 f! L1 q - FSMC_Bank1->BTCR[4]=0X00000000;$ z! R4 t, E8 I4 A! E ^; i
- FSMC_Bank1->BTCR[5]=0X00000000;
4 ]0 H6 f: P6 C& S5 Z" l - FSMC_Bank1E->BWTR[4]=0X00000000;" i% ?/ Z0 S+ ^( d
- //操作BCR寄存器 使用异步模式,模式A(读写共用一个时序寄存器)* `% O! p. f% I* B3 l
- //BTCR[偶数]:BCR寄存器;BTCR[奇数]:BTR寄存器
& x: y; W0 N) }* o5 ^% j - FSMC_Bank1->BTCR[4]|=1<<12;//存储器写使能
5 W ]$ t' ^" W, l - FSMC_Bank1->BTCR[4]|=1<<4; //存储器数据宽度为16bit 8 p( c$ V# Y. I }" w+ _! X
- //操作BTR寄存器 (HCLK=168M, 1个HCLK=6ns 9 `! s" p# u! n. ]! d
- FSMC_Bank1->BTCR[5]|=8<<8; //数据保持时间(DATAST)为9个HCLK 6*9=54ns 6 w* r- I- q* A& q8 c
- FSMC_Bank1->BTCR[5]|=0<<4; //地址保持时间(ADDHLD)未用到 5 }; b! a0 E# o1 W$ ]
- FSMC_Bank1->BTCR[5]|=0<<0; //地址建立时间(ADDSET)为0个HCLK 0ns + |* B. u" ` Y* w5 }
- //闪存写时序寄存器 : X( @+ S: K& b6 d+ x6 J, ? G
- FSMC_Bank1E->BWTR[4]=0x0FFFFFFF;//默认值* d1 d+ A" K. H$ i* ]( }1 Q; w0 T
- //使能BANK1区域3$ P9 Z) \, `8 \# K
- FSMC_Bank1->BTCR[4]|=1<<0;
. `. K' o3 ~1 Y* W" _6 ?) |7 f8 h - }- X6 H! i4 {+ S7 @; d0 v- r; u: f+ c
- ————————————————
8 j+ P! `3 `; J) v% r* |) Z
复制代码
i% T0 w6 C! [7 v, K$ z* P4 c |