STM32-基本知识梳理9-FSMC控制外部SRAM

一、SRAM基础知识介绍

1,外部SRAM,STM32芯片扩展内存与给PC扩展内存的原理是一样的,只是PC上一般以内存条的形式扩展;

2,外部SRAM,断电之后,存储器信息会丢失;

 3,外部SRAM的内部框图解析

1-实际存储器模块;

2-IO接口,包括地址线、数据线

3-控制模块,

包括 CS片选引脚、OE读使能、WE写使能、UB高位字节允许访问、LB低位字节允许访问

(补充,具体操作不需要担心,只要后面配置好FSMC模块和时间参数,这些都会交给FSMC模块自动处理)

4,地址和内存位置的关系

内存可以理解为在excel中的一个个小表格,我们可以通过行地址和列地址具体的找到一个地址位置;

本例中,使用的是IS62WV51216型号的SRAM,SRAM比较小,没有列地址线,它的数据宽度为16位,即一个行地址对应2字节空间,框图中左侧的A0-A18是行址信号,18根地址线一共可以表示218=28x1024=512K行存储单元,所以它一共能访问512Kx16bits大小的空间。访问时,使用UB#或LB#线控制数据宽度,

 5,控制的SRAM的关键参数

1-地址建立时间;

2-数据建立时间;

具体在后面的fmsc模块初始化中介绍


至此,SRAM简要介绍到此结束,下面介绍FSMC模块

二、FSMC基础知识介绍

1,用FSMC外设来管理扩展的存储器,FSMC是Flexible Static Memory Controller的缩写,译为灵活的静态存储控制器。

2,可以用于驱动包括SRAM、NOR FLASH以及NAND FLSAH类型的存储器;不同的存储器类型,由于读取操作方式的不同,在FSMC模块中有不同的接口进行配置

3,FSMC框图介绍

①外部接线引脚,根据不同的存储器类型,由对应的控制引脚,但是地址线和数据线是共用的;

②控制模块

③FMSC模块是直接挂载在AHB总线上的,时钟是72mhz

 4,使用FMSC模块中访问外部SRAM空间

通过FSMC模块控制的存储器模块,和SPI控制的flash模块、I2C控制的EEROM,甚至串口控制的最大区别在于:FSMC控制的存储器模块,数据地址是存放在STM32的地址区间内的,也就是连接的SRAM模块,相当于STM32的内存,我们可以通过指针访问的方式直接对SRAM进行操作;

而其他一般是输入指令,输入内存模块自身的地址空间,执行对应操作

5,对应地址空间在STM32中的内存地址分区

在bank1-NORSRAM3模块区域,首地址为0x68000000

 

6,FSMC控制SRAM的时序

①FSMC外设支持输出多种不同的时序以便于控制不同的存储器,它具有ABCD四种模式,控制SRAM使用模式A,控制外部液晶屏选用模式B

②地址建立周期的关键参数

地址建立周期ADDSET配置为0x00(即1个地址建立周期,单位HCLK);HCLK的数值是由AHB时钟决定,STM32F103 为1/72M;

数据建立周期为0x02,即3个HCLK

ps:这是读写周期相同的情况,理论上要具体计算,我这边直接借用了野火的经验值。

至此FSMC模块介绍完毕,下面进入代码模块


三、代码模块解析

1,FSMC结构体初始化

1- FSMC结构初始化主要分为两个模块,时序初始化、整体FSMC初始化

 配置好时序结构体后,再在整体初始化结构体中,进行地址传递,一起进行初始化

2,整体代码逻辑分析

1 - GPIO模块初始化,按照ST推荐方式初始化,全部复用推挽输出;

2 - 初始化FSMC

3-mian函数中配置使用

1 - GPIO模块初始化

void fsmc_gpio_config(void)
{
	//打开时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF|RCC_APB2Periph_GPIOD|
	                              RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOG,ENABLE);
	
	//开始配置GPIO
	//地址A0-A18
	
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;//PF0
	GPIO_Init( GPIOF, & GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_1 |GPIO_Pin_2 | GPIO_Pin_3| GPIO_Pin_4
	                         |GPIO_Pin_5|GPIO_Pin_12 |GPIO_Pin_13 |GPIO_Pin_14 |GPIO_Pin_15;// PF
	GPIO_Init( GPIOF, & GPIO_InitStruct);
	
	
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0 |GPIO_Pin_1 | GPIO_Pin_7| GPIO_Pin_8
	                         |GPIO_Pin_9|GPIO_Pin_10 |GPIO_Pin_11 |GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14
	                          |GPIO_Pin_15;
	GPIO_Init( GPIOE, & GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0 |GPIO_Pin_1|GPIO_Pin_4 |GPIO_Pin_5
	                         |GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13
							 |GPIO_Pin_14|GPIO_Pin_15;
	GPIO_Init( GPIOD, & GPIO_InitStruct);
	
    GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0 |GPIO_Pin_1|GPIO_Pin_2 |GPIO_Pin_3
	                         |GPIO_Pin_4|GPIO_Pin_5 |GPIO_Pin_10;
	GPIO_Init( GPIOG, & GPIO_InitStruct);
	
}

2 - 初始化FSMC,并在调用GPIO,并且cmd启动

void fsmc_config(void)
{
	fsmc_gpio_config();
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC,ENABLE);//开启fsmc时钟
	
	//先配置读写时序结构体
	FSMC_NORSRAMTimingInitTypeDef readWriteTiming;
	readWriteTiming.FSMC_AccessMode=FSMC_AccessMode_A;//控制sram选择模式A
	readWriteTiming.FSMC_AddressHoldTime=0x00;//地址保持时间0
	//地址建立时间(ADDSET)为1个HCLK 1/72M=14ns,addset+1
	readWriteTiming.FSMC_AddressSetupTime=0x00;
	
	
	readWriteTiming.FSMC_BusTurnAroundDuration=0;
	readWriteTiming.FSMC_CLKDivision=0;
	readWriteTiming.FSMC_DataLatency=0x00;  //这三个,模式A未用到
	
	
	//数据保持时间(DATAST)+ 1个HCLK = 3/72M=42ns(对EM的SRAM芯片)	
	readWriteTiming.FSMC_DataSetupTime=0x02;
	
	
	//下面进行FSMC-SRAM初始化
	FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStruct;
	
	//SRAM的地址区域在bank1-SRAM3
	FSMC_NORSRAMInitStruct.FSMC_Bank=FSMC_Bank1_NORSRAM3 ;
	//异步,不适用突发模式
	FSMC_NORSRAMInitStruct.FSMC_BurstAccessMode=FSMC_BurstAccessMode_Disable ;
	//等待时间
	FSMC_NORSRAMInitStruct.FSMC_AsynchronousWait=FSMC_AsynchronousWait_Disable ;
	//数据总线和地址总线不复用
	FSMC_NORSRAMInitStruct.FSMC_DataAddressMux=FSMC_DataAddressMux_Disable ;
	//扩展模式不开启,读写时序保持一种
	FSMC_NORSRAMInitStruct.FSMC_ExtendedMode=FSMC_ExtendedMode_Disable ;
	//数据宽度16位
	FSMC_NORSRAMInitStruct.FSMC_MemoryDataWidth=FSMC_MemoryDataWidth_16b ;
	//存储器类型  SRAM
	FSMC_NORSRAMInitStruct.FSMC_MemoryType=FSMC_MemoryType_SRAM ;
	
	FSMC_NORSRAMInitStruct.FSMC_WaitSignal=FSMC_WaitSignal_Disable ;
	FSMC_NORSRAMInitStruct.FSMC_WaitSignalActive=FSMC_WaitSignalActive_BeforeWaitState ;
	FSMC_NORSRAMInitStruct.FSMC_WaitSignalPolarity=FSMC_WaitSignalPolarity_Low ;
	FSMC_NORSRAMInitStruct.FSMC_WrapMode=FSMC_WrapMode_Disable;
	FSMC_NORSRAMInitStruct.FSMC_WriteBurst=FSMC_WriteBurst_Disable  ;
	
	//写使能
	FSMC_NORSRAMInitStruct.FSMC_WriteOperation=FSMC_WriteOperation_Enable ;
	FSMC_NORSRAMInitStruct.FSMC_ReadWriteTimingStruct=&readWriteTiming;
	//扩展模式有效
	FSMC_NORSRAMInitStruct.FSMC_WriteTimingStruct=&readWriteTiming;
	
   FSMC_NORSRAMInit(&FSMC_NORSRAMInitStruct);
   //启动
   FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3,ENABLE);
	
}

3-main函数中配置使用

#include "stm32f10x.h"                  // Device header
#include "LED.H"
#include "BSP_USART.H"

#include "BSP_FSMC.H"

//uint8_t testvalue __attribute__((at(SRAM_BASE_ADD+0x40)));

uint8_t testValue __attribute__((section(".ARM.__at_(0x68000000+0x40)")));

int main(void)
{
	
	 bsp_usart_config();
	 fsmc_config();
	
printf ( "\r\n野火外部 SRAM 测试1\r\n" );
	  
	uint16_t *p16;
	 p16=(uint16_t *)(0x68000000);
	 *p16=0x1234;
	 printf("%x  %p\n",*p16,p16);
	 
	 
	 float*pf=(float *)(0x68000000+0x20);
	 *pf=56.789;
	 printf("%.4f  %p\n",*pf,pf);
	
	
	uint32_t *p32;
	 p32=(uint32_t *)(0x68000000+0x40);
	 *p32=0x12345678;
	 printf("%x  %p\n",*p32,p32);
	
}

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值