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