1、FSMC简介:FSMC即灵敏的静态存储控制器,FSMC办理1GB空间,具有4个Bank衔接外部存储器,每个Bank有独立的片选信号和独立的时序装备;支撑的存储器类型有SRAM、PSRAM、NOR/ONENAND、ROM、LCD接口(支撑8080和6800形式)、NANDFlash和16位的PCCard。
2、在规划中将FPGA作为SRAM来驱动,运用库函数来完成FSMC的初始化装备代码如下:
//初始化外部SRAM
void FSMC_SRAM_Init(void)
{
FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure; //界说FSMC初始化的结构体变量
FSMC_NORSRAMTimingInitTypeDef readWriteTIming; //用来设置FSMC读时序和写时序的指针变量
GPIO_InitTypeDef GPIO_InitStructure; //初始化FSMC总线的IO口
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOE|RCC_APB2Periph_AFIO,ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC,ENABLE); //敞开FSMC的时钟
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_14
|GPIO_Pin_15|GPIO_Pin_0|GPIO_Pin_1
|GPIO_Pin_7|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_4|GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //IO口装备为复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=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_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &GPIO_InitStructure);
readWriteTIming.FSMC_AddressSetupTIme = 14;
readWriteTIming.FSMC_AddressHoldTime = 0x00;
readWriteTiming.FSMC_DataSetupTime = 16;
readWriteTiming.FSMC_BusTurnAroundDuration = 0;
readWriteTiming.FSMC_CLKDivision = 0x00;
readWriteTiming.FSMC_DataLatency = 0x00;
readWriteTiming.FSMC_AccessMode = FSMC_AccessMode_A;
FSMC_NORSRAMInitStructure.FSMC_Bank=FSMC_Bank1_NORSRAM1;
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
FSMC_NORSRAMInitStructure.FSMC_MemoryType =FSMC_MemoryType_SRAM;
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth= FSMC_MemoryDataWidth_16b;
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode=FSMC_BurstAccessMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait=FSMC_AsynchronousWait_Disable;
FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &readWriteTiming;
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &readWriteTiming;
FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE);
delay_ms(50);
}
FPGA代码:
//fsmc read / write ep4ce6 demo
module fsmc(
ab, //address
db, //data
wrn, //wr
rdn, //rd
resetn, //resetn
csn, //cs
clk
);
input[2:0] ab;
inout[15:0] db;
input wrn;
input rdn;
input resetn;
input csn;
input clk;
reg [15:0] ina = 16'd0; //存储数据供ARM读
reg [15:0] inb = 16'd1;
reg [15:0] inc = 16'd2;
reg [15:0] ind = 16'd3;
reg [15:0] ine = 16'd4;
reg [15:0] inf = 16'd5;
reg [15:0] ing = 16'd6;
reg [15:0] inh = 16'd7;
reg [15:0] outa;
reg [15:0] outb;
reg [15:0] outc;
reg [15:0] outd;
reg [15:0] oute;
reg [15:0] outf;
reg [15:0] outg;
reg [15:0] outh;
wire rd;
wire wr;
reg [15:0] indata;
assign rd = !(csn & rdn); //get rd pulse ____|~~~~|______
assign wr = !(csn & wrn) ; //get wr pulse ____|~~~~|______
/*********当不进行读写操作时db=indata*********
*********当进行写操作时db=16'hzzzz**********
*********当进行读操作时db=indata**********/
assign db = rd? indata:16'hzzzz;
//write data, 依据地址线挑选八个空间写入,每个空间16位
always @(negedge wr or negedge resetn)
begin
if(!resetn)begin
outa <= 16'h0000;
outb <= 16'h0000;
outc <= 16'h0000;
outd <= 16'h0000;
oute <= 16'h0000;
outf <= 16'h0000;
outg <= 16'h0000;
outh <= 16'h0000;
end else begin
case (ab)
3'b000:outa <= db;
3'b001:outb <= db;
3'b010:outc <= db;
3'b011:outd <= db;
3'b100:oute <= db;
3'b101:outf <= db;
3'b110:outg <= db;
3'b111:outh <= db;
default:;
endcase
end
end
//red data 依据地址线挑选8个空间读取,每个空间 16位
always @(rd or !resetn)
begin
if(!resetn)indata <= 16'h0000;
else begin
case (ab)
3'b000:indata <= ina;
3'b001:indata <= inb;
3'b010:indata <= inc;
3'b011:indata <= ind;
3'b100:indata <= ine;
3'b101:indata <= inf;
3'b110:indata <= ing;
3'b111:indata <= inh;
default:;
endcase
end
end
endmodule