打印
[APM32E1]

揭开SDRAM的神秘面纱:从零开始搞懂APM32E103中的DMC是什么

[复制链接]
450|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 Reli-eng-z 于 2025-6-18 22:59 编辑

#申请原创# #技术资源#@21小跑堂



揭开SDRAM的神秘面纱:从零开始搞懂APM32E103中的DMC是什

前言
      如果你是第一次接触SDRAM,尤其是用APM32E103单片机开发SDRAM应用,可能会被一个名叫EMMC的东西搞得晕头转向。文档里提到它,代码里配置它,硬件上还得接它,但它到底是个啥?为什么每次谈到SDRAM都绕不开EMMC

1、引言:EMMC是个啥?它有什么作用
eMMC 想象成一个「智能快递仓库」,eMMC 就像一个大仓库,里面既存放临时包裹(动态数据),也存放长期固定的包裹(静态数据)。它内部有两个管理员分工合作:
SMC(静态管理员):管固定货架(SRAMNorFlash 等)
DMC(动态管理员):管流动货架(SDRAM)。处理器从eMMC读取数据(如启动代码)到SDRAM中执行,运行时,应用程序数据从eMMC加载到SDRAM缓存以提高速度。

2eMMC的定义:它到底是个啥?
      
用户手册上,介绍EMMC是外部存储器控制器,EMMC 包括 SMC(静态存储控制器)、DMC(动态存储控制器)。SMC 负责控 制 SRAMPSRAMNandFlashNorFlashPCCardDMC 控制 SDRAM

2.1 SMC 是用来管理扩展静态存储器的外设;可以将 AHB 传输信号转换到适当的外
部设备;内部存在四个存储块,每个存储块都对应控制不同类型的存储器,通过
片选信号加以区分;任一时刻只访问一个外部设备;每个存储块都可以单独配
置,时序可编程以适用外部设备。

2.2 DMC 一个动态存储控制器,外接片外 SDR-SDRAM
DMC 主要特征
l 16 位数据宽度
l 最大支持 2MB 片外 SDR-SDRAM
l SDR-SDRAM 的时序和大小可配置
l 支持 SDR-SDRAM power-down 模式
l 支持 SDR-SDRAM auto-refresh self-refresh

3 EMMCSDRAM:一对好搭档
      
eMMCSDRAM通过各自的专用接口与控制器独立工作,协同完成存储和运行任务:
eMMC提供持久化存储,通过SD/MMC协议由主机控制器访问。
SDRAM作为高速临时存储,由内存控制器直接管理
数据通过CPU/DMA在两者间传输,实现高效的系统运行

4、  EMMC的作用:它具体干了啥?

4.1 SMC(静态管理员)——管「固定货架」
    负责的存储类型:SRAMPSRAMNandFlashNorFlash 等。
    特点:这些存储像「固定货架」:数据存进去后,除非主动搬走,否则一直存在(比如 NorFlash 断电不丢数据)。适合放长期保存的东西(比如系统程序、固件)。
    举例: 你手机的系统文件存在 NorFlash 里,由 SMC 管理,开机时直接读取。

4.2 DMC(动态管理员)——管「流动货架」
    负责的存储类型:SDRAM(比如手机的运行内存)。

    特点: 这些存储像「流动货架」:数据随时搬进搬出,但断电就清空。适合放临时使用的东西(比如正在运行的游戏、APP)。
举例: 你打游戏时,DMC 会把游戏数据快速搬到 SDRAM 里,退出游戏后货架就腾空了。



  5 为什么这样分工?
    SMC 的「固定货架」:速度较慢但稳定,适合长期存储。
    DMC 的「流动货架」:速度快但需要持续供电,适合高速计算。
就像仓库既要存长期货物(SMC管),又要高效处理临时包裹(DMC管),eMMC 通过这两个控制器分工协作,兼顾速度和存储需求。
     
一句话总结
eMMC 是一个大仓库,SMC 管固定存储(像硬盘),DMC 管临时内存(像运行内存),两者配合让设备既存得住数据,又跑得快。
6、 APM32E103中的SDRAM应用:怎么用它?
    6.1.  谁控制 SDRAM
     主要控制器:
       DMC(动态内存控制器)是专门为控制 SDRAMDDR 等动态内存设计的硬件模块,负责:
       内存的初始化、读写时序、刷新(SDRAM 需要定期刷新保持数据)。
       CPU/SoC 通信,将内存请求转换为 SDRAM 能理解的信号。
    其他可能的名称:
        在某些芯片(如 IntelAMD CPU)中,DMC 可能集成在 内存控制器(IMC, Integrated Memory Controller) 中。
         ARM 架构的 SoC 中,DMC 通常是 SoC 内部的一个独立模块(比如三星 Exynos、高通骁龙芯片中的 DMC)。
6.2 为什么需要 DMC
    SDRAM 的特性:
        需要复杂的时序控制(行地址、列地址、预充电、刷新等)。
        数据是“动态”的,断电丢失,且需要定期刷新电容电荷。
        直接由 CPU 控制效率极低,因此需要专用控制器(DMC)来高效管理。
    类比:
DMC 就像一个“交通警察”,负责协调 CPU SDRAM 之间的高速数据流,确保读写有序、及时刷新。
7、  DMC 的实际应用场景
    手机/嵌入式设备:
        SoC 中的 DMC 控制 LPDDR SDRAM(低功耗内存),例如手机运行内存。
    电脑:
        CPU 内置的内存控制器(IMC)控制 DDR SDRAM(如 DDR4/DDR5)。
    其他场景:
       FPGA 或自定义硬件中,可能通过软核(如 Xilinx MIG IP)实现 DMC 功能。
8、 对比:SMC 控制什么?
    SMC(静态内存控制器)管理的是 不需要刷新 的存储器,例如:
        SRAM(静态随机存取存储器,速度快、成本高)。
        NorFlash/NandFlash(非易失性存储,断电不丢数据)。
        它们的特点是接口简单,无需复杂时序控制。
总结
    SDRAM DMC 控制,因为它的动态特性需要专用控制器
    DMC 的核心任务:初始化、时序管理、刷新、高效数据传输。
    不同系统中,DMC 可能以独立模块、集成控制器(IMC)或 IP 核的形式存在。
简单来说:CPU 想用内存时,会通过 DMC 这个“专业管家”来操作 SDRAM,而静态存储(如 Flash)则由 SMC 管理。


9硬件连接
      M12L64 164A-5TG2C为例,APM32E103SDRAM的连接如下:


APM32E103SDRAM连接


10、   DMC工作流程(以SDRAM为例)
    初始化序列:
        时钟使能:发送NOP命令并等待200μs
        预充电所有Bank
        c
SDRAM_Command(SDRAM_CMD_PALL, 0, 0); // 预充电命令
自动刷新8次:
for (int i = 0; i < 8; i++)
    SDRAM_Command(SDRAM_CMD_AUTO_REFRESH, 0, 0);
设置模式寄存器(配置CAS延迟、突发长度):
c
    SDRAM_Command(SDRAM_CMD_LOAD_MODE, 0x230, 0); // CAS=2, Burst=4
读写操作:
    通过行列地址分时复用访问:
    c
*(volatile uint16_t*)0xC0000000 = 0xABCD; // 写入SDRAM
  

11、  DMC驱动设计
    低功耗管理:
        进入自刷新模式(SDRAM在睡眠时保持数据):
        c
    SDRAM_Command(SDRAM_CMD_SELF_REFRESH, 0, 0);
性能优化:
    Bank交错访问:减少行激活延迟。
    突发传输:利用Burst Mode提升吞吐量。

12、  SDRAM驱动关键步骤
    初始化配置(以APM32E103为例):
    c
void SDRAM_Init(void) {
    // 配置GPIOFSMC控制器
    FSMC_Bank5_6->SDCR[0] = 0x000029D9; // 控制寄存器(CAS=2, 16位数据)
    FSMC_Bank5_6->SDTR[0] = 0x00112233; // 时序寄存器(tRCD=2, tRP=2)  
    // 执行初始化序列
    SDRAM_SendCmd(FMC_SDRAM_CMD_CLK_ENABLE, 0, 0); // 时钟使能
    delay(1);
    SDRAM_SendCmd(FMC_SDRAM_CMD_PALL, 0, 0);       // 预充电所有Bank
    SDRAM_SendCmd(FMC_SDRAM_CMD_AUTOREFRESH, 0, 8); // 自动刷新8
    // 设置模式寄存器(突发长度=4
    uint32_t mode_reg = 0x230; // CAS=2, Burst=4
    SDRAM_SendCmd(FMC_SDRAM_CMD_LOAD_MODE, mode_reg, 0);
}
读写操作:
c
// 直接通过内存地址访问(映射到SDRAM地址空间)
uint16_t *sdram = (uint16_t*)0xC0000000;
sdram[0] = 0x1234;  // 写入数据
uint16_t val = sdram[0]; // 读取数据

13、  本文参考资料
      - APM32E103用户手册
      - M12L64 164A-5TG2C数据手册
   





使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

60

主题

167

帖子

1

粉丝