1、FMC簡介
STM32F429 使用 FMC 外設來管理擴展的存儲器, FMC 是 Flexible Memory Controller的縮寫,譯為可變存儲控制器。它可以用於驅動包括 SRAM、 SDRAM、 NOR FLASH 以及NAND FLSAH 類型的存儲器。在其它系列的 STM32 控制器中,只有 FSMC 控制器(Flexible Static Memory Controller),譯為可變靜態存儲控制器,所以它們不能驅動 SDRAM這樣的動態存儲器,因為驅動 SDRAM 時需要定時刷 新, STM32F429 的 FMC 外設才支持該功能,且只支持普通的 SDRAM,不支持 DDR 類型的 SDRAM。我們只講述 FMC 的SDRAM 控制功能。
2、FMC模塊框圖解析
(1)通訊引腳
在框圖的右側是 FMC 外設相關的控制引腳,由於控制不同類型存儲器的時候會有一些不同的引腳,看起來有非常多, 其中地址線 FMC_A 和數據線 FMC_D 是所有控制器都共用的。
(2)存儲器控制器
上面不同類型的引腳是連接到 FMC 內部對應的存儲控制器中的。 NOR/PSRAM/SRAM設備使用相同的控制器, NAND/PC 卡設備使用相同的控制器,而 SDRAM 存儲器使用獨立的控制器。不同的控制器有專用的寄存器用於配置其工作模式。
控制 SDRAM 的有 FMC_SDCR1/FMC_SDCR2 控制寄存器、控制 SDRAM 的有 FMC_SDCR1/FMC_SDCR2 控制寄存器、刷新定時器寄存器。其中控制寄存器及時序寄存器各有 2 個,分別對應於 SDRAM 存儲區域 1 和存儲區域 2 的配置。
FMC_SDCR 控制寄存器可配置 SDCLK 的同步時鍾頻率、突發讀使能、寫保護、 CAS延遲、行列地址位數以及數據總線寬度等。
FMC_SDTR 時序寄存器用於配置 SDRAM 訪問時的各種時間延遲,如 TRP 行預充電延遲、 TMRD 加載模式寄存器激活延遲等。
FMC_SDCMR 命令模式寄存器用於存儲要發送到 SDRAM 模式寄存器的配置,以及要向 SDRAM 芯片發送的命令。
FMC_SDRTR 用於配置 SDRAM 的自動刷新周期。
(3) 時鍾控制邏輯
FMC 外設掛載在 AHB3 總線上,時鍾信號來自於 HCLK(默認 180MHz),控制器的時鍾輸出就是由它分頻得到。如 SDRAM 控制器的 FMC_SDCLK 引腳輸出的時鍾,是用於與SDRAM 芯片進行同步通訊,它的時鍾頻率可通過 FMC_SDCR1 寄存器的 SDCLK 位配置,可以配置為 HCLK 的 1/2 或 1/3,也就是說,與 SDRAM 通訊的同步時鍾最高頻率為90MHz。
3、 FMC 的地址映射
FMC 連接好外部的存儲器並初始化后,就可以直接通過訪問地址來讀寫數據,這種地址訪問與 I2C EEPROM、 SPI FLASH 的不一樣,后兩種方式都需要控制 I2C 或 SPI 總線給存儲器發送地址,然后獲取數據;在程序里,這個地址和數據都需要分開使用不同的變量存儲,並且訪問時還需要使用代碼控制發送讀寫命令。而使用 FMC 外接存儲器時,其存儲單元是映射到 STM32 的內部尋址空間的;在程序里,定義一個指向這些地址的指針,然后就可以通過指針直接修改該存儲單元的內容, FMC 外設會自動完成數據訪問過程,讀寫命令之類的操作不需要程序控制。 FMC 的地址映射見圖 26-14。
圖中左側的是 Cortex-M4 內核的存儲空間分配,右側是 STM32 FMC 外設的地址映射。可以看到 FMC 的 NOR/PSRAM/SRAM/NAND FLASH 以及 PC 卡的地址都在 External RAM地址空間內,而 SDRAM 的地址是分配到 External device 區域的。正是因為存在這樣的地址映射,使得訪問 FMC 控制的存儲器時,就跟訪問 STM32 的片上外設寄存器一樣(片上外設的地址映射即圖中左側的“ Peripheral”區域)。
(1)SDRAM 的存儲區域
FMC 把 SDRAM 的存儲區域分成了 Bank1 和 Bank2 兩塊,這里的 Bank 與 SDRAM 芯片內部的 Bank 是不一樣的概念,只是 FMC 的地址區域划分而已。每個 Bank 有不一樣的起始地址,且有獨立的 FMC_SDCR 控制寄存器和 FMC_SDTR 時序寄存器,還有獨立的FMC_SDCKE 時鍾使能信號線和 FMC_SDCLK 信號線。 FMC_SDCKE0 和 FMC_SDCLK0對應的存儲區域 1 的地址范圍是 0xC000 0000-0xCFFF FFFF,而 FMC_SDCKE1 和FMC_SDCLK1 對應的存儲區域 2 的地址范圍是 0xD000 0000- 0xDFFF FFFF。 當程序里控制內核訪問這些地址的存儲空間時, FMC 外設會即會產生對應的時序,對它外接的SDRAM 芯片進行讀寫。
(2)External RAM 與 External device 的區別
比較遺憾的是 FMC 給 SDRAM 分配的區域不在 External RAM 區,這個區域可以直接執行代碼,而 SDRAM 所在的 External device 區卻不支持這個功能。這里說的可直接執行代碼的特性就是在“常用存儲器”章節介紹的 XIP(eXecute In Place)特性,即存儲器上若存儲了代碼, CPU 可直接訪問代碼執行,無需緩存到其它設備上再運行;而且 XIP 特性還對存儲器的種類有要求, SRAM/SDRAM 及 NOR Flash 都支持這種特性, 而 NAND FLASH及 PC 卡是不支持 XIP 的。結合存儲器的特性和 STM32 FMC 存儲器種類的地址分配,就發現它的地址規划不合理了, NAND FLASH 和 PC 卡這些不支持 XIP 的存儲器卻占據了External RAM 的空間,而支持 XIP 的 SDRAM 存儲器的空間卻被分配到了 Extern device 區。
為了解決這個問題,通過配置“ SYSCFG_MEMRMP”寄存器的“SWP_FMC”寄存器位可用於交換 SDRAM 與 NAND/PC 卡的地址映射,使得存儲在 SDRAM 中的代碼能被執行,只是由於 SDRAM 的最高同步時鍾是 90MHz,代碼的執行速度會受影響。
這里主要講解當 STM32 的片內 SRAM 不夠用時使用 SDRAM 擴展內存,但假如程序太大,它的程序空間 FLASH 不夠用怎么辦呢?首先是裁剪代碼,目前 STM32F429 系列芯片內部 FLASH 空間最高可達 2MB,實際應用中只要我們把代碼中的圖片、字模等占據大空間的內容放到外部存儲器中,純粹的代碼很難達到 2MB。如果還不夠用,非要擴展程序空間的話,一種方法是使用 FMC 擴展 NOR FLASH,把程序存儲到 NOR 上,程序代碼能夠直接在 NOR FLASH 上執行。另一種方法是把程序存儲在其它外部存儲器,如 SD 卡,需要時把存儲在 SD 卡上的代碼加載到 SRAM 或 SDRAM 上,再在 RAM 上執行代碼。如果 SDRAM 不是用於存儲可執行代碼,只是用來保存數據的話,在 External RAM 或Exteranl device 區域都沒有區別,不需要與 NAND 的映射地址交換。