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
評論
查看更多