STM32
直播中

王军

8年用户 1858经验值
私信 关注
[问答]

怎样去编写FSMC的初始化配置代码

FSMC是什么?
怎样去编写FSMC的初始化配置代码?

回帖(1)

李伟

2021-10-9 12:14:39
  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; // orignal code : !(csn & rdn) = !csn | !rdn (摩根定律) get rd pulse ____|~~~~|______
  assign wr = !csn & !wrn; //orignal code : !(csn & wrn) = !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
举报

更多回帖

发帖
×
20
完善资料,
赚取积分