硬件方面:IS62WV51216" _$ a a9 G: ~' ?
软件方面:MDK& }& c+ \2 C" X/ z- e0 K; g
# M ]3 O$ U% A9 y3 [修改startup_xxx.s 堆栈地址并在__main函数前初始化FSMC- ]( \! x8 D$ \
修改.sct文件(分散加载),添加外部SRAM的使用空间及大小。
7 a' K5 E5 M, m6 [具体步骤如下:0 R# P `6 h, X0 X0 n; G
- //startup_stm32f407xx.s部分
* {6 k9 l. B L1 |! y4 z- a - ; Vector Table Mapped to Address 0 at Reset
4 h) X k; D' [ - AREA RESET, DATA, READONLY( t% e9 E. z6 p
- EXPORT __Vectors
" c! J s3 m0 p8 k* Q& v' c( V - EXPORT __Vectors_End
6 i( |- B1 S7 e2 X - EXPORT __Vectors_Size
- g" B$ M& h B( w6 T: Y -
) l7 e7 l3 Z) C/ W& i - __Vectors DCD 0x20000100 ; Top of Stack
: _# A$ o9 M: k5 Y - DCD Reset_Handler ; Reset Handler: F+ x4 U( ?0 X! ~) {! y
- DCD NMI_Handler ; NMI Handler
7 E# O8 G% Q7 f3 k6 r - ...
9 H; i( i- r" l/ p* t8 U - ...! B4 ?8 X- [, o% C8 k: }: a. z
- ...
' ]) k8 E' H4 _ - IMPORT SystemInit # B8 C4 G! i8 }, W
- IMPORT FSMC_SRAM_Init
7 e* }' R9 T2 ^3 e' t/ h( g - IMPORT __main
1 Y* F2 U, j( p' ]9 _ - LDR R0, =SystemInit8 }" I2 z) Q: }- C! ~
- BLX R0. w0 n, R, j: G& [
- LDR R0, =FSMC_SRAM_Init
& {$ P! ^5 F& e, A' ] j' e - BLX R0 , q+ t5 m8 ]: ?* Z
- LDR R0, =__main
7 @/ R" v1 y7 G M+ H& Y - BX R0- d1 V! T3 {# I1 Q8 V- l
- ENDP- n V8 D! Y& v0 C1 F; s4 {
复制代码 0x20000100 替换 __initial_sp/ {( R4 c) [3 I5 } V' Z
添加IMPORT FSMC_SRAM_Init
3 C7 J& } i8 `9 b( q+ ~$ Z添加LDR R0, =FSMC_SRAM_Init和LX R0。敲黑板这两句必须在__main前面) B$ C* B* r- y
这里的FSMC_SRAM_Init函数是使用正点原子探索者407寄存器版本的,里面所使用的变量只能是创建在内部SRAM哦,一旦用了外部SRAM就会触发HardFault,后果你懂的。所以尽量使用寄存器来初始化配置FSMC。( V; }/ S2 {9 j% o6 ^: R, ?. J
- l$ t, w! n; s: y, K' E$ K. t
( Y B* j" }. O7 R3 M( t8 {, S. z
接下来就是第二部分,配置内存分配空间
) m) Y3 @) l3 x' j按上图配置,要注意的是default一定要勾选,不然内存是不会分配到外部SRAM的。当然了你用__atrribute__来指定分配也是可以用的,但是有一个问题就是你不能初始化赋值,管你是非零还是零赋值,通通没用,原因何在,我也不知道。希望高人指点一二
' j7 b. _2 A% i6 ]: N# W- w9 S: T2 p
- z9 v2 L) I2 i3 D" f w+ R# o' a# k4 d
之后就可以愉快的使用外部SRAM啦。
g+ J/ U* b" j( v4 _. N6 o编写代码的时候使用方式与内部SRAM无异。
4 |5 j2 W. q0 r不过速度嘛…肯定比使用内部SRAM要慢的,毕竟FSMC操作外部SRAM的速度就那么大。
, Q9 O6 ^2 u1 V7 c M9 M3 [
' Q4 i" @( K: \$ s- z+ L6 I! {# \( h8 K" q
最后附上我改写后的纯寄存器版本的FSMC_SRAM_Init" ^3 u3 V# v$ C5 M V
经测试能用在STM32F407上,其他芯片请自行修改。& |: Q1 i1 z! P" V
- void FSMC_SRAM_Init(void)
' g+ R7 V0 X( z8 E& k9 t - {
" v( }# K2 T1 [, i - /*-- GPIOs Configuration -----------------------------------------------------*/# h- J0 I2 R$ R5 [
- /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */
+ c9 w5 X; c9 C* w5 b - RCC->AHB1ENR |= 0x00000078;
# f& X) d1 _# N -
% }" u: x4 M, ~) [5 ] - //PD0,1,4,5,8~15 100M AF OUT_PP UP
9 l6 w- z3 v9 n2 q - //PE0,1,7~15 100M AF OUT_PP UP
) C: h; ]7 G0 W# X. [5 ` - //PF0~5,12~15 100M AF OUT_PP UP8 [9 Q% ]4 y. G4 B- {
- //PG0~5,10 100M AF OUT_PP UP
# w9 i q" s% ^, }1 G - 3 v" U3 p3 l! @$ h) C
- /* Connect PDx pins to FMC Alternate function */: S0 H4 S1 o0 @
- GPIOD->AFR[0] = 0x00CC00CC;
3 q* I7 v; b; V% z+ s* R - GPIOD->AFR[1] = 0xCCCCCCCC;
# Q' o/ c3 \" D$ E, D9 U) Z1 B2 K; u4 e - /* Configure PDx pins in Alternate function mode */ . X$ d& z+ \! Z, i( }, c
- GPIOD->MODER = 0xAAAA0A0A;
+ A: t- T$ O+ [' i9 |+ Y7 F - /* Configure PDx pins speed to 100 MHz */
$ v2 o0 J! i$ G, f% A% f - GPIOD->OSPEEDR = 0xFFFF0F0F;0 u# _; o4 J) w: ^! E
- /* Configure PDx pins Output type to push-pull */
# U4 u1 h4 g1 q: }6 Z" B - GPIOD->OTYPER = 0x00000000;( K) O/ \$ B# S2 H5 z' x
- /* pull-up for PDx pins */ % i$ m$ T1 h* u5 b, X
- GPIOD->PUPDR = 0x55550505;
`) V2 E, t8 Y. u" G D -
) v$ z X( l- v0 D6 w# w - /* Connect PEx pins to FMC Alternate function */
/ G1 \- { S9 I( b) d - GPIOE->AFR[0] = 0xC00000CC;
, I2 o& _+ [! o: B - GPIOE->AFR[1] = 0xCCCCCCCC;" e) ~6 J- V9 _2 _6 }# m
- /* Configure PEx pins in Alternate function mode */ 9 ?4 D/ U9 w( l! i( ]1 o$ e
- GPIOE->MODER = 0xAAAA800A;1 f9 D+ l# p! G5 h6 A2 E
- /* Configure PEx pins speed to 100 MHz */ " J5 ]: t; @; q
- GPIOE->OSPEEDR = 0xFFFFC00F;; A2 K* `6 \7 m0 d
- /* Configure PEx pins Output type to push-pull */ 6 z" S1 Y# b. b c3 ~; w/ v! G9 Y
- GPIOE->OTYPER = 0x00000000;1 _+ l4 \3 @; l1 N7 P1 ]% e
- /* pull-up for PEx pins */ + Y0 n5 ]( S* d% F R
- GPIOE->PUPDR = 0x55554005;% }+ p8 y7 v, ~& X
-
2 Y+ v; a5 [; W6 Z8 A1 x9 W) F: v1 R - /* Connect PFx pins to FMC Alternate function */
3 N4 b' h) J$ a% z7 K - GPIOF->AFR[0] = 0x00CCCCCC;
( S. A. g2 H0 W; e; k0 b - GPIOF->AFR[1] = 0xCCCC0000;
% n2 B+ W1 s# H9 U1 a0 K7 l# F1 W - /* Configure PFx pins in Alternate function mode */ - e$ C. S M" {+ S
- GPIOF->MODER = 0xAA000AAA;7 Z Z+ S, H' z& K
- /* Configure PFx pins speed to 100 MHz */
. K, `# u4 Z+ P7 H u - GPIOF->OSPEEDR = 0xFF000FFF;) M# y2 Q1 N5 m& K7 F6 o
- /* Configure PFx pins Output type to push-pull */
7 N' F4 |" F e0 O ] - GPIOF->OTYPER = 0x00000000;; G5 z. h# [# J: `3 h+ }
- /* pull-up for PFx pins */ / h# R$ N' P' V
- GPIOF->PUPDR = 0x55000555;7 E& e2 S% u: s+ C0 h# ^+ w
- 8 d5 D& q0 j" U
- /* Connect PGx pins to FMC Alternate function */
3 [+ n- Q2 o+ X$ a5 m! |9 H - GPIOG->AFR[0] = 0x00CCCCCC;( ~* C2 u' F7 L+ w& N; o
- GPIOG->AFR[1] = 0x00000C00;
; U1 p( L: z8 X7 j+ U+ @' s - /* Configure PGx pins in Alternate function mode */ ' E$ D+ z5 U# [/ c4 p9 a1 S" O; w
- GPIOG->MODER = 0x00200AAA;9 m, s J! u# G
- /* Configure PGx pins speed to 100 MHz */
! W2 {' Z4 [8 T - GPIOG->OSPEEDR = 0x00300FFF;
& Q( g) P; J. K, {' Z# ` - /* Configure PGx pins Output type to push-pull */
0 `% ^5 `1 Y0 ~6 _; E* C4 j5 ^ - GPIOG->OTYPER = 0x00000000;0 g0 u& ^- p! a0 ^
- /* pull-up for PGx pins */
& T6 P7 r% H; e - GPIOG->PUPDR = 0x00100555;
% e ~5 P# P6 b; X -
0 C! r; [6 M% n, c+ m - /*-- FMC/FSMC Configuration --------------------------------------------------*/
) d+ ~$ U% p0 V! P - /* Enable the FMC/FSMC interface clock */
0 w8 R& `- [7 O4 p5 N& C- n - RCC->AHB3ENR |= 0x00000001;
; E+ ?2 u# l/ z9 {' J& q - 4 }0 S! i3 o, g
- //寄存器清零
" s" T! A% i, k: } ] - //bank1有NE1~4,每一个有一个BCR+TCR,所以总共八个寄存器。
/ E, H# z; k* i9 g. S6 a; j4 x# y) N - //这里我们使用NE3 ,也就对应BTCR[4],[5]。
/ k+ } }( S# f: I* |+ O+ h/ ^ - FSMC_Bank1->BTCR[4]=0X00000000;* P' g' B5 w4 J; U6 f4 J# Z
- FSMC_Bank1->BTCR[5]=0X00000000;
' X1 \: h* A. m: A; r7 L/ H - FSMC_Bank1E->BWTR[4]=0X00000000;
% c+ V/ ?' `# d1 ~) K* c8 \ |# D - //操作BCR寄存器 使用异步模式,模式A(读写共用一个时序寄存器)' P: c( F8 B1 r
- //BTCR[偶数]:BCR寄存器;BTCR[奇数]:BTR寄存器) c% [/ w; v- Q
- FSMC_Bank1->BTCR[4]|=1<<12;//存储器写使能
$ F/ k! }$ Q9 p. e+ i# a3 W" L5 i - FSMC_Bank1->BTCR[4]|=1<<4; //存储器数据宽度为16bit & p1 h y6 y) C! ~3 Q& C
- //操作BTR寄存器 (HCLK=168M, 1个HCLK=6ns 5 ~4 B% [- F+ [. C
- FSMC_Bank1->BTCR[5]|=8<<8; //数据保持时间(DATAST)为9个HCLK 6*9=54ns ~1 }. G: q6 n- ^- o: l9 j
- FSMC_Bank1->BTCR[5]|=0<<4; //地址保持时间(ADDHLD)未用到 # h" M& x# u$ I
- FSMC_Bank1->BTCR[5]|=0<<0; //地址建立时间(ADDSET)为0个HCLK 0ns 7 e: ?2 Z: o% ?+ k" F. @( y
- //闪存写时序寄存器 3 m' q& H+ G5 X5 b, l
- FSMC_Bank1E->BWTR[4]=0x0FFFFFFF;//默认值
! G! f) l/ Z, L) P' ^% U - //使能BANK1区域35 P9 F( F) D! X- n' T
- FSMC_Bank1->BTCR[4]|=1<<0;$ @' j3 }* [* G; L2 v$ J
- }& K) p; n2 A" B; }1 J1 p/ I
- ————————————————+ H& z D& f- ?( V1 X/ [- D+ y) `0 Q
复制代码
7 C" C& r4 j$ y5 Y |