【STM32自学笔记-FSMC-扩展SRAM】_fsmc 配置
一、FSMC简介
FSMC又叫灵活的静态存储器,主要作用是管理扩展的存储器。它可以用于驱动包括SRAM、NOR FLASH以及NAND FLSAH类型的存储器,不能驱动如SDRAM这种动态的存储器而在STM32F429系列的控制器中,它具有FMC外设,支持控制SDRAM存储器。
二、FSMC框图说明设定
2.1 引脚说明
FSMC引脚 | SRAM引脚 | 说明 |
FSMC_NBL[1:0] | LB\UB | 数据掩码信息 |
FSMC_A[18:0] | A[18:0] | 行地址线 |
FSMC_D[15:0] | D[15:0] | 数据线 |
FSMC_NWE | WE | 写使能 |
FSMC_NOE | OE | 读使能 |
FSMC_NE[1:4] | CE(CS) | 片选信号 |
其中比较特殊的FSMC_NE是用于控制SRAM芯片的控制信号线,STM32具有FSMC_NE1/2/3/4号引脚,不同的引脚对应STM32内部不同的地址区域。当使用不同的NE引脚连接外部存储器时,STM32访问的SRAM的地址不一样,从而达到控制多块SRAM的目的
2.2 存储器控制器
上面不同类型的引脚是连接到FSMC内部对应的存储控制器中的。NOR/PSRAM/SRAM设备使用相同的控制器,NAND/PC卡设备使用相同的控制器,不同的控制器有专用的寄存器用于配置其工作模式。
2.3 时钟控制逻辑
FSMC外设挂载在AHB总线上,时钟信号来自于HCLK(默认72MHz),控制器的同步时钟输出就是由它分频得到。
三、FSMC地址映射
FSMC把整个External RAM存储区域分成了4个Bank区域,并分配了地址范围及适用的存储器类型,如NOR及SRAM存储器只能使用Bank1的地址。
在NOR及SRAM区域,每个Bank的内部又分成了4个小块,每个小块有相应的控制引脚用于连接片选信号,如FSMC_NE[4:1]信号线可用于选择BANK1内部的4小块地址区域,当STM32访问0x68000000-0x6BFFFFFF地址空间时,会访问到Bank1的第3小块区域,相应的FSMC_NE3信号线会输出控制信号。
四、FSMC控制SRAM的时序
FSMC外设支持输出多种不同的时序以便于控制不同的存储器,它具有ABCD四种模式,下面我们仅针对控制SRAM使用的模式A进行讲解。
读时序
该图表示一个存储器操作周期由地址建立周期(ADDSET)、数据建立周期(DATAST)以及2个HCLK周期组成。在地址建立周期中,地址线发出要访问的地址,数据掩码信号线指示出要读取地址的高、低字节部分,片选信号使能存储器芯片;地址建立周期结束后读使能信号线发出读使能信号,接着存储器通过数据信号线把目标数据传输给FSMC,FSMC把它交给内核。
写时序
该图表示一个存储器操作周期由地址建立周期(ADDSET)、数据建立周期(DATAST)组成。在地址建立周期中,地址线发出要访问的地址,数据掩码信号线指示出要读取地址的高、低字节部分,片选信号使能存储器芯片;地址建立周期结束后读使能信号线发出写使能信号,FSMC把数据通过数据线传输到存储器中。
五、SRAM
SRAM属于掉电易丢失的存储器,并且无时钟同步。STM32控制器芯片内部有一定大小的SRAM及FLASH作为内存和程序存储空间,但当程序较大,内存和程序空间不足时,就需要在STM32芯片的外部扩展存储器了。STM32F103ZE系列芯片可以扩展外部SRAM用作内存。给STM32芯片扩展内存与给PC扩展内存的原理是一样的,只是PC上一般以内存条的形式扩展,而且内存条实质是由多个内存颗粒(即SDRAM芯片)组成的通用标准模块,而STM32扩展时,直接直接与SRAM芯片连接。
六、SRAM内部功能框图
6.1 SRAM信号线
SRAM的控制比较简单,只要控制信号线使能了访问,从地址线输入要访问的地址,即可从I/O数据线写入或读出数据。
6.2 SRAM的存储矩阵
SRAM内部包含的存储阵列,可以把它理解成一张表格,数据就填在这张表格上。和表格查找一样,指定一个行地址和列地址,就可以精确地找到目标单元格,这是SRAM芯片寻址的基本原理。这样的每个单元格被称为存储单元,而这样的表则被称为存储矩阵。
6.3 地址译码器、列IO和IO数据电路
地址译码器把N根地址线转换成2N根信号线,每根信号线对应一行或一列存储单元,通过地址线找到具体的存储单元,实现寻址。本实例中的使用的SRAM比较小,没有列地址线,它的数据宽度为16位,即一个行地址对应2字节空间,框图中左侧的A0-A18是行址信号,18根地址线一共可以表示218=28×1024=512K行存储单元,所以它一共能访问512Kx16bits大小的空间。访问时,使用UB#或LB#线控制数据宽度。
6.4 控制电路
控制电路主要包含了片选、读写使能以及上面提到的宽度控制信号UB#和LB#。利用CS2或CS1#片选信号,可以把多个SRAM芯片组成一个大容量的内存条。OE#和WE#可以控制读写使能,防止误操作。
七 、SRAM读写流程
对SRAM读数据流程
对SRAM写数据流程
读写时序的流程很类似,过程如下:
(1) 主机使用地址信号线发出要访问的存储器目标地址;
(2) 控制片选信号CS1#及CS2#使能存储器芯片;
(3) 若是要进行读操作,则控制读使能信号OE#表示要读数据,若进行写操作则控制写使能信号WE#表示要写数据;
(4) 使用掩码信号LB#与UB#指示要访问目标地址的高、低字节部分;
(5) 若是读取过程,存储器会通过数据线向主机输出目标数据,若是写入过程,主要使用数据线向存储器传输目标数据。
八、FSMC案例-扩展SRAM
//1个HCLK时钟周期1/72M=0.138*10^-8s=13.8ns
//写时序时间要求
//1.(ADDSET+1)+(DATAST+1)>55ns 13.8+41.4=55.2ns>55ns
//2.(DATAST+1)>40ns 2+1=41.4ns
//3.(ADDSET+1)>0ns 0+1=13.8ns//读时序时间要求
//1.(ADDSET+1)+(DATAST+1)+2HCLK>55ns
//2.(DATAST+1)>25ns 1+1=27.6ns
//3.(ADDSET+1)>0ns 0+1=13.8ns
SRAM.H
#ifndef __SRAM_H
#define __SRAM_H
#define SRAM_BASE_ADDR (0X68000000)
#define SRAM_SIZE (1*102481024)
#define SRAM_End_ADDR (SRAM_BASE_ADDR+SRAM_SIZE)
//A0-F0
#define FSMC_A0_CLK RCC_APB2Periph_GPIOF
#define FSMC_GPIO_A0 GPIO_Pin_0
#define FSMC_A0 GPIOF
//A1-F1
#define FSMC_A1_CLK RCC_APB2Periph_GPIOF
#define FSMC_GPIO_A1 GPIO_Pin_1
#define FSMC_A1 GPIOF
//A2-F2
#define FSMC_A2_CLK RCC_APB2Periph_GPIOF
#define FSMC_GPIO_A2 GPIO_Pin_2
#define FSMC_A2 GPIOF
//A3-F3
#define FSMC_A3_CLK RCC_APB2Periph_GPIOF
#define FSMC_GPIO_A3 GPIO_Pin_3
#define FSMC_A3 GPIOF
//A4-F4
#define FSMC_A4_CLK RCC_APB2Periph_GPIOF
#define FSMC_GPIO_A4 GPIO_Pin_4
#define FSMC_A4 GPIOF
//A5-F5
#define FSMC_A5_CLK RCC_APB2Periph_GPIOF
#define FSMC_GPIO_A5 GPIO_Pin_5
#define FSMC_A5 GPIOF
//A6-F12
#define FSMC_A6_CLK RCC_APB2Periph_GPIOF
#define FSMC_GPIO_A6 GPIO_Pin_12
#define FSMC_A6 GPIOF
//A7-F13
#define FSMC_A7_CLK RCC_APB2Periph_GPIOF
#define FSMC_GPIO_A7 GPIO_Pin_13
#define FSMC_A7 GPIOF
//A8-F14
#define FSMC_A8_CLK RCC_APB2Periph_GPIOF
#define FSMC_GPIO_A8 GPIO_Pin_14
#define FSMC_A8 GPIOF
//A9-F15
#define FSMC_A9_CLK RCC_APB2Periph_GPIOF
#define FSMC_GPIO_A9 GPIO_Pin_15
#define FSMC_A9 GPIOF
//A10-G0
#define FSMC_A10_CLK RCC_APB2Periph_GPIOG
#define FSMC_GPIO_A10 GPIO_Pin_0
#define FSMC_A10 GPIOG
//A11-G1
#define FSMC_A11_CLK RCC_APB2Periph_GPIOG
#define FSMC_GPIO_A11 GPIO_Pin_1
#define FSMC_A11 GPIOG
//A12-G2
#define FSMC_A12_CLK RCC_APB2Periph_GPIOG
#define FSMC_GPIO_A12 GPIO_Pin_2
#define FSMC_A12 GPIOG
//A13-G3
#define FSMC_A13_CLK RCC_APB2Periph_GPIOG
#define FSMC_GPIO_A13 GPIO_Pin_3
#define FSMC_A13 GPIOG
//A14-G4
#define FSMC_A14_CLK RCC_APB2Periph_GPIOG
#define FSMC_GPIO_A14 GPIO_Pin_4
#define FSMC_A14 GPIOG
//A15-G5
#define FSMC_A15_CLK RCC_APB2Periph_GPIOG
#define FSMC_GPIO_A15 GPIO_Pin_5
#define FSMC_A15 GPIOG
//A16-D11
#define FSMC_A16_CLK RCC_APB2Periph_GPIOD
#define FSMC_GPIO_A16 GPIO_Pin_11
#define FSMC_A16 GPIOD
//A17-D12
#define FSMC_A17_CLK RCC_APB2Periph_GPIOD
#define FSMC_GPIO_A17 GPIO_Pin_12
#define FSMC_A17 GPIOD
//A18-D13
#define FSMC_A18_CLK RCC_APB2Periph_GPIOD
#define FSMC_GPIO_A18 GPIO_Pin_13
#define FSMC_A18 GPIOD
//D0-D14
#define FSMC_D0_CLK RCC_APB2Periph_GPIOD
#define FSMC_GPIO_D0 GPIO_Pin_14
#define FSMC_D0 GPIOD
//D1-D15
#define FSMC_D1_CLK RCC_APB2Periph_GPIOD
#define FSMC_GPIO_D1 GPIO_Pin_15
#define FSMC_D1 GPIOD
//D2-D0
#define FSMC_D2_CLK RCC_APB2Periph_GPIOD
#define FSMC_GPIO_D2 GPIO_Pin_0
#define FSMC_D2 GPIOD
//D3-D1
#define FSMC_D3_CLK RCC_APB2Periph_GPIOD
#define FSMC_GPIO_D3 GPIO_Pin_1
#define FSMC_D3 GPIOD
//D4-E7
#define FSMC_D4_CLK RCC_APB2Periph_GPIOE
#define FSMC_GPIO_D4 GPIO_Pin_7
#define FSMC_D4 GPIOE
//D5-E8
#define FSMC_D5_CLK RCC_APB2Periph_GPIOE
#define FSMC_GPIO_D5 GPIO_Pin_8
#define FSMC_D5 GPIOE
//D6-E9
#define FSMC_D6_CLK RCC_APB2Periph_GPIOE
#define FSMC_GPIO_D6 GPIO_Pin_9
#define FSMC_D6 GPIOE
//D7-E10
#define FSMC_D7_CLK RCC_APB2Periph_GPIOE
#define FSMC_GPIO_D7 GPIO_Pin_10
#define FSMC_D7 GPIOE
//D8-E11
#define FSMC_D8_CLK RCC_APB2Periph_GPIOE
#define FSMC_GPIO_D8 GPIO_Pin_11
#define FSMC_D8 GPIOE
//D9-E12
#define FSMC_D9_CLK RCC_APB2Periph_GPIOE
#define FSMC_GPIO_D9 GPIO_Pin_12
#define FSMC_D9 GPIOE
//D10-E13
#define FSMC_D10_CLK RCC_APB2Periph_GPIOE
#define FSMC_GPIO_D10 GPIO_Pin_13
#define FSMC_D10 GPIOE
//D11-E14
#define FSMC_D11_CLK RCC_APB2Periph_GPIOE
#define FSMC_GPIO_D11 GPIO_Pin_14
#define FSMC_D11 GPIOE
//D12-E15
#define FSMC_D12_CLK RCC_APB2Periph_GPIOE
#define FSMC_GPIO_D12 GPIO_Pin_15
#define FSMC_D12 GPIOE
//D13-D8
#define FSMC_D13_CLK RCC_APB2Periph_GPIOD
#define FSMC_GPIO_D13 GPIO_Pin_8
#define FSMC_D13 GPIOD
//D14-D9
#define FSMC_D14_CLK RCC_APB2Periph_GPIOD
#define FSMC_GPIO_D14 GPIO_Pin_9
#define FSMC_D14 GPIOD
//D15-D10
#define FSMC_D15_CLK RCC_APB2Periph_GPIOD
#define FSMC_GPIO_D15 GPIO_Pin_10
#define FSMC_D15 GPIOD
//CS (NE3)对应的基地址0x68000000-G10
#define FSMC_CS_CLK RCC_APB2Periph_GPIOG
#define FSMC_GPIO_CS GPIO_Pin_10
#define FSMC_CS GPIOG
//WE-D5(写使能)
#define FSMC_WE_CLK RCC_APB2Periph_GPIOD
#define FSMC_GPIO_WE GPIO_Pin_5
#define FSMC_WE GPIOD
//OE-D4(读使能)
#define FSMC_OE_CLK RCC_APB2Periph_GPIOD
#define FSMC_GPIO_OE GPIO_Pin_4
#define FSMC_OE GPIOD
//LB-E1 (数据掩码低位)
#define FSMC_LB_CLK RCC_APB2Periph_GPIOE
#define FSMC_GPIO_LB GPIO_Pin_1
#define FSMC_LB GPIOE
//UB-E0 (数据掩码高位)
#define FSMC_UB_CLK RCC_APB2Periph_GPIOE
#define FSMC_GPIO_UB GPIO_Pin_0
#define FSMC_UB GPIOE
void SRAM_Config(void);
#endif
SRAM.C
#include "stm32f10x.h"
#include "sram.h"
static void SRAM_GPIO_Config(void)
{
RCC_APB2PeriphClockCmd(FSMC_A0_CLK | FSMC_A1_CLK | FSMC_A2_CLK |FSMC_A3_CLK
| FSMC_A4_CLK | FSMC_A5_CLK | FSMC_A6_CLK |FSMC_A7_CLK
| FSMC_A8_CLK | FSMC_A9_CLK | FSMC_A10_CLK |FSMC_A11_CLK
| FSMC_A12_CLK | FSMC_A13_CLK | FSMC_A14_CLK |FSMC_A15_CLK
| FSMC_A16_CLK | FSMC_A17_CLK | FSMC_A18_CLK
| FSMC_D0_CLK | FSMC_D1_CLK | FSMC_D2_CLK |FSMC_D3_CLK
| FSMC_D4_CLK | FSMC_D5_CLK | FSMC_D6_CLK |FSMC_D7_CLK
| FSMC_D8_CLK | FSMC_D9_CLK | FSMC_D10_CLK |FSMC_D11_CLK
| FSMC_D12_CLK | FSMC_D13_CLK | FSMC_D14_CLK |FSMC_D15_CLK
| FSMC_CS_CLK | FSMC_WE_CLK | FSMC_OE_CLK |FSMC_LB_CLK | FSMC_UB_CLK,ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_A0;
GPIO_Init(FSMC_A0,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_A1;
GPIO_Init(FSMC_A1,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_A2;
GPIO_Init(FSMC_A2,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_A3;
GPIO_Init(FSMC_A3,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_A4;
GPIO_Init(FSMC_A4,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_A5;
GPIO_Init(FSMC_A5,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_A6;
GPIO_Init(FSMC_A6,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_A7;
GPIO_Init(FSMC_A7,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_A8;
GPIO_Init(FSMC_A8,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_A9;
GPIO_Init(FSMC_A9,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_A10;
GPIO_Init(FSMC_A10,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_A11;
GPIO_Init(FSMC_A11,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_A12;
GPIO_Init(FSMC_A12,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_A3;
GPIO_Init(FSMC_A13,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_A14;
GPIO_Init(FSMC_A14,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_A15;
GPIO_Init(FSMC_A15,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_A16;
GPIO_Init(FSMC_A16,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_A17;
GPIO_Init(FSMC_A17,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_A18;
GPIO_Init(FSMC_A18,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_D0;
GPIO_Init(FSMC_D0,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_D1;
GPIO_Init(FSMC_D1,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_D2;
GPIO_Init(FSMC_D2,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_D3;
GPIO_Init(FSMC_D3,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_D4;
GPIO_Init(FSMC_D4,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_D5;
GPIO_Init(FSMC_D5,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_D6;
GPIO_Init(FSMC_D6,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_D7;
GPIO_Init(FSMC_D7,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_D8;
GPIO_Init(FSMC_D8,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_D9;
GPIO_Init(FSMC_D9,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_D10;
GPIO_Init(FSMC_D10,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_D11;
GPIO_Init(FSMC_D11,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_D12;
GPIO_Init(FSMC_D12,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_D13;
GPIO_Init(FSMC_D13,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_D14;
GPIO_Init(FSMC_D14,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_D15;
GPIO_Init(FSMC_D15,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_CS;
GPIO_Init(FSMC_CS,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_WE;
GPIO_Init(FSMC_WE,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_OE;
GPIO_Init(FSMC_OE,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_LB;
GPIO_Init(FSMC_LB,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=FSMC_GPIO_UB;
GPIO_Init(FSMC_UB,&GPIO_InitStructure);
}
作者:普通网友