STM32 FMC接口详解
FMC框图
SDRAM
SDRAM说明
引脚解释(大部分芯片都相同)
容量计算(例子)
CubeMX配置界面说明
芯片手册与CubeMX配置界面倒序对应
地址映射说明
FMC 给SDRAM 分配的区域不在External RAM 区这个区域可以直接执行代码,而SDRAM 所在的External device 区却不支持这个功能。
为了解决这个问题,通过配置“SYSCFG_MEMRMP”寄存器的“SWP_FMC”寄存器位可用于交换SDRAM 与NAND/PC 卡的地址映射,使得存储在SDRAM 中的代码能被执行,只是会限制在SDRAM 的最高同步时钟,代码的执行速度会受影响。(详细参考芯片手册RM0433的22.5节AXI接口)
CubeMX映射切换选项
CubeMX配置参数
注意
不知道为什么不分频无法读写SDRAM
初始化(参考芯片手册)
SDRAM比SRAM多一步初始化操作
初始化步骤
函数说明
发送命令函数说明
HAL_SDRAM_SendCommand()
通过该函数发送不同的命令达到初始化的步骤,命令由FMC_SDRAM_CommandTypeDef
结构体决定,该结构体有四个参数分别为(对应芯片手册的命令模式寄存器 (FMC_SDCMR)详细参考RM0433 第22.9.5节 SDRAM 控制寄存器)
CommandMode
命令模式 (Command mode)有以下选择
#define FMC_SDRAM_CMD_NORMAL_MODE (0x00000000U) 000:正常模式
#define FMC_SDRAM_CMD_CLK_ENABLE (0x00000001U) 001:时钟配置使能
#define FMC_SDRAM_CMD_PALL (0x00000002U) 010:PALL(“预充电所有存储区域”)命令
#define FMC_SDRAM_CMD_AUTOREFRESH_MODE (0x00000003U) 011:自动刷新命令
#define FMC_SDRAM_CMD_LOAD_MODE (0x00000004U) 100:加载模式寄存器
#define FMC_SDRAM_CMD_SELFREFRESH_MODE (0x00000005U) 101:自我刷新命令
#define FMC_SDRAM_CMD_POWERDOWN_MODE (0x00000006U) 110:掉电命令
CommandTarget
命令目标存储区域(Command Target Bank)有以下选择
#define FMC_SDRAM_CMD_TARGET_BANK2 FMC_SDCMR_CTB2 向 SDRAM 存储器 2 发送命令
#define FMC_SDRAM_CMD_TARGET_BANK1 FMC_SDCMR_CTB1 向 SDRAM 存储器 1 发送命令
#define FMC_SDRAM_CMD_TARGET_BANK1_2 (0x00000018U) 向 SDRAM 存储器 1 和 2 发送命令
AutoRefreshNumber
自动新次数 (Number of Auto-refresh)有以下选择
0~15
MODE =“011”自动刷新命令 时所发出的连续自刷新命令个数(该参数只在处于自动刷新命令才有效)
ModeRegisterDefinition
模式寄存器定义 (Mode Register definition)(该参数只在处于加载模式寄存器才有效)
自动刷新函数说明
HAL_SDRAM_ProgramRefreshRate()
输入参数有接口句柄结构体和刷新速率(计算公式如下)(基本为(0.064/行数)*SDRAM时钟频率-20)
初始化函数
FMC_SDRAM_CommandTypeDef DevCommand;
DevCommand.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE; //时钟配置使能
DevCommand.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
HAL_SDRAM_SendCommand(&hsdram1, &DevCommand,0xFFFF);
HAL_Delay(1); //延时200us以上
DevCommand.CommandMode = FMC_SDRAM_CMD_PALL; //预充电所有存储区域
DevCommand.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
HAL_SDRAM_SendCommand(&hsdram1, &DevCommand,0xFFFF);
DevCommand.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE; //自动刷新命令
DevCommand.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
DevCommand.AutoRefreshNumber = 8; //设置为8个
HAL_SDRAM_SendCommand(&hsdram1, &DevCommand,0xFFFF);
DevCommand.CommandMode = FMC_SDRAM_CMD_LOAD_MODE; //加载模式寄存器
DevCommand.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
DevCommand.ModeRegisterDefinition = 0x220; //使能突发模式,CL设置为2
HAL_SDRAM_SendCommand(&hsdram1, &DevCommand,0xFFFF);
HAL_SDRAM_ProgramRefreshRate(&hsdram1, 918); //设置自动刷新速率
注意MPU(内存保护单元)
如果不配置MPU的话请直接关闭MPU,不然CubeMX默认生成的文件会配置MPU,会导致程序触发地址异常,卡死在地址异常中断里
解决方法一(关闭MPU)
解决方法二(配置MPU)
作者:xss3009