硬件方面:IS62WV51216
. M6 Z9 J7 {' W软件方面:MDK: \: A1 w7 W8 l; ~5 Q6 q
/ e) p; Z& }1 c4 o1 w修改startup_xxx.s 堆栈地址并在__main函数前初始化FSMC
$ }+ A T) t; r9 h: V/ y修改.sct文件(分散加载),添加外部SRAM的使用空间及大小。, f% l( a; ^3 u4 \2 |8 x
具体步骤如下:
$ a3 b- E0 H' `2 p& W- //startup_stm32f407xx.s部分% N- l& ]7 K% p B4 j9 x0 i
- ; Vector Table Mapped to Address 0 at Reset
8 g+ k( }8 `& P: W5 M% q4 Y/ i - AREA RESET, DATA, READONLY+ ^" ~& _1 Y8 {# X) @7 ] u
- EXPORT __Vectors
1 w4 Q; {( Q4 |( S/ |, a+ g - EXPORT __Vectors_End
. I# H V9 D0 Q+ o - EXPORT __Vectors_Size s6 I( S! ~) X8 ]4 o6 k
-
! A/ L; W4 \ z! m - __Vectors DCD 0x20000100 ; Top of Stack+ L% B. l5 `) h1 [! ^( Z( P3 s4 I5 _
- DCD Reset_Handler ; Reset Handler' h/ N* a: ?+ z; E( D; F3 |2 @; w
- DCD NMI_Handler ; NMI Handler
, w" q% a! Q" N0 t2 l s1 | - ...& I" ?- d% |6 a8 w2 K$ J
- ...0 M/ V! v1 b3 u* j5 Q4 e
- ...
4 u2 ]# W6 f; A! | l. j$ l - IMPORT SystemInit 3 y7 P' H/ F" q2 l2 M
- IMPORT FSMC_SRAM_Init7 W/ h3 z* o: v0 p4 a5 I
- IMPORT __main( W0 h0 _8 g# [* C, _, ?1 }) H
- LDR R0, =SystemInit
; w/ M- t! }$ B" o4 Y - BLX R0* U; g7 @& W9 N" f- E
- LDR R0, =FSMC_SRAM_Init1 o6 z( l# h( ^" K" E
- BLX R0 : |( X, d9 i2 y5 t! _. h* J
- LDR R0, =__main' [0 p& n% Y% m
- BX R0/ u0 z( i0 J9 m1 F
- ENDP
& K4 j( O: r" c
复制代码 0x20000100 替换 __initial_sp
3 v: k9 B" s6 g+ S. B, s添加IMPORT FSMC_SRAM_Init
. y5 C0 f" C7 o! v) u R添加LDR R0, =FSMC_SRAM_Init和LX R0。敲黑板这两句必须在__main前面- b5 j; H7 W- B. V7 _& w8 g
这里的FSMC_SRAM_Init函数是使用正点原子探索者407寄存器版本的,里面所使用的变量只能是创建在内部SRAM哦,一旦用了外部SRAM就会触发HardFault,后果你懂的。所以尽量使用寄存器来初始化配置FSMC。9 H& j5 Z' o& R: a: Q4 r
; K% o; T2 l( O# L8 t3 k1 J6 b$ j- A" m2 }
接下来就是第二部分,配置内存分配空间
+ W2 K: H8 a z+ k7 L. U按上图配置,要注意的是default一定要勾选,不然内存是不会分配到外部SRAM的。当然了你用__atrribute__来指定分配也是可以用的,但是有一个问题就是你不能初始化赋值,管你是非零还是零赋值,通通没用,原因何在,我也不知道。希望高人指点一二( X* n+ F1 `' z3 |- `4 h% {$ }
7 k$ z2 Z @4 K1 b% W3 d7 C
# U9 g L: [5 T3 ]之后就可以愉快的使用外部SRAM啦。6 }# ?9 i4 q' I, R
编写代码的时候使用方式与内部SRAM无异。
! p g% F1 p, p" a/ s不过速度嘛…肯定比使用内部SRAM要慢的,毕竟FSMC操作外部SRAM的速度就那么大。
6 X6 m' ~/ I0 W' r$ e, Z: ~4 |( J0 [& E
: d' d/ i: `" \7 v9 ~* A$ i5 H7 \最后附上我改写后的纯寄存器版本的FSMC_SRAM_Init7 O% e; K+ `$ `' h2 A5 q# t
经测试能用在STM32F407上,其他芯片请自行修改。
5 o7 M# Y2 Q$ [1 ~( D- / Q% }. Z# o6 {: G7 [$ C! V
复制代码- void FSMC_SRAM_Init(void)" I5 U+ P& O3 H) l1 `8 t1 u8 n
- {
+ p0 t% K+ u2 r- K" g - /*-- GPIOs Configuration -----------------------------------------------------*/
3 ~6 m0 |: S5 o" [0 }$ Y% V - /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */
|, ^! E I& h) @$ f* w5 |% x - RCC->AHB1ENR |= 0x00000078;% e" Q" R" y: A5 }7 K; u
- 9 s% N7 A. ~! a" t
- //PD0,1,4,5,8~15 100M AF OUT_PP UP; y0 U$ C% f8 X; j/ P
- //PE0,1,7~15 100M AF OUT_PP UP9 ]/ K8 p$ Y. m" T/ h
- //PF0~5,12~15 100M AF OUT_PP UP
5 k) |7 W+ f% l$ W - //PG0~5,10 100M AF OUT_PP UP& h( w6 q3 l( @9 ?5 r" G4 z& L
- ; r* n! \7 O0 A2 O5 _, F, x, x
- /* Connect PDx pins to FMC Alternate function */ s2 J0 Z/ A& h/ e
- GPIOD->AFR[0] = 0x00CC00CC;! w# k* d- m5 D7 I+ U( P
- GPIOD->AFR[1] = 0xCCCCCCCC;
9 o# v$ ~ ~- D# h, f - /* Configure PDx pins in Alternate function mode */ * W3 z" b; g7 L8 @4 J2 Q( H
- GPIOD->MODER = 0xAAAA0A0A;, b4 P7 e2 z) c' M7 }
- /* Configure PDx pins speed to 100 MHz */ * m x, q# Z* o; l! J3 ^& @ M
- GPIOD->OSPEEDR = 0xFFFF0F0F;
$ }% ~- k9 U: [- Z8 ~5 s! v4 P - /* Configure PDx pins Output type to push-pull */ % v6 z, N/ D1 z+ J* _9 A+ V3 L5 D
- GPIOD->OTYPER = 0x00000000;
( c4 {% K8 t& j; t+ t - /* pull-up for PDx pins */ : N3 U* q! x- s% U
- GPIOD->PUPDR = 0x55550505;" R4 b9 P& }' M9 e2 W
-
. ^. W5 j# v* ], y( B% ]4 y) | - /* Connect PEx pins to FMC Alternate function */
% q) P7 Z9 c8 ~ W - GPIOE->AFR[0] = 0xC00000CC;( ~. F7 z L B
- GPIOE->AFR[1] = 0xCCCCCCCC;( J5 G1 q/ ]7 r; Q+ L: Q! T6 Z
- /* Configure PEx pins in Alternate function mode */ : e5 ~! S, k' z6 t4 l& u
- GPIOE->MODER = 0xAAAA800A;
. D, Q% Q7 _: m( Z8 ] ` I& @ - /* Configure PEx pins speed to 100 MHz */ $ b$ Q2 K! J6 L+ S( g- ~7 b- N
- GPIOE->OSPEEDR = 0xFFFFC00F;
8 V; S+ ?/ c: M B6 b) s - /* Configure PEx pins Output type to push-pull */
$ x6 p" m" A6 g. d - GPIOE->OTYPER = 0x00000000;
$ x4 o9 P3 n( @) D6 [( g* b - /* pull-up for PEx pins */ / E# [& R) d6 Z4 F6 t7 Y
- GPIOE->PUPDR = 0x55554005;
2 Y3 v% ?4 h3 X ^8 Q7 l -
) k( j H. B3 }. U6 Z4 a* x - /* Connect PFx pins to FMC Alternate function */2 f1 p6 C6 w2 O$ T1 \) O7 q
- GPIOF->AFR[0] = 0x00CCCCCC;
# V5 B/ e W9 W% F$ C1 ~- p - GPIOF->AFR[1] = 0xCCCC0000;; p8 \1 a5 G2 d' E6 B
- /* Configure PFx pins in Alternate function mode */
; n. T; x) E. |1 F3 ^6 |$ N - GPIOF->MODER = 0xAA000AAA;
Y. H" v( a& m2 x; e [ - /* Configure PFx pins speed to 100 MHz */ & u0 T& k5 x) b; R
- GPIOF->OSPEEDR = 0xFF000FFF;0 a# Q$ H( T0 f8 J9 V( Y( ?
- /* Configure PFx pins Output type to push-pull */ 8 u4 D) Y6 M3 f2 y6 L+ c0 V6 m7 w
- GPIOF->OTYPER = 0x00000000;7 s' m! l% ^6 w; `$ r( \5 B, P
- /* pull-up for PFx pins */
2 H! G' j( }0 }! Y" C8 A0 z - GPIOF->PUPDR = 0x55000555;; a' I W( V5 P( }' k$ }7 G% L
-
* M- a. T; f6 G- M' t3 h - /* Connect PGx pins to FMC Alternate function */+ S5 C X0 A. o! d" k
- GPIOG->AFR[0] = 0x00CCCCCC;. Q$ \; C' o2 w9 U. H
- GPIOG->AFR[1] = 0x00000C00;
: {: p/ S$ r, z x0 j- m8 h - /* Configure PGx pins in Alternate function mode */
- ^9 i& k0 L2 t - GPIOG->MODER = 0x00200AAA;
" j$ ?" F. I( r# ^ P. E+ o: L - /* Configure PGx pins speed to 100 MHz */
6 U7 \8 v z# E - GPIOG->OSPEEDR = 0x00300FFF;
) D9 e7 |/ v6 A0 x8 O+ j3 l - /* Configure PGx pins Output type to push-pull */ ' x: M/ b3 ~/ f. R
- GPIOG->OTYPER = 0x00000000;$ ?6 P2 d7 \3 C$ G* n" ~& [
- /* pull-up for PGx pins */
; {' ^2 H2 q5 w6 r" A - GPIOG->PUPDR = 0x00100555;
. W6 F9 y5 S' p - C3 P! q, G- b# M) Z
- /*-- FMC/FSMC Configuration --------------------------------------------------*/3 w9 _; q4 w2 U
- /* Enable the FMC/FSMC interface clock */
) o! P, s+ Y2 S* e7 A - RCC->AHB3ENR |= 0x00000001;! q) L! X9 }; V$ b: i# |) Y' n; P1 C+ p
- % D1 Y" w5 p3 R% J w, o( j% k
- //寄存器清零* f1 T" @1 ], O2 n
- //bank1有NE1~4,每一个有一个BCR+TCR,所以总共八个寄存器。
3 y2 \# t" ?! s9 n - //这里我们使用NE3 ,也就对应BTCR[4],[5]。 5 C7 m2 @2 T) B$ _4 W, c4 V
- FSMC_Bank1->BTCR[4]=0X00000000;
: S; Y+ |5 t( J: A9 T6 {# R - FSMC_Bank1->BTCR[5]=0X00000000;
5 d' D/ w; U7 W1 B1 x7 S - FSMC_Bank1E->BWTR[4]=0X00000000;8 I, L0 Y* _& s* a7 H% G
- //操作BCR寄存器 使用异步模式,模式A(读写共用一个时序寄存器)
, s* C# K( Y5 d( `3 {6 n R - //BTCR[偶数]:BCR寄存器;BTCR[奇数]:BTR寄存器
5 N! g% Y8 f6 \. h0 h - FSMC_Bank1->BTCR[4]|=1<<12;//存储器写使能
6 P) J1 v" I9 \; x* ? - FSMC_Bank1->BTCR[4]|=1<<4; //存储器数据宽度为16bit % O& ?% L' [5 O, U d
- //操作BTR寄存器 (HCLK=168M, 1个HCLK=6ns
; u9 g' e" t7 Q - FSMC_Bank1->BTCR[5]|=8<<8; //数据保持时间(DATAST)为9个HCLK 6*9=54ns
' D# s H9 U: P7 u$ Q - FSMC_Bank1->BTCR[5]|=0<<4; //地址保持时间(ADDHLD)未用到 0 t" V6 Q Z/ _) s* _5 _: x
- FSMC_Bank1->BTCR[5]|=0<<0; //地址建立时间(ADDSET)为0个HCLK 0ns
0 n8 F [' Y4 O - //闪存写时序寄存器 7 y( L0 [5 c7 c# P
- FSMC_Bank1E->BWTR[4]=0x0FFFFFFF;//默认值+ J1 r! e6 m; P* _
- //使能BANK1区域3" Y- h, A% o( F
- FSMC_Bank1->BTCR[4]|=1<<0;
& j- k9 ]3 C1 I7 m. K+ R. _% t - }
0 j4 V; l% ?$ N& _% _! Q( V - ————————————————( H ]' L9 N0 Q. j3 \, n
复制代码
2 z( @0 t9 A+ [* L7 v3 e0 U) a: Q. E |