硬件方面:IS62WV512169 g; o9 N) o0 U; P
软件方面:MDK
" }/ {9 T: x6 [; v# p# s& x' ^7 x' ?
修改startup_xxx.s 堆栈地址并在__main函数前初始化FSMC
0 R: W* D! T" n- a; o" @修改.sct文件(分散加载),添加外部SRAM的使用空间及大小。
A! w# q8 U* Q具体步骤如下:, C3 V$ P4 ` N& i5 t
- //startup_stm32f407xx.s部分
0 P, ^5 _- J x: @) D, P& p - ; Vector Table Mapped to Address 0 at Reset& l" F3 p1 L; H" w* Z6 r4 `
- AREA RESET, DATA, READONLY4 t2 b3 H- B) G
- EXPORT __Vectors
. C$ u" [6 d; e( A7 [9 s - EXPORT __Vectors_End
. x4 P$ x& g! E - EXPORT __Vectors_Size4 p- z8 J0 f/ H% h* s3 B t x
-
4 Y% p- `1 }/ z$ @* W) X$ \ - __Vectors DCD 0x20000100 ; Top of Stack8 W4 Y. m6 A+ S
- DCD Reset_Handler ; Reset Handler
9 U1 W5 P$ b8 q9 {( | - DCD NMI_Handler ; NMI Handler! E1 g+ {' T6 j J1 z
- ...
% T; X2 o. r* [* W% _/ n" J - .... D$ q! x4 {2 L, z# l
- ...* k( `( l. { X+ g
- IMPORT SystemInit & J5 Z% J+ `3 E
- IMPORT FSMC_SRAM_Init
9 M) m3 w# V2 A: W - IMPORT __main" ]: g g4 D9 a- k% U5 `& S
- LDR R0, =SystemInit1 @4 ]4 M5 {1 C& \% U
- BLX R0
, [# L2 W0 D4 l R% k; c6 v3 Z( |( w - LDR R0, =FSMC_SRAM_Init
1 [# K0 U2 T$ G' {; K4 M - BLX R0 4 u9 {# U9 ~ I, M- Y
- LDR R0, =__main/ d- P6 B; P; g. M9 z
- BX R0
6 {4 ~9 j8 Y1 @2 z' R4 g1 j/ H - ENDP8 x# Q6 ?- w! k* L) }7 w# E8 V& V
复制代码 0x20000100 替换 __initial_sp9 F7 ]+ J( ?4 m7 R* e0 E3 F
添加IMPORT FSMC_SRAM_Init
6 g% ?, A! |. R o/ ]2 S6 _1 G添加LDR R0, =FSMC_SRAM_Init和LX R0。敲黑板这两句必须在__main前面" h$ [) Q( v# R7 @! n, p% z8 m
这里的FSMC_SRAM_Init函数是使用正点原子探索者407寄存器版本的,里面所使用的变量只能是创建在内部SRAM哦,一旦用了外部SRAM就会触发HardFault,后果你懂的。所以尽量使用寄存器来初始化配置FSMC。$ F9 w4 c4 x2 w! I3 Q
7 ~3 o9 U3 `3 h$ B
2 l5 H+ X; y0 {3 B接下来就是第二部分,配置内存分配空间
9 g9 g4 N2 m( H9 o/ Z$ J1 h- m按上图配置,要注意的是default一定要勾选,不然内存是不会分配到外部SRAM的。当然了你用__atrribute__来指定分配也是可以用的,但是有一个问题就是你不能初始化赋值,管你是非零还是零赋值,通通没用,原因何在,我也不知道。希望高人指点一二( w" T# `/ g, D5 N( t, E( L, H9 ?
# z. ~/ Y; v4 e/ A5 P% T5 E
5 R+ r# i1 l# a7 S& k2 F4 v之后就可以愉快的使用外部SRAM啦。8 V* r8 M3 Z3 F
编写代码的时候使用方式与内部SRAM无异。9 G9 j3 }( [) F3 z p7 T a: Y
不过速度嘛…肯定比使用内部SRAM要慢的,毕竟FSMC操作外部SRAM的速度就那么大。
( N% F. \ M+ @+ G4 b
B! G; n0 P: E* Q, _' r# Y0 V- K! p. P8 t \, F1 z
最后附上我改写后的纯寄存器版本的FSMC_SRAM_Init
: m3 k" b9 T8 b1 M' B0 u经测试能用在STM32F407上,其他芯片请自行修改。
/ @- z. r. S; V: \6 V1 d$ [% M, G1 L3 J- 1 g1 V# Y2 N8 j l) e/ \2 n
复制代码- void FSMC_SRAM_Init(void)
: |; u) f o4 m5 ~0 o9 ` - {6 ?: m$ ]2 V6 b$ ?# t5 k' `: D
- /*-- GPIOs Configuration -----------------------------------------------------*/- `" q& h# {8 R* P
- /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */
/ k2 Z% G9 ]& _; a" R - RCC->AHB1ENR |= 0x00000078;
8 c2 _$ O# x, e7 H0 M - 5 N+ o- j. Z) _. m% N# f/ w5 E! J
- //PD0,1,4,5,8~15 100M AF OUT_PP UP( @4 _0 A) \* C
- //PE0,1,7~15 100M AF OUT_PP UP! v4 a, w6 _. ?
- //PF0~5,12~15 100M AF OUT_PP UP
_9 m5 i9 x0 N - //PG0~5,10 100M AF OUT_PP UP' D. h( o5 l$ a$ ]
-
, g1 i& @: k s( e1 g) } - /* Connect PDx pins to FMC Alternate function */" \2 f. H# ^4 N- P/ r" ^
- GPIOD->AFR[0] = 0x00CC00CC;
) d0 i/ T5 Y# Z/ g' z! t! P - GPIOD->AFR[1] = 0xCCCCCCCC;; p. h- z( Q0 B* n
- /* Configure PDx pins in Alternate function mode */ 8 n" B2 w' x' f7 o6 n K0 Y/ Q
- GPIOD->MODER = 0xAAAA0A0A;, P4 B: K' w5 q) ~* X
- /* Configure PDx pins speed to 100 MHz */ $ r0 n1 d- X X1 e- V
- GPIOD->OSPEEDR = 0xFFFF0F0F;4 D8 y+ v0 }/ `7 \
- /* Configure PDx pins Output type to push-pull */
- H5 ^& q2 ~' d* A, N! T1 ] - GPIOD->OTYPER = 0x00000000;! Y4 V" A6 H$ F/ }: a. ?
- /* pull-up for PDx pins */
/ T7 W) U8 L% F* k9 ] - GPIOD->PUPDR = 0x55550505;# h! K2 S- O# Q/ f. h
- 6 g( |, \! }2 `: n& { R
- /* Connect PEx pins to FMC Alternate function */
( B4 q2 ~9 Y5 j( Z - GPIOE->AFR[0] = 0xC00000CC;# q4 Y, ^, ^0 ]0 v5 I
- GPIOE->AFR[1] = 0xCCCCCCCC;$ W! B1 W6 Y$ m+ Z3 k- K
- /* Configure PEx pins in Alternate function mode */ 8 z; N$ t) G! P
- GPIOE->MODER = 0xAAAA800A;/ U* v' C- b* y, [
- /* Configure PEx pins speed to 100 MHz */ . N. K( l( P& u7 Q( `7 J: M! r( _
- GPIOE->OSPEEDR = 0xFFFFC00F;
% p, h! T8 {" n% j - /* Configure PEx pins Output type to push-pull */
/ {% W3 J; p: J9 t# C/ T - GPIOE->OTYPER = 0x00000000;
( F3 }# c& S$ P* I% a% r* ^ - /* pull-up for PEx pins */ 2 p! G; a1 F2 F7 {$ z% w2 Q
- GPIOE->PUPDR = 0x55554005;
& m- U4 I. A* p7 z: b) T7 D -
- \7 C6 d6 M" a" m - /* Connect PFx pins to FMC Alternate function */" y: o5 }5 ~9 M5 j
- GPIOF->AFR[0] = 0x00CCCCCC;2 ]! m# I5 Z }) H$ Z6 L1 N
- GPIOF->AFR[1] = 0xCCCC0000;
( @& f/ G, I- O; V- O - /* Configure PFx pins in Alternate function mode */ : D! C5 |1 ^( u8 O/ K6 }
- GPIOF->MODER = 0xAA000AAA;' P$ F3 S0 l% S* G/ Q
- /* Configure PFx pins speed to 100 MHz */
& c' x- F7 S" R% B1 P" X - GPIOF->OSPEEDR = 0xFF000FFF;* E! K& o; ^4 S+ X& J: h5 N
- /* Configure PFx pins Output type to push-pull */
. H/ c( F* j1 o% o - GPIOF->OTYPER = 0x00000000;
" J. z: p4 L9 | - /* pull-up for PFx pins */ 8 t- Z I2 z1 ~3 n
- GPIOF->PUPDR = 0x55000555;
# F+ Y; X- d" F5 `: N% L - : C' w7 {$ {6 h, {" A3 ?- d
- /* Connect PGx pins to FMC Alternate function */
9 f' u# n$ x8 k5 Y* z+ k - GPIOG->AFR[0] = 0x00CCCCCC;9 q) \6 B: Z) M6 D& O& c
- GPIOG->AFR[1] = 0x00000C00;
% ?+ M7 B8 Q8 x9 h - /* Configure PGx pins in Alternate function mode */ z3 p" Q, s& V1 ^, `
- GPIOG->MODER = 0x00200AAA;+ c1 B! U( L( w o' z
- /* Configure PGx pins speed to 100 MHz */ & |& `; r/ {# T
- GPIOG->OSPEEDR = 0x00300FFF;7 s8 N; j( R( a1 T: [2 C& Y
- /* Configure PGx pins Output type to push-pull */ 1 M2 W8 s$ U* M
- GPIOG->OTYPER = 0x00000000;: N' b' a: I& P$ B' G
- /* pull-up for PGx pins */ ( @( {1 H; M) I: s0 A' }
- GPIOG->PUPDR = 0x00100555;
, Y- |" [# `' a, ?" D% r -
% F8 j; G1 D* | - /*-- FMC/FSMC Configuration --------------------------------------------------*/1 M2 e' L M1 ^% i _7 a
- /* Enable the FMC/FSMC interface clock */% G5 K/ Y+ n _2 v. D
- RCC->AHB3ENR |= 0x00000001;
& z. i7 x: k1 l( z1 i* c -
7 x2 Y: R& [, d' Q9 S$ ?$ O g6 C/ B - //寄存器清零' Z! \5 `% Z" ]1 o# z1 z2 ?8 W# G
- //bank1有NE1~4,每一个有一个BCR+TCR,所以总共八个寄存器。8 X0 q9 L" E1 Q* v! s0 f
- //这里我们使用NE3 ,也就对应BTCR[4],[5]。
* y- }+ c# ]; x - FSMC_Bank1->BTCR[4]=0X00000000;
9 I% n" R& X: R' s - FSMC_Bank1->BTCR[5]=0X00000000;9 V; E% S' }" c+ O" y8 G4 k2 \
- FSMC_Bank1E->BWTR[4]=0X00000000;
+ E* d- x* }7 d' I- ?) O - //操作BCR寄存器 使用异步模式,模式A(读写共用一个时序寄存器)
* L3 b; Q, A7 ^: x. |% x7 Z- H9 D - //BTCR[偶数]:BCR寄存器;BTCR[奇数]:BTR寄存器' f* M7 X0 E, J
- FSMC_Bank1->BTCR[4]|=1<<12;//存储器写使能% F6 j9 B9 l" [; L
- FSMC_Bank1->BTCR[4]|=1<<4; //存储器数据宽度为16bit
( T0 N4 o& V2 j6 @0 h - //操作BTR寄存器 (HCLK=168M, 1个HCLK=6ns
# d1 {# c3 M8 p- n - FSMC_Bank1->BTCR[5]|=8<<8; //数据保持时间(DATAST)为9个HCLK 6*9=54ns
' U/ Q, K8 Y7 H6 z& K6 @ - FSMC_Bank1->BTCR[5]|=0<<4; //地址保持时间(ADDHLD)未用到
" O6 ^1 X) x' o: j) p6 d - FSMC_Bank1->BTCR[5]|=0<<0; //地址建立时间(ADDSET)为0个HCLK 0ns 7 j7 k- m' a0 T0 Y+ u4 v* g8 w# z1 ?
- //闪存写时序寄存器 8 t9 g& m1 L, z$ I) N6 z
- FSMC_Bank1E->BWTR[4]=0x0FFFFFFF;//默认值/ B6 h8 W) j) F. D9 q1 h3 W
- //使能BANK1区域3
% R! g- f- A2 E4 N7 ~$ O1 `7 O2 q - FSMC_Bank1->BTCR[4]|=1<<0;
* h6 C& f6 d; c) _' W; a" y - }
/ m5 `% o9 ?5 e9 M* ^ - ————————————————
' w/ j2 }0 Q& H+ @7 Z/ o0 P: T
复制代码
; ~* t. n S \" X, f2 B6 u |