外部 SRAM 实验

 IS62WV51216是ISSI(Integrated Silicon Solution, Inc)公司生产的一颗16位宽512K(512*16,即1M字节)容量的CMOS静态内存(SRAM)芯片。

IS62WV51216特点:

①高速。具有45ns/55ns访问速度。

②低功耗。操作时:36mW;待机时:12uW。

③兼容TTL电平。

④全静态操作。不需要刷新和时钟电路。

⑤三态输出。

⑥字节控制功能。支持高/低字节控制。

图中A0~18为地址线,总共19根地址线(即2^19=512K,1K=1024);I/O0~15为数据线,总共16根数据线。CS2和CS1都是片选信号,不过CS2是高电平有效CS1是低电平有效;OE是输出使能信号(读信号);WE为写使能信号;UB和LB分别是高字节控制和低字节控制信号;

IS62WV51216读时序

重点时序: 读周期时间(tRC) 、地址建立时间(tAA) 、OE建立时间(tDOE) 

我们开发板使用55ns的IS62WV51216,tRC=55ns tAA=55ns(Max),tDOE=25ns(Max)

IS62WV51216写时序

 重点时序: 写周期时间(tWC) 、地址建立时间(tSA) 、WE脉宽(tPWE)

开发板使用55ns的IS62WV51216,tWC=55ns tSA=0ns,tPWE=45ns(min)

FSMC介绍

 FSMC,即灵活的静态存储控制器,能够与同步或异步存储器和16位PC存储器卡连接,STM32的FSMC接口支持包括SRAM、NAND FLASH、NOR FLASH和PSRAM等存储器。FSMC的框图如下图所示:

FSMC驱动外部SRAM时,外部SRAM的控制一般有:地址线(如A0~A25)、数据线(如D0~D15)、写信号(WE,即WR)、读信号(OE,即RD)、片选信号(CS),如果SRAM支持字节控制,那么还有UB/LB信号。      

而IS62WV51216的信号包括:I/O0~I/O15、A0~A18、OE、WE、CS、UB、LB等,我们将这些信号依次连接STM32 FSMC接口的D0~D15、A0~A18、OE、WE、CS、UB、LB等信号即可。 

STM32的FSMC支持8/16位数据宽度,我们这里用到的SRAM是16位宽度的,所以在设置的时候,选择16位宽就OK了。FSMC的外部设备地址映像,STM32的FSMC将外部存储器划分为固定大小为256M字节的四个存储块

STM32的FSMC存储块1(Bank1)用于驱动NOR FLASH/SRAM/PSRAM,被分为4个区,每个区管理64M字节空间,每个区都有独立的寄存器对所连接的存储器进行配置。Bank1的256M字节空间由28根地址线(HADDR[27:0])寻址。     这里HADDR,是内部AHB地址总线,其中,HADDR[25:0]来自外部存储器地址FSMC_A[25:0],而HADDR[26:27]对4个区进行寻址。如下表所示:

当Bank1接的是16位宽度存储器的时候:HADDR[25:1]->FSMC_A[24:0]

当Bank1接的是8位宽度存储器的时候:HADDR[25:0]->FSMC_A[25:0]

不论外部接8位/16位宽设备,FSMC_A[0]永远接在外部设备地址A[0] 

STM32的FSMC存储块1 支持的异步突发访问模式包括:模式1、模式A~D等多种时序模型,驱动SRAM时一般使用模式1或者模式 A,这里我们使用模式A来驱动SRAM

 对于NOR FLASH/PSRAM控制器(存储块1),通过FSMC_BCRx、FSMC_BTRx和FSMC_BWTRx寄存器设置(其中x=1~4,对应4个区)。通过这3个寄存器,可以设置FSMC访问外部存储器的时序参数,拓宽了可选用的外部存储器的速度范围。

SRAM/NOR闪存片选控制寄存器(FSMC_BCRx)

EXTMOD:扩展模式使能位,控制是否允许读写不同的时序,设置为0

WREN:写使能位。我们需要向SRAM写数据,故该位必须设置为1

MWID[1:0]:存储器数据总线宽度。00,表示8位数据模式;01表示16位数据模式;10和11保留。我们的SRAM是16位数据线,所以设置WMID[1:0]=01。

MTYP[1:0]:存储器类型。00表示SRAM、ROM;01表示PSRAM;10表示NOR FLASH;11保留。我们驱动的芯片为SRAM,所以需要设置MTYP[1:0]=00。

MBKEN:存储块使能位。需设置为1 。

SRAM/NOR闪存片选时序寄存器(FSMC_BTRx)

ACCMOD[1:0]:访问模式。00:模式A;01:模式B;10:模式C;11:模式D。 DATAST[7:0]:数据保持时间,等于: DATAST(+1)个HCLK时钟周期,DATAST最大为255。对IS62WV51216来说,其实就是OE/WE低电平持续时间,最大为55ns。对STM32F1,一个HCLK=13.8ns (1/72M),设置为3;对STM32F4,一个HCLK=6ns(1/168M) ,设置为8。 ADDSET[3:0]:地址建立时间。表示:ADDSET (+1)个HCLK周期,ADDSET最大为15。对IS62WV51216来说,访问周期最快位55ns,而我们前面的设置,已经可以保证访问周期不小于55ns,因此这个地址建立时间,我们可以直接设置为0即可。 

因为设置了EXTMOD位,所以读写时序共用这个时序寄存器!

寄存器组合说明

在ST官方库提供的的寄存器定义里面,并没有定义FSMC_BCRx、FSMC_BTRx、FSMC_BWTRx等这个单独的寄存器,而是将他们进行了一些组合。规律如下:     

FSMC_BCRx和FSMC_BTRx,组合成BTCR[8]寄存器组,他们的对应关系如下:

BTCR[0]对应FSMC_BCR1,BTCR[1]对应FSMC_BTR1

BTCR[2]对应FSMC_BCR2,BTCR[3]对应FSMC_BTR2

BTCR[4]对应FSMC_BCR3,BTCR[5]对应FSMC_BTR3

BTCR[6]对应FSMC_BCR4,BTCR[7]对应FSMC_BTR4

FSMC_BWTRx则组合成BWTR[7],他们的对应关系如下:

BWTR[0]对应FSMC_BWTR1,BWTR[2]对应FSMC_BWTR2,

BWTR[4]对应FSMC_BWTR3,BWTR[6]对应FSMC_BWTR4,

BWTR[1]、BWTR[3]和BWTR[5]保留,没有用到。

硬件连接

 代码讲解:

sram.c 文件:此部分代码包含 3 个函数,FSMC_SRAM_Init 函数用于初始化,包括 FSMC 相关 IO 口的 初始化以及 FSMC 配置;FSMC_SRAM_WriteBuffer 和 FSMC_SRAM_ReadBuffer 这两个函数分 别用于在外部 SRAM 的指定地址写入和读取指定长度的数据(字节数)。 这里需要注意的是:FSMC 当位宽为 16 位的时候,HADDR 右移一位同地址对其,但是 ReadAddr 我们这里却没有加 2,而是加 1,是因为我们这里用的数据为宽是 8 位,通过 UB 和 LB 来控制高低字节位,所以地址在这里是可以只加 1 的。另外,因为我们使用的是 BANK1, 区域 3,所以外部 SRAM 的基址为:0x68000000。

main.c文件

u32 testsram[250000] __attribute__((at(0X68000000)));//测试用数组
//外部内存测试(最大支持1M字节内存测试)	    
void fsmc_sram_test(u16 x,u16 y)
{  
	u32 i=0;  	  
	u8 temp=0;	   
	u8 sval=0;	//在地址0读到的数据	  				   
  	LCD_ShowString(x,y,239,y+16,16,"Ex Memory Test:   0KB"); 
	//每隔4K字节,写入一个数据,总共写入256个数据,刚好是1M字节
	for(i=0;i<1024*1024;i+=4096)
	{
		FSMC_SRAM_WriteBuffer(&temp,i,1);
		temp++;
	}
	//依次读出之前写入的数据,进行校验		  
 	for(i=0;i<1024*1024;i+=4096) 
	{
  		FSMC_SRAM_ReadBuffer(&temp,i,1);
		if(i==0)sval=temp;
 		else if(temp<=sval)break;//后面读出的数据一定要比第一次读到的数据大.	   		   
		LCD_ShowxNum(x+15*8,y,(u16)(temp-sval+1)*4,4,16,0);//显示内存容量  
 	}					 
}	

int main(void)
{        
	u8 key;		 
 	u8 i=0;	     
	u32 ts=0;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
	delay_init(168);  //初始化延时函数
	uart_init(115200);		//初始化串口波特率为115200
	
	LED_Init();					//初始化LED
 	LCD_Init();         //LCD初始化
 	KEY_Init();					//按键初始化 
 	FSMC_SRAM_Init();			//初始化外部SRAM  
 	POINT_COLOR=RED;//设置字体为红色 
	LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");	
	LCD_ShowString(30,70,200,16,16,"SRAM TEST");	
	LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
	LCD_ShowString(30,110,200,16,16,"2014/5/14");   
	LCD_ShowString(30,130,200,16,16,"KEY0:Test Sram");
	LCD_ShowString(30,150,200,16,16,"KEY1:TEST Data");
 	POINT_COLOR=BLUE;//设置字体为蓝色  
	for(ts=0;ts<250000;ts++)testsram[ts]=ts;//预存测试数据	 
  	while(1)
	{	
		key=KEY_Scan(0);//不支持连按	
		if(key==KEY0_PRES)fsmc_sram_test(60,170);//测试SRAM容量
		else if(key==KEY1_PRES)//打印预存测试数据
		{
			for(ts=0;ts<250000;ts++)LCD_ShowxNum(60,190,testsram[ts],6,16,0);//显示测试数据	 
		}else delay_ms(10);   
		i++;
		if(i==20)//DS0闪烁.
		{
			i=0;
			LED0=!LED0;
 		}
	}
}

此段代码,我们定义了一个超大数组 testsram,我们指定该数组定义在外部 sram 起始地址 (__attribute__((at(0X68000000)))),该数组用来测试外部 SRAM 数据的读写。注意该数组的定 义方法,是我们推荐的使用外部 SRAM 的方法。如果想用 MDK 自动分配,那么需要用到分散 加载还需要添加汇编的 FSMC 初始化代码,相对来说比较麻烦。而且外部 SRAM 访问速度又远 不如内部 SRAM,如果将一些需要快速访问的 SRAM 定义到了外部 SRAM,将会严重拖慢程序 运行速度。而如果以我们推荐的方式来分配外部 SRAM,那么就可以控制 SRAM 的分配,可以 针对性的选择放外部还是放内部,有利于提高程序运行速度,使用起来也比较方便。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值