前言:FMC(Flexible Memory Controller) 靈活存儲控制器,是STM32針對各種存儲器外設,所推出的一種總線控制器;可以配置多種存儲器接口用來通信;
那么FMC和FSMC有什么區別呢?FMC是在FSMC(Flexible Static Memory Controller)的基礎上擴展了SDRAM的總線控制器;沒什么區別;
1 靈活存儲控制器類型
fmc控制器用來配置單片機與各種存儲器的通信配置;不同存儲器類型的配置不同;
fmc同一時刻只能控制一個存儲器外設 (因為fmc配置的地址線,數據線和控制線是共享的) ;每種存儲區內都有自己的bank片選信號;
fmc包含三種類型的存儲控制器:NOR/PSRAM/SRAM存儲控制器,NAND控制器,SDRAM控制器;
下圖給出了三種存儲控制器的默認地址,以及地址重映射配置參數;還給出了NOR/PSRAM部分地址相關配置參數;
可知控制器內部總線的尋址范圍為2^26線;尋址的最小單位為byte;
如果尋址單位為16bits數據時,則內部總線的地址線bit0不使用;比如當fmc_addr[23:16]連接到單片機,內部總線stm_addr對應地址應該為[24:17];
概括而言,就是代碼中操作的地址是fmc內部地址總線的地址;而單片機接口接出的地址對應的是存儲器的地址;
AHB 時鍾 (fmc_hclk) 是 FMC 寄存器訪問的參考時鍾單位;
2 NOR/PSRAM/SRAM存儲控制器
2.1 引腳說明
A[25:0]引腳: 地址總線,為共享信號;為外部存儲器的地址總線,不是內部fmc尋址時的地址總線;
D[31:0]引腳: 數據總線,為共享信號;可以配置數據位為8bits/16bits/32bits;
NE[4:1]引腳: fmc控制的nor/psram/sram存儲器的默認地址為0x6000_0000到0x6fff_ffff;分為4個bank;每個bank都有唯一的片選信號NE[4:1];
FMC_CLK引腳: FMC在驅動NOR/PSRAM/SRAM存儲器時,通常工作於異步模式下,不需要使用FMC_CLK信號線;
FMC在驅動NOR/PSRAM存儲器時,只有工作在同步訪問的突發模式下時,才會需要使用FMC_CLK信號線;
FMC_CLK信號是fmc_ker_ck分頻得到的信號,通過配置CCLKEN位來決定是否啟用;
NOE引腳: 讀數據信號;單片機讀取數據;
NWE引腳: 寫數據信號;單片機發送數據;
NL(NADV)引腳: 鎖存使能,nor flash的地址有效信號;
NWAIT引腳: nor flash輸入到單片機的信號,表示nor flash准備好了,等待輸入;
NBL[3:0]引腳: PSRAM/SRAM的字節輸出通道輸出引腳,控制字節0到字節3的使能;
信號引腳"N"為前綴,表示該信號低電平有效;
2.2 參數配置:nor flash舉例
許多參數用不到,並沒有了解的十分深入,具體配置如下;
//nor 參數配置 hnor.Instance=FMC_NORSRAM_DEVICE; //存儲器選擇 hnor.Extended=FMC_NORSRAM_EXTENDED_DEVICE; //擴展寄存器地址 讀寫可不同時序 hnor.Init.NSBank=FMC_NORSRAM_BANK1; //選擇FMC SRAM Bank1區 hnor.Init.DataAddressMux=FMC_DATA_ADDRESS_MUX_DISABLE; //使能數據地址不復用 hnor.Init.MemoryType=FMC_MEMORY_TYPE_NOR; //選擇存儲器類型 hnor.Init.MemoryDataWidth=FMC_NORSRAM_MEM_BUS_WIDTH_16; //數據位寬為16位 hnor.Init.BurstAccessMode=FMC_BURST_ACCESS_MODE_DISABLE;//禁止讀突發訪問 讀操作工作在異步模式 hnor.Init.WaitSignal=FMC_WAIT_SIGNAL_DISABLE; hnor.Init.WaitSignalPolarity=FMC_WAIT_SIGNAL_POLARITY_LOW; hnor.Init.WaitSignalActive=FMC_WAIT_TIMING_BEFORE_WS; hnor.Init.AsynchronousWait=FMC_ASYNCHRONOUS_WAIT_DISABLE; hnor.Init.WriteOperation=FMC_WRITE_OPERATION_ENABLE; hnor.Init.ExtendedMode=FMC_EXTENDED_MODE_DISABLE; //禁止擴展模式 此時讀寫按照模式2進行 hnor.Init.WriteBurst=FMC_WRITE_BURST_DISABLE; //禁止寫突發訪問 寫操作工作在異步模式 //hnor.Init.ContinuousClock=FMC_CONTINUOUS_CLOCK_SYNC_ASYNC; hnor.Init.WriteFifo=FMC_WRITE_FIFO_ENABLE; //讀寫數據應該底層是按位操作先的,然后再字節操作;所以要fifo; hnor.Init.PageSize=FMC_PAGE_SIZE_NONE;
2.3 時序說明
同步時序配置:具體看中文參考手冊的各個模式的時序;
異步時序配置:概括來說,可以將異步時序配置成 "使能擴展模式" 和 "禁止擴展模式" 兩種模式;
(1)使能擴展模式:fmc的時序可以混合使用A,B,C,D模式;比如使用模式A讀取,而在模式B寫入;
(2)禁止擴展模式:當fmc配置為SRAM/PSRAM 存儲器類型時,默認使用模式1時序 (FMC_BCRx 寄存器中MTYP = 0x0 或 0x01);
當fmc配置為 NOR 存儲器類型時,默認使用模式2時序 (FMC_BCRx 寄存器中MTYP = 0x10);
2.3.1 nor flash時序說明
nor flash可以工作在同步或異步模式,以工作在異步模式下的nor flash為例;nor flash的時序通過如下結構體配置:
/*nor時序的單位時鍾來自AHB_HCLK,假設配置為了100MHz*/ /*NADV高電平(ADDSET) = AddressSetupTime + AddressHoldTime;*/ /*NADV低電平 = DataSetupTime + 1hclk時鍾周期; */ Timing.AddressSetupTime=8; Timing.AddressHoldTime=2; Timing.DataSetupTime=7; //DATAST //Timing.BusTurnAroundDuration=0; //讀寫轉換插入時間周期為0 //Timing.CLKDivision=0; //FMC輸出時鍾分頻系數 在異步操作時無效 //Timing.DataLatency=0; //數據延遲 在異步操作時無效 //Timing.AccessMode=FMC_ACCESS_MODE_A; //時序操作模式A 在FMC_BCRx寄存器的ExtMode位為0時此設置無效
默認nor flash工作在模式2時序下,模式2的時序如下所示:
對於寫入數據而言,在fpga端,可以簡化為NWE使能的時候寫入數據就行;
對於讀取數據而言,在fpga端,可以簡化為NOE使能的時候把數據放入數據線就行;
3 源碼github
單片機源碼:https://gitee.com/caesura/stm32h7_demo
fpga源碼:https://gitee.com/caesura/fpga_demo