FMC STM32H7 SDRAM

如何無痛使用片外SDRAM?

stm32 已經成功初始化了 STM32H7 上的外部 SDRAM(32MB) 如何在開發中無痛使用SDRAM 使它像普通 RAM 一樣“自然地”使用?

[todo] 重要

MMT(Memory Management Tool) of STM32CubeMx

The Memory Management Tool (MMT) displays the memory map and defines memory attributes applied in user projects opened/created in STM32CubeMX. The tool is located in the “Tools” tab. It allows the user to declare memory regions at application level (referred to as “application region” or AppReg in this document). The hardware constraints related to TrustZone?, Memory Protection Unit and the memory granularity are handled by MMT and made transparent to the user, so that the focus can be put on the memory regions at the application level. A linker file is generated according to the application regions declared and configured by the user. The MMT key features are:

  • Memory map display
  • Application regions management
  • Linker file generation

MMT interacts with peripherals starting from the moment the user enters its interface:

  • Checks their settings
  • Updates other peripherals involved in memory map configuration

The peripherals are updated only when the first toggle button is ON.?

Apply periph.png


MMT updates the linker scripts only when the second toggle button is ON.?

Apply linker.png

STM32H7 FMC SDRAM 配置

嵌入式STM32上設置好外部SDRAM并不難。

// code verified OK STM32H743IIT6 -?W9825G6KH-6I - 32MB
#include "main.h"
#include "SDRAM_W9825G6KH.h"   //externel sdram memory devicestatic void FMC_SDRAM_ClockInit(void);
static void FMC_SDRAM_GPIOInit(void);
void SDRAM_Init(void);/*
** 功能:FMC的SDRAM控制器初始化 + 外部SDRAM存儲設備初始化
** 配置:1. 時鐘源來自PLL2也需要適配。GPIO引腳也需要適配。
**       2. 初始化SDRAM控制器+外設時序初始化
** 注意:注意棧溢出。
*/
void SDRAM_Init(void)
{/*** 第一步:配置SDRAM控制器的時鐘源*/FMC_SDRAM_ClockInit();/*** 第二步:配置SDRAM控制器與外部存儲設備的引腳*/FMC_SDRAM_GPIOInit();/*** 第三步:FMC SDRAM 控制器初始化 -----------------------------*/FMC_SDRAM_TimingTypeDef  SDRAM_Timing = {0};SDRAM_HandleTypeDef      hsdram = {0};/* SDRAM device configuration */hsdram.Instance                = FMC_SDRAM_DEVICE;             /* SDRAM在BANK5,6 */hsdram.Init.SDBank             = FMC_SDRAM_BANK1;              /* 第一個SDRAM BANK */hsdram.Init.ColumnBitsNumber   = FMC_SDRAM_COLUMN_BITS_NUM_9;  /* 列數量 */hsdram.Init.RowBitsNumber      = FMC_SDRAM_ROW_BITS_NUM_13;    /* 行數量 */hsdram.Init.MemoryDataWidth    = FMC_SDRAM_MEM_BUS_WIDTH_16;   /* 數據寬度為16位 */       hsdram.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4; /* 一共4個BANK */hsdram.Init.CASLatency         = FMC_SDRAM_CAS_LATENCY_2;      /* CAS延遲為2個周期 */hsdram.Init.WriteProtection    = FMC_SDRAM_WRITE_PROTECTION_DISABLE;  /* 失能寫保護 */hsdram.Init.SDClockPeriod      = FMC_SDRAM_CLOCK_PERIOD_2;     /* SDRAM時鐘=fmc_ker_ck/2=220M/2=110M=9.1ns */hsdram.Init.ReadBurst          = FMC_SDRAM_RBURST_ENABLE;      /* 使能突發訪問 */hsdram.Init.ReadPipeDelay      = FMC_SDRAM_RPIPE_DELAY_1;      /* 讀通道延遲1個fmc_ker_ck時鐘周期 *//* Timing configuration for xxxMhz as SDRAM clock frequency */SDRAM_Timing.LoadToActiveDelay    = 2;  /* 加載模式寄存器到激活時間的延遲為2個時鐘周期 */SDRAM_Timing.ExitSelfRefreshDelay = 8;  /* 退出自刷新延遲為8個時鐘周期 */SDRAM_Timing.SelfRefreshTime      = 7;  /* 自刷新時間為7個時鐘周期 */SDRAM_Timing.RowCycleDelay        = 7;  /* 行循環延遲為7個時鐘周期 */SDRAM_Timing.WriteRecoveryTime    = 2;  /* 恢復延遲為2個時鐘周期 */SDRAM_Timing.RPDelay              = 2;  /* 行預充電延遲為2個時鐘周期 */SDRAM_Timing.RCDDelay             = 2;  /* 行到列延遲為2個時鐘周期 */if(HAL_SDRAM_Init(&hsdram, &SDRAM_Timing) != HAL_OK){ Error_Handler();}/* Program the SDRAM external device -----------------------** 第四步:外部 SDRAM 存儲設備的時序初始化*/__IO uint32_t tmpmrd =0;FMC_SDRAM_CommandTypeDef command;/* Step 1:  Configure a clock configuration enable command */command.CommandMode       = FMC_SDRAM_CMD_CLK_ENABLE;command.CommandTarget     = FMC_SDRAM_CMD_TARGET_BANK1;command.AutoRefreshNumber = 1;command.ModeRegisterDefinition = 0;HAL_SDRAM_SendCommand(&hsdram, &command, SDRAM_TIMEOUT);/* Step 2: 此時最小需要500us延遲;HAL庫粒度為1ms,延遲1ms */HAL_Delay(1);/* Step 3: Configure a PALL (precharge all) command */command.CommandMode   = FMC_SDRAM_CMD_PALL;command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;command.AutoRefreshNumber = 1;command.ModeRegisterDefinition = 0;HAL_SDRAM_SendCommand(&hsdram, &command, SDRAM_TIMEOUT);/* Step 4 : Configure a Auto-Refresh command */command.CommandMode   = FMC_SDRAM_CMD_AUTOREFRESH_MODE;command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;command.AutoRefreshNumber = 8;command.ModeRegisterDefinition = 0;HAL_SDRAM_SendCommand(&hsdram, &command, SDRAM_TIMEOUT);/* Step 5: Program the external memory mode register */tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1          |SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL   |SDRAM_MODEREG_CAS_LATENCY_2           |SDRAM_MODEREG_OPERATING_MODE_STANDARD |SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;command.CommandMode   = FMC_SDRAM_CMD_LOAD_MODE;command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;command.AutoRefreshNumber = 1;command.ModeRegisterDefinition = tmpmrd;HAL_SDRAM_SendCommand(&hsdram, &command, SDRAM_TIMEOUT);/* Step 6: Set the refresh rate counter */HAL_SDRAM_ProgramRefreshRate(&hsdram, REFRESH_COUNT); }/* configure PLL2->R as output at 220MHz for FMC */
static void FMC_SDRAM_ClockInit(void)
{RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_FMC;PeriphClkInitStruct.PLL2.PLL2M = 25;PeriphClkInitStruct.PLL2.PLL2N = 440;PeriphClkInitStruct.PLL2.PLL2P = 2;PeriphClkInitStruct.PLL2.PLL2Q = 2;PeriphClkInitStruct.PLL2.PLL2R = 2;  //220MHz PLL2R OutputPeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_0;PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;PeriphClkInitStruct.FmcClockSelection = RCC_FMCCLKSOURCE_PLL2;if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK){Error_Handler();}/* Peripheral clock enable */__HAL_RCC_FMC_CLK_ENABLE(); 
}/*
1. 配置FMC內的SDRAM控制器對外部SDRAM存儲設備物理連接引腳
*/
static void FMC_SDRAM_GPIOInit(void)
{GPIO_InitTypeDef GPIO_InitStruct ={0};/* 1. GPIO Ports Clock Enable */;//在MX_GPIO_Init函數里實現的。/** FMC GPIO ConfigurationPF0   ------> FMC_A0PF1   ------> FMC_A1PF2   ------> FMC_A2PF3   ------> FMC_A3PF4   ------> FMC_A4PF5   ------> FMC_A5PC0   ------> FMC_SDNWEPH2   ------> FMC_SDCKE0PH3   ------> FMC_SDNE0PF11  ------> FMC_SDNRASPF12  ------> FMC_A6PF13  ------> FMC_A7PF14  ------> FMC_A8PF15  ------> FMC_A9PG0   ------> FMC_A10PG1   ------> FMC_A11PE7   ------> FMC_D4PE8   ------> FMC_D5PE9   ------> FMC_D6PE10  ------> FMC_D7PE11  ------> FMC_D8PE12  ------> FMC_D9PE13  ------> FMC_D10PE14  ------> FMC_D11PE15  ------> FMC_D12PD8   ------> FMC_D13PD9   ------> FMC_D14PD10  ------> FMC_D15PD14  ------> FMC_D0PD15  ------> FMC_D1PG2   ------> FMC_A12PG4   ------> FMC_BA0PG5   ------> FMC_BA1PG8   ------> FMC_SDCLKPD0   ------> FMC_D2PD1   ------> FMC_D3PG15  ------> FMC_SDNCASPE0   ------> FMC_NBL0PE1   ------> FMC_NBL1*/GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF12_FMC;HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);GPIO_InitStruct.Pin = GPIO_PIN_0;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF12_FMC;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF12_FMC;HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_8|GPIO_PIN_15;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF12_FMC;HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);GPIO_InitStruct.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_PIN_0|GPIO_PIN_1;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF12_FMC;HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF12_FMC;HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);}

Flexible memory controller (FMC)

stm32h743iit6 RM0433

The flexible memory controller (FMC) includes three memory controllers:

  • The NOR/PSRAM memory controller

  • The NAND memory controller

  • The Synchronous DRAM (SDRAM/Mobile LPSDR SDRAM) controller

The FMC functional block makes the interface with: synchronous and asynchronous static memories, SDRAM memories, and NAND flash memory. Its main purposes are: ? to translate AXI transactions into the appropriate external device protocol ? to meet the access time requirements of the external memory devices

關于靜態存儲器、動態存儲器、Nand Flash

所有外部存儲器都與FMC控制器共享地址、數據和控制信號。 每個外部設備都通過唯一的片選信號進行訪問。FMC 每次只能對一個外部設備執行一次訪問。

FMC 的主要特性如下:

? 與靜態存儲器映射設備接口,包括: – 靜態隨機存取存儲器 (SRAM) – NOR 閃存/OneNAND 閃存 – PSRAM(4 個存儲體) – 帶有 ECC 硬件的 NAND 閃存,可校驗高達 8 KB 的數據 ? 與同步 DRAM(SDRAM/Mobile LPSDR SDRAM)存儲器接口 ? 支持突發模式,可更快地訪問同步設備,例如 NOR 閃存、PSRAM 和 SDRAM ? 可編程連續時鐘輸出,用于異步和同步訪問 ? 8、16 或 32 位寬數據總線 ? 每個存儲體均具有獨立的片選控制 ? 每個存儲體均具有獨立的配置 ? 寫使能和字節通道選擇輸出,可用于 PSRAM、SRAM 和 SDRAM 設備 ? 外部異步等待控制 ? 16 x 32 位深度的寫 FIFO 寫 FIFO 適用于所有存儲器控制器,包括: – 寫數據 FIFO,存儲待寫入存儲器的數據 – 寫地址 FIFO,用于存儲地址(最多 28 位)加上數據大小(最多 2 位)。在突發模式下工作時,僅存儲起始地址, 除非跨越頁邊界(對于 PSRAM 和 SDRAM)。在這種情況下,突發會被拆分成兩個 FIFO 條目。 ? 為 SDRAM 控制器提供 6 x64 位深度(6 x14 位地址標記)的可緩存讀取 FIFO。

啟動時,FMC 引腳必須由用戶應用程序配置。應用程序未使用的 FMC I/O 引腳可用于其他用途。更詳細地講,

在系統啟動時就需要根據外部設備類型和相關特性設置好FMC寄存器參數,并且直到系統再次復位或上電前不能再次修改FMC絕大多數的寄存器參數,除了極少部分on-the-fly特性的FMC寄存器比特位可以被再次修改,他們是:

  • FMC_PCR 寄存器中的 ECCEN 和 PBKEN 位

  • FMC_SR 寄存器中的 IFS、IRS 和 ILS 位

  • FMC_SDCMR 寄存器中的 MODE[2:0]、CTB1/CTB2、NRFS 和 MRD 位

  • FMC_SDRTR 寄存器中的 REIE 和 CRE 位。

當FMC使能時,需要按照如下流程去修改FMC的參數:

  1. 首先禁用 FMC,以防止在修改寄存器期間進一步訪問任何內存控制器。

  2. 更新所有必需的配置。

  3. 再次啟用 FMC。

使用 SDRAM 控制器時,如果在初始化階段后需要修改 SDCLK 時鐘比或刷新率,則必須遵循以下步驟。

  1. 將 SDRAM 設備置于自刷新模式。

  2. 通過復位 FMC_BCR1 寄存器中的 FMCEN 位來禁用 FMC。

  3. 更新所需參數。

  4. 一旦所有參數更新完成后,立即啟用 FMC。

  5. 最后,發送“時鐘配置啟用”命令退出自刷新模式。

FMC 內部模塊分析

FMC由以下幾個內部硬件電路模塊組成:

  • NOR Flash/PSRAM/SRAM 控制器;

  • NAND Flash 控制器;

  • SDRAM 控制器;

  • AXI 總線接口;

  • APB 總線接口(including the FMC configuration registers);內部模塊框圖如下:

image-20250607160942667

FMC 內部信號

image-20250607161312838

AHB interface

內部 CPU 核心通過 AHB 從機接口訪問 FMC 寄存器。

AHB 總線時鐘為訪問 FMC 寄存器提供參考時鐘。

AXI interface

內部 CPU 核心和其他總線上的主設備通過 AXI 從機接口訪問外部存儲設備。

AXI總線上的業務數據,會被轉換成外部設備協議。由于 AXI 數據總線為 64 位寬,AXI 業務數據可能會根據訪問數據的大小被拆分成多個連續的 32 位、16 位或 8 位訪問。FMC 片選 (FMC_NEx) 不會在連續的訪問之間切換。

當以下條件被觸發后,FMC就會產生一個AXI從機錯誤:

  • 讀取或寫入未啟用的 FMC 存儲區(存儲區 1 至 4)。

  • 在 FMC_BCRx 寄存器中的 FACCEN 位復位時讀取或寫入 NOR 閃存存儲區。

  • 寫入具有寫保護的 SDRAM 存儲區(FMC_SDCRx 寄存器中的 WP 位被置位)。

  • 超出 SDRAM 地址范圍(訪問保留地址范圍)。

  • 在 SDRAM 存儲區尚未初始化時嘗試對其進行讀/寫訪問。

當 BMAP[1:0] 配置的 FMC bank 基地址不支持 ADDR[31:28] 里的地址,FMC 便會產生一個 AXI 解碼錯誤。

The kernel clock for the FMC is the asynchronous fmc_ker_ck clock (refer to Section 8: Reset and Clock Control (RCC) for fmc_ker_ck clock source selection).

AXI支持的存儲和業務類型

通用規則

AXI總線上的請求業務數據尺寸可以是8/16/32/64位,然而接收訪問的外部存儲設備必須具有固定的數據寬度。

單詞學習:whereas :compared with the fact that; but: 意思是:即使前面描述的是客觀事實,但是xxxx

比如,You eat a huge plate of food for lunch, whereas I have just a sandwich. 你已然吃了很多午餐了,但我僅僅吃了一個三明治。

只有當AXI業務數據寬度與外部設備數據寬度一致時,才能發揮AXI總線數據傳輸的最大性能。

當AXI業務數據寬度與外部設備的數據寬度不一致時:

  1. AXI業務數據寬度大于設備數據寬度時,

    • 讀寫業務:FMC會將AXI業務數據寬度分割成較小的連續訪問,以符合外部設備數據寬度。

  2. AXI業務數據寬度小于外部設備數據寬度且外部設備(SRAM, PSRAM, SDRAM)支持字節選擇時,

    • 寫業務:FMC 使用字節通道信號管理事務。

    • 讀業務:FMC 根據外部設備的數據寬度返回所有字節。無用的字節將被系統丟棄。

  3. AXI業務數據寬度小于外部設備數據寬度且外部設備 (NOR and NAND flash memories)不支持字節選擇時,

    • 寫業務:FMC 寫入一些不相關的字節,可能會損壞外部設備。

    • 讀業務:FMC 根據外部設備的數據寬度返回所有字節。無用的字節將被系統丟棄。

注意:地址對齊

  1. FMC 不支持地址未對齊的讀取業務請求(例如,從奇數地址開始的半字)。

  2. FMC 會根據外部設備是否支持字節選擇特性來決定是否支持地址未對齊的寫入事務。 如果外部設備不支持字節選擇(NOR 和 NAND 閃存)特性,則FMC將不會支持窄寫入事務和/或未對齊的寫入事務,因為 FMC 會寫入不相關的字節并損壞外部設備。

對 NOR 閃存/PSRAM 和 SDRAM 的封裝支持

同步存儲器必須配置為未定義長度的線性突發模式,因為并非所有主設備都能支持數據經過封裝的業務。 如果主設備生成封裝事務: ? 讀取操作將被拆分為兩個線性突發事務。 ? 如果啟用了寫入 FIFO,則寫入操作將被拆分為兩個線性突發事務;如果禁用了寫入 FIFO,則寫入操作將被拆分為多個線性突發事務。

外部設備地址的映射

從FMC的視角去看,外部存儲設備被劃分為數個256M字節大小的塊區(bank)。

Bank1: NOR/PSRAM/SRAM,(4x64MB)可用于高達4個外部 NOR flash 或者 PSRAM 存儲設備。此區塊1被劃分為4個 NOR/PSRAM 子存儲區塊,且支持子區塊片選特性:

– Bank 1 - NOR/PSRAM 1 – Bank 1 - NOR/PSRAM 2 – Bank 1 - NOR/PSRAM 3 – Bank 1 - NOR/PSRAM 4

Bank2: SDRAM Bank1,(4x64MB)供外部 SDRAM 存儲設備使用。SDRAM bank 1 or SDRAM bank 2 depending on BMAP bits configuration。

Bank3: NAND Flash, (4x64MB)用于外部 NAND flash 設備尋址。此區塊的MPU存儲屬性必須配置成 software to Device。

Bank4: Not used ,(4x64MB)保留,FMC無法使用。

Bank5: SDRAM Bank1: (4x64MB) 用于 SDRAM 設備尋址(一個設備獨占一個bank)。

Bank6: SDRAM Bank2: (4x64MB) 用于 SDRAM 設備尋址(一個設備獨占一個bank)。

可以通過 FMC_BCR1 寄存器中的 BMAP[1:0] 位修改 FMC 存儲體映射。表 154 顯示了將 NOR/PSRAM 存儲體與 SDRAM 存儲體交換或重新映射 SDRAM 存儲體 2 的配置,從而允許以兩個不同的地址映射訪問 SDRAM 存儲體。

image-20250607181050249

習慣上,稱一級bank為FMC bank + 數字標號,稱二級bank為外部設備bank + 數字標號.

NOR/PSRAM 地址映射

[todo]

NAND flash 地址映射

[todo]

SDRAM 地址映射

[todo]

NOR flash/PSRAM 控制器

[todo]

NAND flash 控制器

[todo]

SDRAM 控制器

SDRAM 控制器主要特性

SDRAM 控制器支持如下主要特性:

  • 支持兩個可獨立配置 SDRAM banks;

  • 支持 8/16/32 數據總線寬度;

  • 13位數行地址,11位數列地址,4個內部子banks: 4x16Mx32bit (256 MB), 4x16Mx16bit (128 MB), 4x16Mx8bit (64 MB);

  • 支持以字、半字、字節形式訪問;

  • SDRAM時鐘可以是 fmc_ker_ck/2 or fmc_ker_ck/3;

  • 行和bank邊界的自動化管理;

  • banks之間的來回往復訪問;

  • 可編程的時序參數;

  • 支持可編程刷新率的自動刷新操作;

  • 自我刷新模式;

  • 掉電模式;

  • 通過軟件方式上電初始化SDRAM;

  • 列地址選通延遲等級配置:等級1,等級2,等級3;

  • 可緩存的讀 FIFO,深度為 6 行 x32 位(6 x14 位地址標簽);

CAS(Column Address Strobe)Latency(列地址選通延遲)是 SDRAM 的核心時序參數,在 STM32H743 的 FMC SDRAM 控制器中,它決定了從發出讀命令到數據輸出的延遲時鐘周期數

SDRAM 外部存儲接口信號

最開始,必須配置那些規劃被 "FMC SDRAM控制器"用來與“外部SDRAM存儲設備”通信的 ”SDRAM 引腳” ,那些余下的 SDRAM 引腳可以另做他用。

image-20250607201413815

SDRAM 控制器功能描述

SDRAM控制器所有的輸出(信號、地址、數據)都是在存儲時鐘(FMC_SDCLK)的下降沿做出改變。

初始化 SDRAM

SDRAM的初始化序列有軟件負責管理。如果使用兩個存儲槽(banks),那么必須通過設置 FMC_SDCMR 寄存器里的命中存儲槽Bank1/Bank2的對應的 CTB1 和 CTB2 位同時向Bank1和Bank2發出SDRAM的啟動序列

  1. 將外部存儲設備的特性寫入到 FMC_SDCRx 寄存器內。 SDRAM 時鐘頻率、RBURST 和 RPIPE 是必須要寫入到 FMC_SDCR1 寄存器內的。

  2. 將外部存儲設備的時序特性寫入到 FMC_SDTRx 寄存器內。TRP和TRC時序參數必須寫入到 FMC_SDTR1 寄存器內。

  3. 設置 FMC_SDCMR 寄存器內的 MODE 位為 ‘001’ ,并配置其中的命中的bank位 Target Bank bits (CTB1 and/or CTB2),便開始向外部存儲設備輸送時鐘信號(SDCKE被驅動為高)。

  4. 等待"規定"的延遲時間。典型延遲時間約為 100 μs(有關上電后所需的延遲時間,請參閱 SDRAM 數據手冊)。

  5. 將 FMC_SDCMR 寄存器內的模式位設置為 ‘010’ 且配置好目標存儲槽對應的比特位(CTB1 and/or CTB2),發出“預充所有”的命令。

  6. 將 MODE 位設置為“011”,并配置目標存儲區位(CTB1 和/或 CTB2)以及 FMC_SDCMR 寄存器中的連續自動刷新命令 (NRFS) 數量。有關應發出的自動刷新命令數量,請參閱 SDRAM 數據手冊。典型數量為 8。

  7. 配置 MRD 字段,將 MODE 位設置為“100”,并配置 FMC_SDCMR 寄存器中的目標存儲區位(CTB1 和/或 CTB2),以發出“加載模式寄存器”命令并對 SDRAM 設備進行編程。具體來說,必須將突發長度 (BL) 設置為“1”,并選擇 CAS 延遲。如果兩個 SDRAM 存儲區的模式寄存器不同,則必須重復此步驟兩次,每個存儲區各一次,并相應地設置目標存儲區位。對于移動 SDRAM 設備,MRD 字段還用于在發出“加載模式寄存器”命令時配置擴展模式寄存器。

  8. 把刷新速率寫入 FMC_SDRTR 寄存器內。 刷新率對應于刷新周期之間的延遲。其值必須正確適配外部的 SDRAM 存儲設備。

此時,SDRAM 設備已準備好接受命令。如果在 SDRAM 接收訪問期間發生系統復位,數據總線可能仍由 SDRAM 設備驅動。因此,在 NOR 閃存/PSRAM/SRAM 或 NAND 閃存控制器發出任何新的訪問之前,必須復位緊接著重新初始化 SDRAM 設備。

注意:If two SDRAM devices are connected to the FMC, all the accesses performed at the same time to both devices by the Command Mode register (Load Mode Register command) are issued using the timing parameters configured for SDRAM Bank 1 (TMRD andTRAS timings) in the FMC_SDTR1 register. 如果 FMC 連接了兩個 SDRAM 外部存儲設備,那么使用命令模式寄存器同時對兩個外部存儲設備執行的所有訪問,將都使用 FMC_SDTR1 寄存器內為SDRAM Bank 1配置的 TMRD andTRAS timings 位設定的時序發出。

SDRAM 控制器的寫周期

SDRAM 控制器接受單次和突發寫入請求,并將其轉換為單次內存訪問。在這兩種情況下,SDRAM 控制器都會跟蹤每個存儲體的活動行,以便能夠對不同的存儲體執行連續的寫入訪問(多存儲體乒乓訪問)。

在執行任何寫訪問之前,必須通過清除 FMC_SDCRx 寄存器中的 WP 位來失能 SDRAM 的 Bank 寫保護。

image-20250607215606016

SDRAM 控制器始終檢查下一次訪問。 ? 如果下一次訪問位于同一行或另一個活動行,則執行寫入操作; ? 如果下一次訪問的目標是另一行(非活動行),則 SDRAM 控制器生成預充電命令,激活新行并發起寫入命令。

SDRAM 控制器的讀周期

SDRAM 控制器接受單次和突發讀取請求,并將其轉換為單次內存訪問。在這兩種情況下,SDRAM 控制器都會跟蹤每個存儲體中的活動行,以便能夠在不同的存儲體中執行連續的讀取訪問(多存儲體乒乓訪問)。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/84120.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/84120.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/84120.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【AIGC】RAGAS評估原理及實踐

【AIGC】RAGAS評估原理及實踐 (1)準備評估數據集(2)開始評估2.1 加載數據集2.2 評估忠實性2.3 評估答案相關性2.4 上下文精度2.5 上下文召回率2.6 計算上下文實體召回率 RAGas(RAG Assessment)RAG 評估的縮寫&#xff…

VuePress完美整合Toast消息提示

VuePress 整合 Vue-Toastification 插件筆記 記錄如何在 VuePress 項目中整合使用 vue-toastification 插件,實現優雅的消息提示。 一、安裝依賴 npm install vue-toastification或者使用 yarn: yarn add vue-toastification二、配置 VuePress 客戶端增…

C#學習12——預處理

一、預處理指令: 解釋:是在編譯前由預處理器執行的命令,用于控制編譯過程。這些命令以 # 開頭,每行只能有一個預處理指令,且不能包含在方法或類中。 個人理解:就是游戲里面的備戰階段(不同對局…

開疆智能Profinet轉Profibus網關連接CMDF5-8ADe分布式IO配置案例

本案例是客戶通過開疆智能研發的Profinet轉Profibus網關將PLC的Profinet協議數據轉換成IO使用的Profibus協議,操作步驟如下。 配置過程: Profinet一側設置 1. 打開西門子組態軟件進行組態,導入網關在Profinet一側的GSD文件。 2. 新建項目并…

(三)Linux性能優化-CPU-CPU 使用率

CPU使用率 user(通常縮寫為 us),代表用戶態 CPU 時間。注意,它不包括下面的 nice 時間,但包括了 guest 時間。nice(通常縮寫為 ni),代表低優先級用戶態 CPU 時間,也就是進…

Digital IC Design Flow

Flow介紹 1.設計規格 架構師根據市場需求制作算法模型(Algorithm emulation)及芯片架構(Chip architecture),確定芯片設計規格書(Chip design specification) 原型驗證 原型驗證(Prototype Validation)通常位于產品開發流程的前期階段,主要是在設計和開發的初步階…

算法打卡第18天

從中序與后序遍歷序列構造二叉樹 (力扣106題) 給定兩個整數數組 inorder 和 postorder ,其中 inorder 是二叉樹的中序遍歷, postorder 是同一棵樹的后序遍歷,請你構造并返回這顆 二叉樹 。 示例 1: 輸入:inorder [9,3,15,20,7…

LangChain工具集成實戰:構建智能問答系統完整指南

導讀:在人工智能快速發展的今天,如何構建一個既能理解自然語言又能調用外部工具的智能問答系統,成為許多開發者面臨的核心挑戰。本文將為您提供一套完整的解決方案,從LangChain內置工具包的基礎架構到復雜系統的工程實踐。 文章深…

P3156 【深基15.例1】詢問學號

P3156 【深基15.例1】詢問學號 - 洛谷 數據結構-線性表 #include<bits/stdc.h> using namespace std; int n,m,a[2000005]; int main(){cin>>n>>m;for(int i1;i<n;i)cin>>a[i];//使用數組模擬線性表while(m--){int k;cin>>k;cout<<a[…

衡量嵌入向量的相似性的方法

衡量嵌入向量的相似性的方法 一、常見相似性計算方法對比 方法核心原理公式優點缺點適用場景余弦相似度計算向量夾角的余弦值,衡量方向相似性,與向量長度無關。$\text{cos}\theta = \frac{\mathbf{a} \cdot \mathbf{b}}{\mathbf{a}\mathbf{b}歐氏距離計算向量空間中的直線距離…

小番茄C盤清理:專業高效的電腦磁盤清理工具

在使用電腦的過程中&#xff0c;我們常常會遇到系統盤空間不足、磁盤碎片過多、垃圾文件堆積等問題&#xff0c;這些問題不僅會導致電腦運行緩慢&#xff0c;還可能引發系統崩潰。為了解決這些問題&#xff0c;小番茄C盤清理應運而生。它是一款專業的C盤清理軟件&#xff0c;能…

【版本控制】Git 和 GitHub 入門教程

目錄 0 引言1 Git與GitHub的誕生1.1 Git&#xff1a;Linus的“兩周奇跡”&#xff0c;拯救Linux內核1.2 GitHub&#xff1a;為Git插上協作的翅膀1.3 協同進化&#xff1a;從工具到生態的質變1.4 關鍵歷程時間軸&#xff08;2005–2008&#xff09; 2 Git與GitHub入門指南2.1 Gi…

Dify源碼教程:賬戶和密碼傳遞分析

概述 Dify系統中賬戶創建過程中的密碼處理是Web應用安全的重要環節。本教程詳細分析了從前端表單到后端存儲的完整流程&#xff0c;展示了Dify如何安全地處理用戶憑據。 前端部分 在 dify/web/app/install/installForm.tsx 文件中&#xff0c;當用戶填寫完表單并點擊安裝按鈕…

window查看SVN賬號密碼

背景 公司的SVN地址發生遷移&#xff0c;想遷移一下本地SVN地址&#xff0c;后來發現SVN賬號密碼忘記了。寫此文章純記錄。 遷移SVN地址&#xff1a; 找到svn目錄點擊relocate&#xff0c;輸入新的svn地址&#xff0c;如需輸入賬號密碼&#xff0c;輸入賬號密碼即完成svn地址…

Read View在MVCC里如何工作

Read View的結構 Read View中有四個重要的字段&#xff1a; m_ids&#xff1a;創建 Read View 時&#xff0c;數據庫中啟動但未提交的「活躍事務」的事務 id 列表 。min_trx_id&#xff1a;創建 Read View 時&#xff0c;「活躍事務」中事務 id 最小的值&#xff0c;即 m_ids …

如何在mac上安裝podman

安裝 Podman 在 macOS 上 在 macOS 上安裝 Podman 需要使用 Podman 的桌面客戶端工具 Podman Desktop 或通過 Homebrew 安裝命令行工具。 使用 Homebrew 安裝 Podman&#xff1a; (base) ninjamacninjamacdeMacBook-Air shell % brew install podman > Auto-updating Hom…

QGraphicsView中鼠標點擊與移動事件傳遞給MainWindow

在Qt圖形應用程序開發中,QGraphicsView和QGraphicsScene框架提供了強大的2D圖形顯示功能。然而,當我們需要在主窗口(MainWindow)中處理這些視圖中的鼠標事件。 問題背景 在典型的Qt圖形應用程序架構中: MainWindow └── QGraphicsView└── QGraphicsScene└── QGra…

Spring Boot 緩存注解詳解:@Cacheable、@CachePut、@CacheEvict(超詳細實戰版)

&#x1f4a1; 前言 在高并發、高性能的系統開發中&#xff0c;緩存是提升接口響應速度和降低數據庫壓力的重要手段。Spring Boot 提供了強大的緩存抽象層 —— spring-context-support&#xff0c;并結合 JSR-107 標準&#xff0c;提供了多個緩存注解&#xff0c;如&#xff…

vue中ref的詳解以及react的ref對比

文章目錄 1. ref是什么2. ref的使用3. ref的特性4. 使用場景5. 注意事項6. 與 React 的對比7. 動態 ref8. 函數式組件中的 ref9. 組合式 API 中的 ref10. 總結 1. ref是什么 ref 被用來給元素或子組件注冊引用信息。引用信息將會注冊在父組件的 $refs 對象上。可以通過實例對象…

通過ca證書的方式設置允許遠程訪問Docker服務

設置允許遠程訪問Docker服務 使用場景 環境 系統&#xff1a;anolis7.9 修改Docker服務配置&#xff0c;配置安全證書 生成ca證書到/etc/docker目錄中&#xff0c;后續會要用到 #該步驟需要設置密碼&#xff0c;后面步驟會要用到&#xff0c;此處設置密碼為123456 openss…