主要内容:
& h3 [& y; ], j& M {& g; d1) IS62WV51216简介;5 |/ Q8 I0 z, {% P, S
2) FSMC简介及相关寄存器介绍;1 R8 L' H% F0 ^7 D: ?0 Q
3) 相关实验代码解读。
: q6 X" A% m ~1 c/ y1 |% V硬件连接:% v" i; \2 i; O" W/ b7 m' Z5 t
IS62WV51216原理图如下所示,具体连接关系为:
. Q4 u; W+ E% c1 x- c, z# O/ F3 d7 qA[0:18]接FMSC_A[0:18];D[0:15]接FSMC_D[0:15];UB接FSMC_NBL1;LB接FSMC_NBL0;OE接FSMC_OE;WE接FSMC_WE;CS接FSMC_NE3。( A$ t& c& f8 q" [( [4 {/ v& a
2 j- w/ M- q* K1 p0 N% W
! Q/ d7 r' v2 g* u' C
L& J- p+ J1 q0 n实验功能:程序开启后,按下KEY0键,测试外部SRAM容量大小并发送至串口端;按下KEY1键,显示预存在外部SRAM的数据。DS0指示程序运行状态。( Y% X- d: z/ F! {; p
+ J* K& |' x. p" T+ P4 Z: v' ^
1. IS62WV51216简介! z n! c0 H. \ s0 r
1.1 IS62WV51216是ISSI(Integrated Silicon Solution, Inc)公司生产的一颗16位宽512K(512*16,即1M字节)容量的CMOS静态内存(SRAM)芯片。/ F2 d6 ^" s) c
7 K% T& P! X, N$ i( A4 B1.2 特点
# n* p$ z d, B D9 W1) 高速。具有45ns/55ns访问速度(开发版采用55ns型号);! U0 P' C! G$ u- a! P( \$ u
2) 低功耗。操作时:36mW;待机时:12uW;
# y. C9 [9 [! L6 Y o9 G3) 兼容TTL电平,兼容5V电压;
3 {" r6 I) i1 r6 d6 L- H* O% l4) 全静态操作,不需要刷新和时钟电路;# y' N( m- [5 o; X2 Y! F
5) 三态输出;
8 |' w+ w5 t$ A. k2 `& H V1 c6) 字节控制功能。支持高/低字节控制。
" s; m7 Q) ]/ e+ D0 b" d3 N5 y2 m0 C: j# b( {/ m
1.3 框图. s3 M) r$ R2 j D# v. C9 d
图中A0~18为地址线,总共19根地址线(即2^19=512K,1K=1024);. n8 ^3 w! ~9 y& l
I/O0~15为数据线,总共16根数据线;
) r% A9 Q" M6 O& e' L: {5 [CS2和CS1都是片选信号,CS2是高电平有效,CS1是低电平有效(开发板采用CS1);* }, ?9 U& B% ~ Q' e
OE是输出使能信号(读信号);6 f' Q9 v: Q* r2 h1 e5 _
WE为写使能信号;
( j. E+ R$ I1 O, s; S3 CUB和LB分别是高字节控制和低字节控制信号(设0有效,设1无效)。
2 H. {' ?+ ?9 y" W# c5 X& ^/ s! u
6 d4 |2 u/ I1 I- j1 E
+ _, x, ]9 t- [; l1.4 IS62WV51216读时序4 \% O/ i6 h7 o. J5 W
IS62WV51216芯片的8080并口读时序如下图所示:2 J, v4 W" t1 ~4 E o: O9 O. o2 v
重点时序:读周期时间(tRC);地址建立时间(tAA);OE建立时间(tDOE)。
! v: U! L2 \9 B. N) C& ^开发板使用55ns的IS62WV51216,tRC=55ns,tAA=55ns(Max),tDOE=25ns(Max)。, s* ]4 J4 A% c5 p' f
6 m3 v8 G" ~# N; c
L$ i- p Z/ e% p6 b9 z
: b a) V" s0 p" m) i" C1.5 IS62WV51216写时序
8 a K9 l0 z* D [% L3 UIS62WV51216芯片的8080并口写时序如下图所示:
% A( [7 T- [) M& j0 a& e; A% m" o重点时序:写周期时间(tWC),地址建立时间(tSA),WE脉宽(tPWE)。, }$ a2 A9 p4 x! v& m
开发板使用55ns的IS62WV51216,tWC=55ns,tSA=0ns,tPWE=45ns(min)。1 G7 T9 z+ t5 W0 q9 L1 y6 f6 o: x
0 \ ~- ^9 S5 O' I' U
+ t- ~' }4 v2 V7 y5 G5 O* G# C0 V: m V9 M
2. FSMC简介3 L3 P6 t Q4 u7 k/ c- O. C
FSMC,即灵活的静态存储控制器,能够与同步或异步存储器和16位PC存储器卡连接,STM32的FSMC接口支持包括SRAM、NAND FLASH、NOR FLASH和PSRAM等存储器(不支持SDRAM)。FSMC的框图如下图所示:$ h6 t) X. D8 X
1 v C1 w; u* X) a5 |7 k, q& l
/ ^2 ], w' j+ R4 p# J$ B
) o5 |# o# C3 K3 `' _1 h' R4 a2.1 FSMC驱动IS62WV51216原理
4 g4 _' y0 M! ~% z# MFSMC驱动外部SRAM时,外部SRAM的控制一般有:
, j% }8 T* A" e, W% L5 C$ r1) 地址线(如A0~A25);
! S/ O! j I! p$ l2 X8 u2) 数据线(如D0~D15);
9 k' v2 K. d j( A+ P& E3) 写信号(WE,即WR);3 m; r' X$ M% V* Z* H a+ |
4) 读信号(OE,即RD);0 r* L3 I6 T Z" Z: ^) I9 U, d
5) 片选信号(CS);1 X7 H) U; P* @* c, Q) u @
6) 如果SRAM支持字节控制,还有UB/LB信号。. ~3 T8 ~5 ?) H1 y1 A
IS62WV51216的信号包括:$ m+ S% l/ y9 Z2 F; }
1) 地址线A0~A18;
. j( \. l* s# H3 @2) 数据线I/O0~I/O15;
- W9 e/ U! A+ v* l3) 写信号WE;
: x S" @" {' W i6 v0 D4) 读信号OE;6 y/ r" z% v7 K; u! j7 B8 A
5) 片选信号CS;
- F" V8 Q4 `% ^5 j3 |6) 字节控制UB、LB等。) D$ W; G8 e/ \% H
将这些信号依次连接STM32 FSMC接口的A0-A18、D0-D15、WE、OE、CS、UB、LB等信号即可。& |4 ]* @8 N& i& {. b& F
- E+ I [; h" {& P2 U+ M! D2.2 NOR / PSRAM外设接口
. `" B6 ] m0 D" fSTM32的FSMC支持8/16位数据宽度,我们这里用到的SRAM是16位宽度的,所以在设置的时候,选择16位宽就OK了。FSMC的外部设备地址映像,STM32的FSMC将外部存储器划分为固定大小为256M字节的四个存储块(注意每个块的起始地址!)。+ h! h. o! V8 B7 B, f
. n( u3 o; X7 C
& J Z4 {2 [5 t- [/ `% _+ o* [% N- M1 w, u* l2 w5 x* N
2.3 NOR / PSRAM存储块1 操作简介
. t7 ~4 j) F+ Q6 ?STM32的FSMC存储块1(Bank1)用于驱动NOR FLASH/SRAM/PSRAM,被分为4个区,每个区管理64M字节空间,每个区都有独立的寄存器对所连接的存储器进行配置。Bank1的256M字节空间由28根地址线(HADDR[27:0])寻址。8 a2 A$ _" ?3 z& m
这里HADDR,是内部AHB地址总线,其中,HADDR[25:0]来自外部存储器地址FSMC_A[25:0],而HADDR[26:27]对4个区进行寻址(不能直接设置,只能选择片选间接设置)。如下表所示:
0 m: [. i6 E6 }0 v: k* G! q9 R3 ?' j4 ?$ E" P; [0 m8 E
% l( q5 H6 [$ [6 v
) `$ v0 I& p, G% {6 @' W8 @
注意!2 Q. }% d) g [6 S
当Bank1接的是16位宽度存储器的时候:HADDR[25:1]——FSMC_A[24:0](右移一位对齐),
3 Z/ M( j, Q! a2 L当Bank1接的是8位宽度存储器的时候:HADDR[25:0]——FSMC_A[25:0]," s5 r: O+ m4 Y# y6 @: E
不论外部接8位/16位宽设备,FSMC_A[0]永远接在外部设备地址A[0]。
" P4 r; \* c4 h6 f8 [. N: s5 R
% p" ?! o& |5 H2.4 NOR PSRAM存储块1 访问模式7 g! k6 P& H' S# d0 P
STM32的FSMC存储块1 支持的异步突发访问模式包括:模式1、模式A~D等多种时序模型,驱动SRAM时一般使用模式1或者模式 A,这里使用模式A来驱动SRAM,其他模式说明详见:STM32中文参考手册-FSMC章节。
: x; _, Q! M- V4 t# `* K2 ]5 Z* z3 P" x+ z, q; U
+ R" y f; W/ Q, d' `9 S- l; F
- O* s+ N" \- d4 L模式A支持读写时序分开设置!(可针对一些读写时序不一样的设备分开设置),+ C' Y; E$ Z( D+ f9 c
对STM32F4仅写时序DATAST需要+1(F1按上图要求即可)。
, Y3 T8 I1 |- e w: h4 Q3 | a, i8 u. D$ Q
2.5 FSMC寄存器介绍
( I9 m' E0 }) R! U9 g$ L4 d对于NOR FLASH/PSRAM控制器(存储块1),通过FSMC_BCRx、FSMC_BTRx和FSMC_BWTRx(仅读写时序不一致时才设置)寄存器设置(其中x=1~4,对应4个区)。通过这3个寄存器,可以设置FSMC访问外部存储器的时序参数,拓宽了可选用的外部存储器的速度范围。& B3 T \4 ?9 {6 x8 i0 i! A2 Q
2.5.1 SRAM/NOR闪存片选控制寄存器(FSMC_BCRx)
3 }; G/ e* z- O/ _" f5 R8 y5 b- B
/ v0 E2 I$ b& \8 v7 |9 H6 k. v
" B; B6 f0 \! N. ?
: ]1 l; l4 D5 {' sEXTMOD:扩展模式使能位,控制是否允许读写不同的时序,设置为0(读写相同时序);
1 s4 n/ o9 h+ @& ~; S& JWREN:写使能位。我们需要向SRAM写数据,故该位必须设置为1;
) P( x8 S2 Y9 {5 l2 f5 W% AMWID[1:0]:存储器数据总线宽度。00,表示8位数据模式,01表示16位数据模式,10和11保留。我们的SRAM是16位数据线,所以设置WMID[1:0]=01;
$ ?+ z, u0 O& V; V6 _3 U! IMTYP[1:0]:存储器类型。00表示SRAM、ROM,01表示PSRAM,10表示NOR FLASH,11保留。我们驱动的芯片为SRAM,所以需要设置MTYP[1:0]=00;
; S1 C. X1 ~/ k5 @MBKEN:存储块使能位。需设置为1,使能相应的存储块。
: G3 Y+ d& Y( \5 p! O* o) r$ Z7 Q/ L7 Y* E1 Z# R6 D, j' ]
2.5.2 SRAM/NOR闪存片选时序寄存器(FSMC_BTRx)
6 l# I3 e2 }% I6 e6 A
0 X5 z3 {& ?1 T F% B
1 ?& A$ R6 O7 h7 X |* d
) t, O8 m; R: k- K. P: F* R
ACCMOD[1:0]:访问模式。00:模式A,01:模式B,10:模式C,11:模式D。# B0 e" X& V( ~" E* k
DATAST[7:0]:数据保持时间,等于: DATAST(+1)个HCLK时钟周期(F4只有写的时候要+1),DATAST最大为255。对IS62WV51216来说,其实就是OE/WE低电平持续时间,最大为55ns。对STM32F1,一个HCLK=13.8ns (1/72M),设置为3(13.8×(3+1)≈55.2ns)。对STM32F4,一个HCLK=6ns(1/168M),设置为8(有点超频)。$ s. D4 z, ~7 X+ `: @/ y. k/ @
ADDSET[3:0]:地址建立时间。表示:ADDSET (+1)个HCLK周期(F1不需要+1),ADDSET最大为15。对IS62WV51216来说,访问周期最快为55ns,之前的设置,已经可以保证访问周期不小于55ns,因此这个地址建立时间,直接设置为0即可。6 U& W# a1 H2 I' m) o9 o$ i& w ~
本实验因为EXTMOD位设置为0,所以读写时序共用这个时序寄存器!+ H+ N: w9 h+ i: v
2 y9 D. R! p) K" O9 ]4 H* q; j
2.5.3 SRAM/NOR闪存写时序寄存器(FSMC_BWTRx)
' m. _. o! V4 K2 j3 l. G若EXTMOD位设置为1,读写时序分开,则用该寄存器设置写时序。# \* c3 w$ Z/ d m- m
* K3 S% _) e; m. e
2 `& L. P( i2 U6 O+ V5 K' d
- k- P3 ]3 t( C$ ?
ACCMOD[1:0]:访问模式。00:模式A;01:模式B;10:模式C;11:模式D。
+ ^& Z) q. b7 W' h1 C$ T% _DATAST[7:0]:数据保持时间,等于:
: L! G) V9 _$ i/ d4 o% VDATAST(+1)个HCLK时钟周期,DATAST最大为255。8 W/ Q4 `% \6 z* D
ADDSET[3:0]:地址建立时间。表示:ADDSET+1个HCLK周期,ADDSET最大为15。
) E1 C- x% M/ m3 V本实验因为EXTMOD位设置为0,所以用不到该寄存器!! J1 l) Y. I0 ~
+ ~) y0 S+ K- q, o2.5.4 SRAM/NOR闪存片选寄存器组合说明7 H! I- A; H4 ^
在ST官方库提供的的寄存器定义里面,并没有定义FSMC_BCRx、FSMC_BTRx、FSMC_BWTRx等这些单独的寄存器,而是将他们进行了一些组合。规律如下:+ _$ y) l% b- f
1)FSMC_BCRx和FSMC_BTRx,组合成BTCR[8]寄存器组,对应关系如下:& C: M. B/ q% N& o/ q0 M, k* x- h
BTCR[0]对应FSMC_BCR1,BTCR[1]对应FSMC_BTR1;
/ c2 B. ?( g0 e eBTCR[2]对应FSMC_BCR2,BTCR[3]对应FSMC_BTR2;! u. s' b6 d/ r8 g
BTCR[4]对应FSMC_BCR3,BTCR[5]对应FSMC_BTR3;! `, @3 b1 F9 Y. _/ X, w
BTCR[6]对应FSMC_BCR4,BTCR[7]对应FSMC_BTR4。
& ~# m2 c# z: L% d+ L2)FSMC_BWTRx则组合成BWTR[7],对应关系如下:1 z, k' p- B' I7 F ~
BWTR[0]对应FSMC_BWTR1,BWTR[2]对应FSMC_BWTR2, x3 f' O6 {- q6 R6 z: c8 V @
BWTR[4]对应FSMC_BWTR3,BWTR[6]对应FSMC_BWTR4,4 d* {( p( n% x5 J8 B8 x
BWTR[1]、BWTR[3]和BWTR[5]保留,没有用到。
8 {2 Z4 u5 x" n% H3 _ h) ]& W) G5 o; T% B8 V% A9 A- k4 p
3. 相关代码解读
/ q9 n6 [8 ?) x! F5 \7 N* O3.1 sram.h头文件代码解读2 {3 \9 v7 ^7 P/ }/ }7 W4 H
2 ` O9 H: u- f8 X2 K; n- /**
3 f/ @; n9 i5 X( P3 } - ******************************** STM32F10x *********************************4 y' K7 S$ L" \) Z/ Z) N k
- * @文件名称: sram.h
1 d" q; N+ k, E - * @作者名称: Aaron/ h" \0 _; I1 m! ]! ~/ j
- * @库版本号: V3.5.0, Y! _# o4 V5 y. |
- * @工程版本: V1.0.0
! Y" i, E; [8 o' Y- t$ K2 F& a - * @开发日期: 2020年10月7日& p* I% y+ d; }% n) N; j* o$ [3 `. v- L
- * @摘要简述: SRAM头文件
`" U% D- h4 S* h1 E7 t9 U - ******************************************************************************/
9 m, N0 [. G9 ?* y - /*----------------------------------------------------------------------------- s* H3 t! X& v* s
- * @更新日志:/ F, g+ O' M! N( t
- * @无
+ |* l' ^3 X# u3 t0 U* j# p s - * ---------------------------------------------------------------------------*/
4 R6 r4 C6 i; Y/ S8 q1 d: I. n. F - #ifndef __SRAM_H
# _2 \5 s" _, X4 l) @ - #define __SRAM_H ' c% W! w+ G3 s: T0 B
- /* 包含的头文件 ---------------------------------------------------------------*/$ y6 L1 p! g( y9 L9 Z* H1 R
- #include "sys.h"' j7 ?; F) P+ N! S& l5 P ?
- /* 函数申明 -------------------------------------------------------------------*/ . t* ~# J" t" c4 }+ q
- void FSMC_SRAM_Init(void);
% E9 B# c1 u0 m$ i7 D* g- c - void FSMC_SRAM_WriteBuffer(u8* pBuffer,u32 WriteAddr,u32 NumHalfwordToWrite);1 `+ w& f. o) A1 X! Y
- void FSMC_SRAM_ReadBuffer(u8* pBuffer,u32 ReadAddr,u32 NumHalfwordToRead);
1 w' x- t/ g& l @& o9 I" l - #endif /* __SRAM_H */
: L3 c& l' D! a' m8 c: E. p: U - /****** Copyright (C)2020 Aaron. All Rights Reserved ****** END OF FILE *******/
复制代码
* O. C% I6 v. A5 N% o3.2 sram.c文件代码解读
) B7 r" ]0 A9 g% H! t- C1 e( m- Y/ m$ h* z
- /**
5 c: }4 @4 }7 h v - ******************************** STM32F10x *********************************
' T( L9 H: f- O- \ - * @文件名称: sram.c# @8 | L8 }0 v2 ~/ r
- * @作者名称: Aaron5 Z$ j0 H: @6 ]) G
- * @库版本号: V3.5.07 W2 z% f1 t& f/ {" S
- * @工程版本: V1.0.0; Z" C4 S- j X- C. b% w
- * @开发日期: 2020年10月7日3 l5 b0 Q6 M* u, K/ l
- * @摘要简述: SRAM源文件,使用NOR/SRAM的 Bank1.sector3,地址位HADDR[27,26]=10,
2 }& y2 u- u; j7 E# ~4 ]9 F - * 对IS62WV51216,地址线范围为A0~A18
; Z. p& D3 [( K - ******************************************************************************/
9 I3 F. j( _ N - /*----------------------------------------------------------------------------) Z. V, v( x2 M0 t- k
- * @更新日志:
3 L' v. F7 v* I) e/ ] - * @无: x8 Q5 @8 }. j' X
- * ---------------------------------------------------------------------------*/# p% {% f. q0 g
- /* 包含的头文件 --------------------------------------------------------------*/# H; \+ g9 S0 t/ f \/ w
- #include "sram.h" % a8 {, S6 p) I9 \4 I
- #include "usart.h"
\7 N; ]$ u- c7 u& o! o( D - /* 定义常量 ------------------------------------------------------------------*/
: z# D( E6 g4 J5 O) h) i0 j2 W - #define Bank1_SRAM3_ADDR ((u32)(0x68000000))
5 L3 _4 v2 v u, x1 U - /************************************************! Y9 U' z# l7 g5 c- p
- 函数名称:FSMC_SRAM_Init()
, X3 z& ?- |! O% s4 Q4 T% [ - 函数功能:初始化外部SRAM
0 i( G# P+ p9 b0 N# C G - 入口参数:无
+ h: k3 l' E2 L - 返回参数:无. c9 d; ? o* a5 X. o
- 开发作者:Aaron9 R1 Y7 D) Z7 L
- *************************************************/) V' ~3 ?( K6 i! j
- void FSMC_SRAM_Init(void)
% M6 z5 C1 b8 B1 n - {
2 l" ^. a+ s2 {( F% W7 V7 L2 w( c - /* 定义结构体 */% `- _' F/ E: U! C1 U$ \5 v
- FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
% q3 O7 I" a) f - FSMC_NORSRAMTimingInitTypeDef readWriteTiming;
* l6 I: U O' z) i |1 } - GPIO_InitTypeDef GPIO_InitStructure;
$ T7 U( Y( o S: R8 a+ X+ O - /* 使能相关IO口 */
! t7 O- O0 {' J8 ~% d/ R3 O - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOF|RCC_APB2Periph_GPIOG,ENABLE);
& S% F. S( ^8 v1 U' B$ ~ - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC,ENABLE);$ Z& w, `5 u. E+ Q* r
- GPIO_InitStructure.GPIO_Pin = 0xFF33; /* PD0-1,PD4-5,PD8-15 */
" \3 u' ?7 T. U. ` - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; /* 复用推挽输出 */" U) ]" F0 }6 a- F! g5 I: ?
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;; M5 Q$ A ~) Y6 _
- GPIO_Init(GPIOD, &GPIO_InitStructure);" O, `( N( o. G M/ a0 E
- GPIO_InitStructure.GPIO_Pin = 0xFF83; /* PE0-1,PE7-15 */
: U! t; C: x: L+ y - GPIO_Init(GPIOE, &GPIO_InitStructure);
. b. T% c) `/ f) g5 g$ K - GPIO_InitStructure.GPIO_Pin = 0xF03F; /* PF0-5,PF12-15 */
- m. V, P' p0 k0 B& H5 p - GPIO_Init(GPIOF, &GPIO_InitStructure);, X. P4 J/ q9 r2 W9 O
- GPIO_InitStructure.GPIO_Pin = 0x043F; /* PG0-5,PG10 */ z" u" _) a% n5 ^
- GPIO_Init(GPIOG, &GPIO_InitStructure);# U: V/ o e/ @$ r9 |8 h; t
- /* 读写时序结构体初始化 */ 4 }* h# f$ A7 a4 c$ j" g
- readWriteTiming.FSMC_AddressSetupTime = 0x00; /* 地址建立时间(ADDSET)为1个HCLK 1/36M=27ns */1 ]3 l5 t9 t7 @/ G- T) j/ k% Z
- readWriteTiming.FSMC_AddressHoldTime = 0x00; /* 地址保持时间(ADDHLD)模式A未用到 */
& p, l2 G$ k6 f) \ b/ { - readWriteTiming.FSMC_DataSetupTime = 0x03; /* 数据保持时间(DATAST)为3个HCLK 4/72M≈55ns(对EM的SRAM芯片) */
6 X1 W0 W% ]' w# p; O& r8 E - readWriteTiming.FSMC_BusTurnAroundDuration = 0x00;
; J0 c0 b( Y+ y4 o3 `/ v' M0 q - readWriteTiming.FSMC_CLKDivision = 0x00;2 Z" n, V& m" O
- readWriteTiming.FSMC_DataLatency = 0x00;
; }4 ?5 ]3 K6 G* u R# Y - readWriteTiming.FSMC_AccessMode = FSMC_AccessMode_A; /* 模式A */
N: l& O+ y+ D, ?+ a# J$ v - FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM3; /* 使用NE3,对应BTCR[4],[5] */, Z" ~5 c0 h/ _7 W
- FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; /* 地址复用未用 */: r7 d9 h$ b) Q$ s0 j
- FSMC_NORSRAMInitStructure.FSMC_MemoryType =FSMC_MemoryType_SRAM; /* 存储器类型SRAM */ , U. J' ~# ]! X! L1 d- L4 P3 W
- FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; /* 存储器数据宽度为16bit */ : E. N7 }( p5 p5 D r; L) D5 R1 e
- FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode =FSMC_BurstAccessMode_Disable; /* 禁止突发访问模式 */4 i5 v$ x, i$ K2 F7 s% P3 S
- FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;* V; w; }$ ^& M0 |2 W# R0 e( I
- FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait=FSMC_AsynchronousWait_Disable;# T5 h( ^; R& t5 z. b
- FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; - z" V. ^6 [: k/ W/ w) }( Z6 O }
- FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; 6 F" A' U6 M4 B1 w. `. j7 ] [' q
- FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; /* 存储器写使能 */
3 I _- ]7 w% l5 m2 h/ H - FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
. b+ w; \* P0 b7 q5 d* G* A! J - FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; /* 不使用扩展模式,读写使用相同的时序 */
% Z- t$ A- f1 F8 t% M" y - FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
8 Y! b( G! R1 Z8 }; ? - FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &readWriteTiming; /* 读写同样时序 */
/ o. A8 R2 I7 h/ _# Z. y1 X - FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &readWriteTiming; /* 读写同样时序 */
: J8 e2 j4 r! O$ T# j - FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); /* 初始化FSMC配置 */
' j+ Y1 J# L9 e- a4 S& x7 M8 b) e - FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3, ENABLE); /* 使能BANK3 */
& U" ^% [" Y3 F7 h( s1 w) ~ - }
$ P/ O) Z0 M0 `8 Q - /**********************************************************************
( o" {, g6 \0 A' o+ b3 \5 V - 函数名称:FSMC_SRAM_WriteBuffer(u8* pBuffer,u32 WriteAddr,u32 n)
m& I2 k$ e5 _# F - 函数功能:在指定地址开始,连续写入n个字节
2 Z% G; Z2 t; l' O6 y6 d - 入口参数:pBuffer:字节指针,首地址;WriteAddr:要写入的地址;n:要写入的字节数
' X+ Y* g: B4 q2 | - 返回参数:无
; L7 S1 [& `8 x$ a c- c3 ` - 开发作者:Aaron
# O: U1 h0 u4 i - ***********************************************************************/
! X' U! q% V) g# Q - void FSMC_SRAM_WriteBuffer(u8* pBuffer,u32 WriteAddr,u32 n)
* L! R: v( B! C4 E - {
3 @& S, a2 N* G. e; F7 W/ e& M - for(;n!=0;n--)
$ h1 J1 c2 n m$ d5 L0 k3 } - { ' b4 d- _% |: K. P( d1 a
- *(vu8*)(Bank1_SRAM3_ADDR+WriteAddr)=*pBuffer; /* Bank1_SRAM3_ADDR ((u32)(0x68000000)) */. ~' }/ o1 E9 I( ?
- WriteAddr++; ) v3 c' a, ~. l7 Q
- pBuffer++;- y# I8 F& D+ S1 d! T
- }
' u! L: v! V+ w! D/ A$ ` - }
" C( M3 X( y, ~7 d0 l& Q - /********************************************************************** G5 X+ }3 v' E ]$ |
- 函数名称:FSMC_SRAM_ReadBuffer(u8* pBuffer,u32 ReadAddr,u32 n)
! b4 n6 E+ f1 O; d$ Q5 V - 函数功能:在指定地址开始,连续读出n个字节
9 c4 I& V- s8 }+ ? - 入口参数:pBuffer:字节指针,首地址;ReadAddr:要写入的地址;n:要读出的字节数
- B0 |; z( F3 U7 S+ W& T" K! g - 返回参数:无
2 Q* p5 `0 _% c: Z% j - 开发作者:Aaron( `) E, I4 Z' J; Q4 u
- ***********************************************************************/
, R# _6 o* l. c6 ]/ M/ ^( j# p - void FSMC_SRAM_ReadBuffer(u8* pBuffer,u32 ReadAddr,u32 n)
% |" `! C: a/ F5 V: S+ t - {: a; G7 I! b. H2 n$ S Z& m8 D
- for(;n!=0;n--) 2 B, C! p2 Q- n
- {
, z/ O! E5 M3 ~2 ` - *pBuffer++=*(vu8*)(Bank1_SRAM3_ADDR+ReadAddr); I. \/ M: H) x
- ReadAddr++;
) f* j5 `! N9 a" q" r - }
1 A" z, W9 Y. F- t& {7 e9 t - }
) k; s- w, P# c: j! z& f6 L - /****** Copyright (C)2020 Aaron. All Rights Reserved ****** END OF FILE *******/
复制代码
; e+ G+ c6 r$ E' ?1 V& ~5 D3.3 main.c文件代码解读0 W' i. y }7 d2 Y& R/ F
% I* ?) e- s3 Y" h! Y- /**. s* a0 A% {6 ?+ Y. {, P
- ******************************** STM32F10x *********************************
- \" }% J# C3 |& ]' L - * @文件名称: main.c4 W1 @* }) P: ]" j
- * @作者名称: Aaron
1 ?0 Z) i1 X% b/ G) H# E3 r - * @库版本号: V3.5.07 B7 G6 d! y4 i% r4 j
- * @工程版本: V1.0.0
1 }( |( [6 \7 O- t$ k y" m - * @开发日期: 2020年10月7日
* m! C" B9 G- s* x4 S+ e( o7 R - * @摘要简述: 主函数/ M9 p5 ] | e
- ******************************************************************************/
2 g; E2 R2 T8 p9 b/ ?: \; M- X - /*----------------------------------------------------------------------------
; p2 O2 ~8 e. ^' B9 }5 n; T - * @更新日志:8 r; @% U+ s7 x2 K: I! K
- * @无
# Z% y. b, s0 z5 c) V+ N - * ---------------------------------------------------------------------------*/ O1 _3 R" ^; b, ^
- /* 包含的头文件 --------------------------------------------------------------*/
' s5 R6 y8 B$ a: y - #include "sram.h" b" _# p1 I0 Z. F0 ]: ?$ V' _
- #include "led.h"
; ^+ z- o' a% ^+ u ^ - #include "key.h"+ x5 C( _2 A6 M9 B/ F$ v& M3 |- N
- #include "sys.h"
& D/ N6 h! e' L; \3 u - #include "delay.h"( a6 q: W. U0 J2 J% G; f% o
- #include "usart.h"
* c4 k5 Y( j( t0 {. U v - /* 定义一个数组testsram[],u32表示每个数占4个字节,数组包含250000个值,*/4 Y& a1 G# z4 L$ {) f. [1 T3 W, T
- /* 采用绝对地址定义,数组的起始地址在0x68000000 */
1 s% ]$ W- S2 q7 n1 y7 [) a - u32 testsram[250000] __attribute__((at(0X68000000)));
6 E! A5 I$ b. v! O0 D6 l - /**********************************************************************
" }) E f2 b& Q - 函数名称:fsmc_sram_test()+ P" e2 f8 U1 F5 `6 v7 O' n; U
- 函数功能:外部内存测试(最大支持1M字节内存测试)
& F2 N! o% u. S% ]1 z9 X+ s0 z - 入口参数:无! d5 K/ W! G! k- `
- 返回参数:无2 T3 {4 A! V7 }
- 开发作者:Aaron
! n2 S: Z7 {8 n3 ~1 E" r - ***********************************************************************/1 E l: |( j% _, {! G3 s
- void fsmc_sram_test(void)
0 w' P; R4 M6 K: \ ? - { 2 @/ f: N) q) R W
- u32 i=0; 0 `6 n7 B% p9 ]4 Z8 |
- u8 temp=0; /* 0≤temp≤255 */
d6 X# b% M, n7 D - u8 sval=0; /* 在地址0读到的数据 */
# v& `! P W, l - printf("外部内存测试:0KB\r\n"); ' t. G$ o5 L, Z: O3 D0 I" v' Q
- /* 每隔4K个字节,写入一个数据,总共写入256个数据,刚好是1M字节 */1 X% J( G" j: |6 x& e+ r& Z
- for(i=0;i<1024*1024;i+=4096)5 o% o2 ~! P- U( T5 y- w! q% M
- {/ }1 b1 a% G2 T5 ]
- FSMC_SRAM_WriteBuffer(&temp,i,1);$ o; i: @2 G. H+ b
- temp++; /* for循环运行完后,temp值为0 */- u( b( v2 X3 A& ?5 ]( Z
- }
3 G2 S1 k9 a; o t4 h# g - /* 依次读出之前写入的数据,进行校验 */
6 N( l% m% S+ n0 a1 y3 g1 A# W# l3 V - for(i=0;i<1024*1024;i+=4096) 0 d0 b C8 R3 K! w( h
- {4 V8 Q- p" m( n- p; g
- FSMC_SRAM_ReadBuffer(&temp,i,1);6 p9 r K3 q6 j; k( Z6 i
- if(i==0) /* 将第一次的temp值赋给sval,即sval=temp=0 */
* P% L3 a1 y3 @) V$ v - sval=temp;1 v t1 q/ }; o7 c
- else if(temp<=sval)
! `* P0 Z$ U0 A; v* L - break; /* 本程序设计思路,后面读出的数据一定比第一次读到的数据大 */ 4 y, @6 H/ o, i; w' a
- printf("内存容量为:%dKB\r\n",(temp-sval+1)*4);
$ q* V! j' ^( j/ ~; C4 T - }
$ O: w B& J% f0 O& a \. v - }0 g( M% q) B8 c4 }
- /**********************************************************************
9 v* s; E1 `* H5 G2 N% c8 {% J4 z - 函数名称:main() u% F: Q4 @8 b' j: I+ q6 h
- 函数功能:主函数3 f% j, H9 C @0 M. z
- 入口参数:无& g7 L$ u, o& O5 `4 S: Q
- 返回参数:无
u' i2 V& }4 u' `) B - 开发作者:Aaron
% Z! ~/ V* n2 q - ***********************************************************************/2 Y: k( l, `5 A6 N
- int main(void)
1 l2 S4 Q1 I% E8 R- l/ m4 r& c - { 8 g; y! J, Y8 O y8 Z9 p
- u8 key;
3 ?& O$ M6 v4 ~ - u8 i=0; ! m( j% H0 J; f. S' G# k7 k
- u32 ts=0;1 D+ g2 T: l4 ]1 X
- delay_init();
% w( N; `$ M: O* |# z5 ?/ F5 c# b - NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
! D) _8 O, [6 q) ^; q# p7 L* f - uart_init(115200);
( f$ x5 d% T C" P$ r/ U O2 @ - LED_Init(); 3 E. ~9 ]2 O% C
- KEY_Init(); & a( Q: N' \1 ?4 C( x; ~" ?# X( Z
- FSMC_SRAM_Init();
( ? U6 Z- `* d( d - for(ts=0;ts<250000;ts++)testsram[ts]=ts; /* 预存测试数据 */1 u. I! ^8 x- T5 `4 R+ J9 u5 D( a
- while(1) 5 c6 Q& J+ H" d8 \: x
- { 5 v* ^! e% a9 v/ V
- key=KEY_Scan(0); /* 不支持连按 */ 6 x& h3 X6 Q; ^/ Z; y0 _. w
- if(key==KEY0_PRES)+ I, p* o2 V# i
- fsmc_sram_test(); /* 测试SRAM容量 */
1 t# h. c! V. i7 l( z" f - else if(key==KEY1_PRES) /* 打印预存测试数据 */* ~+ y; K0 ^7 b7 Q, }/ `
- {
+ q% o- Z/ n7 A' r" T) v - for(ts=0;ts<250000;ts++)0 A, s+ b6 H% T7 v8 v
- printf("显示测试数据testsram[%d]=%d\r\n",ts,testsram[ts]);
6 |8 R9 J# `) J8 e* W - }
) q) R) O! Z4 a/ g' U0 e - else 2 U2 e, Z1 d7 `2 c# D* \
- delay_ms(10); 8 y- A5 j3 m0 O) x! ?/ q+ f" S
- i++;9 \6 H5 e8 {& S
- if(i==20)& [- J1 C# C$ D' r" s4 E: V
- {
5 d2 B2 T% S& T - i=0;( T5 P7 q$ h ?+ m2 ?
- LED0=!LED0;
3 E1 N+ \ p3 B- Z; y& C - }
0 b: A7 ~$ z# M8 V! r& l, X/ O - }
, b7 ^# J+ N. \5 I5 q - }
# {, V: n' H, w& T) R( A - /****** Copyright (C)2020 Aaron. All Rights Reserved ****** END OF FILE *******/
0 R4 e$ n+ I! G) ?& a" |
% P: e6 `; W7 B7 ?. ^* u7 X
复制代码 / J, G0 f" L+ s1 s
4. 实验结果
1 x. I' p% H1 h7 o- I按KEY0键:
- j6 d* d- L* B, i2 c* b7 Q
( T1 ^9 q5 q6 I
# S6 S5 ^; T3 |& Q0 N8 |' i0 k9 ]5 C6 ?; x4 a) U* W
3 x. s! [) z. n4 G2 ~" U& o5 B# R' O, A
! D6 ]9 c/ ]# G& }7 w2 O+ d
按KEY1键:
9 O/ W* J( N# c6 W$ [. f+ D$ e+ ~9 n4 |7 B# A- p( f
0 O9 O7 f3 o0 H% e- {" ^
) r# b; b" V* y! Y% k. I1 I3 `————————————————
! e8 O. o% g2 P$ c2 D/ ]版权声明:天亮继续睡2 M7 w7 r3 Y. R4 }" x; g
: B: W' d* k6 j' m
4 a( |: ~ E! o8 ]+ S
|