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
『本文转载自网络,皇冠最新app版本的版权归原作者所有,如有侵权请联系删除』