基於STM32F407VGT6單片機的FSMC與FPGA通信

1. 關於FSMC

FSMC引腳定義:
地址線:A16-23 共8根地址線

數據線有16根(看單片機的原理圖)

控制信號RD、WR、NE1/NCE2,這兩個片選都接的是PD7,NE1即選中BAN1,用於擴展外部SRAM,FPGA相當於掛在單片機的BANK1,實質就是單片機進行讀寫FPGA。

2.FPGA測試程序(網上找的)

module STM32_FPGA(
                 input  main_clk,
                     // output arm_clk,
                      
                      output led,
                      
                      input [2:0] addr,
                      inout [15:0] data,
                      input FPGA_CS0,//FPGA片選
                      input RD,
                      input WR
                      
                     );


wire clk;

pll_50M    pll_50M_inst (
                                .inclk0 ( main_clk ),//25M
                                .c0 ( clk ),         //50M
                                .c1 ( arm_clk )      //8M                        
                             );


//reg [24:0] cnt = 0;
//always @(posedge clk)
 // cnt <= cnt + 1'b1;             

//assign led = cnt[24];


//AWE的上升沿,將數據寫入FPGA寄存器

reg [15:0] ARM_FPGA_REG0;                     
reg [15:0] ARM_FPGA_REG1;
reg [15:0] ARM_FPGA_REG2;                     
reg [15:0] ARM_FPGA_REG3;                     
reg [15:0] ARM_FPGA_REG4;
reg [15:0] ARM_FPGA_REG5;                     
reg [15:0] ARM_FPGA_REG6;                     
reg [15:0] ARM_FPGA_REG7;                     
                     

wire rd_en = ~FPGA_CS0 && ~RD;

reg [15:0] data_reg;                     
                             
always @(*)
begin                                                
   if(rd_en)                                 
     begin                                           
        case(addr[2:0])                              
         3'd0   :  data_reg <= ARM_FPGA_REG0;        
         3'd1   :  data_reg <= ARM_FPGA_REG1;        
         3'd2   :  data_reg <= ARM_FPGA_REG2;        
         3'd3   :  data_reg <= ARM_FPGA_REG3;        
         3'd4   :  data_reg <= ARM_FPGA_REG4;        
         3'd5   :  data_reg <= ARM_FPGA_REG5;        
         3'd6   :  data_reg <= ARM_FPGA_REG6;        
         3'd7   :  data_reg <= ARM_FPGA_REG7;        
         default:  ;                                 
        endcase                                               
     end                                                                                                      
end                                                           

/* AWE上升沿DSP的數據寫入FPGA,即sampling point */                     
                     
reg WR_tmp1;
reg WR_tmp2;
always @(posedge main_clk)//之前是CLK
begin
   WR_tmp1 <= WR;
    WR_tmp2 <= WR_tmp1;
end                     
                     
wire WR_RISING = ~WR_tmp2 && WR_tmp1;//與clk同步         

                 
always @(*)                                      
begin                                              
  if(WR_RISING)                                
     begin                                    
        case(addr[2:0])                       
         3'd0   :  ARM_FPGA_REG0 <= data;     
         3'd1   :  ARM_FPGA_REG1 <= data;     
         3'd2   :  ARM_FPGA_REG2 <= data;     
         3'd3   :  ARM_FPGA_REG3 <= data;     
         3'd4   :  ARM_FPGA_REG4 <= data;     
         3'd5   :  ARM_FPGA_REG5 <= data;     
         3'd6   :  ARM_FPGA_REG6 <= data;     
         3'd7   :  ARM_FPGA_REG7 <= data;     
         default:  ;                          
        endcase                                        
     end                                      
end                                                

assign data =     rd_en ? data_reg : 16'hzzzz;
                     
endmodule

3.STM32測試程序

//讀寫函數

#define fpga_write(offset,data)    *((volatile unsigned short int *)(0x60000000 + (offset << 17))) = data

#define fpga_read(offset)    *((volatile unsigned short int *)(0x60000000 + (offset << 17)))

//FSMC初始化函數,用LCD改的

void fcmc_Init(void )
{
  GPIO_InitTypeDef GPIO_InitStructure;
  FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
  FSMC_NORSRAMTimingInitTypeDef  p;
    

    RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOG, ENABLE);
    

    GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_FSMC);
    
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource3, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource6, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource7, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource10, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource11, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_FSMC);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 |
                                                                GPIO_Pin_6 | 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_Init(GPIOD, &GPIO_InitStructure);

    GPIO_PinAFConfig(GPIOE, GPIO_PinSource2 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource3 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource4 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource5 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource6 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource7 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource8 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource9 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource10, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource11, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource12, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource13, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource14, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource15, GPIO_AF_FSMC);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | 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_Init(GPIOE, &GPIO_InitStructure);
    
    GPIO_PinAFConfig(GPIOG, GPIO_PinSource13, GPIO_AF_FSMC);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
    GPIO_Init(GPIOG, &GPIO_InitStructure);
    

  p.FSMC_AddressSetupTime = 1;
  p.FSMC_AddressHoldTime = 0;
  p.FSMC_DataSetupTime = 4;
  p.FSMC_BusTurnAroundDuration = 0;
  p.FSMC_CLKDivision = 0;
  p.FSMC_DataLatency = 0;
  p.FSMC_AccessMode = FSMC_AccessMode_A;

  FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1;
  FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Enable;
  FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;
  FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
  FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
  FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;  
  FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
  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 = &p;
  FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;

  FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); 

  //FSMC Bank1_SRAM1 Bank
    FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE); 
    delay_ms(50);
}

4.最後用quartusii中sigtapII測試

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章