调试SDRAM-MT48LC
参考
https://mculover666.blog.csdn.net/article/details/108221735
https://www.waveshare.net/study/article-660-1.html
1.新建STM32CUBEMX工程
2.添加FMC模块
3.配置参数
1.根据硬件设计选择SDCKE0(PC2\PC3)还是SDCKE1(PH6\PH7)
2.根据芯片手册选择
3.芯片决定9bits,列地址:A0~A8(9bits)
4.芯片决定13bits,行地址:A0~A12(13bits)
5.
6.根据【配置1】默认选择
7.根据芯片手册
8.根据芯片手册
9.根据芯片手册选择(因为芯片的最高速度为167,所以我们将180M进行2分频以后是90M)
10.禁止写保护
11.2分频
12.使能突发模式提高读效率
13.读延时配置
14.根据芯片手册配置,因为2分频以后SDRAM主频90Mhz 所以1个时钟周期1/90M=11.11ns
15.根据芯片手册配置
16.根据芯片手册配置
17.根据芯片手册配置
18.根据芯片手册配置
19.根据芯片手册配置
20.根据芯片手册配置
SDRAM初始化过程:
SDRAM初始化过程,图片来源于《高手进阶,终极内存技术指南——完整》(这个初始化过程SDRAM通用)
初始化过程分为五步:
① 上电
此步,给SDRAM供电,使能CLK时钟,并发送NOP(No Operation命令)等待最少200us。
② 发送预充电命令
第二步,就是发送预充电命令,给所有Bank预充电。
③ 发送自动刷新命令
这一步,至少要发送发送8次自刷新命令。
④ 设置模式寄存器
这一步,发送模式寄存器的值,配置SDRAM的工作参数。
最后一步设置:SDRAM刷新定时器(图片来源于STM32F4XX中文参考手册)
SDRAM 行地址:A0~A12(13bits),即有8192(2^13)行,F439的SDRAM时钟是90MHz。
刷新速率 = 64ms / 8192行 = 7.81us。
SDRAM 的刷新周期 = 7.81us * 90Mhz - 20 = 682.9,取683
减20是为了有足够的时钟周期留个刷新。
#define SDRAM_MODEREG_BURST_LENGTH_1 ((uint16_t)0x0000) #define SDRAM_MODEREG_BURST_LENGTH_2 ((uint16_t)0x0001) #define SDRAM_MODEREG_BURST_LENGTH_4 ((uint16_t)0x0002) #define SDRAM_MODEREG_BURST_LENGTH_8 ((uint16_t)0x0004) #define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000) #define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008) #define SDRAM_MODEREG_CAS_LATENCY_2 ((uint16_t)0x0020) #define SDRAM_MODEREG_CAS_LATENCY_3 ((uint16_t)0x0030) #define SDRAM_MODEREG_OPERATING_MODE_STANDARD ((uint16_t)0x0000) #define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000) #define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200) /** * @brief Perform the SDRAM exernal memory inialization sequence * @param hsdram: SDRAM handle * @param Command: Pointer to SDRAM command structure * @retval None */ static void SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram) { __IO uint32_t tmpmrd = 0; FMC_SDRAM_CommandTypeDef Command; /* Configure a clock configuration enable command */ Command.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE; Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2; Command.AutoRefreshNumber = 1; Command.ModeRegisterDefinition = 0; /* Send the command */ HAL_SDRAM_SendCommand(hsdram, &Command, 0x1000); /* Insert 10 ms delay */ HAL_Delay(10); /* Configure a PALL (precharge all) command */ Command.CommandMode = FMC_SDRAM_CMD_PALL; Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2; Command.AutoRefreshNumber = 1; Command.ModeRegisterDefinition = 0; /* Send the command */ HAL_SDRAM_SendCommand(hsdram, &Command, 0x1000); /* Configure a Auto-Refresh command */ Command.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE; Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2; Command.AutoRefreshNumber = 8; Command.ModeRegisterDefinition = 0; /* Send the command */ HAL_SDRAM_SendCommand(hsdram, &Command, 0x1000); /* Program the external memory mode register */ tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_8| SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL | SDRAM_MODEREG_CAS_LATENCY_3 | SDRAM_MODEREG_OPERATING_MODE_STANDARD | SDRAM_MODEREG_WRITEBURST_MODE_SINGLE; Command.CommandMode = FMC_SDRAM_CMD_LOAD_MODE; Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2; Command.AutoRefreshNumber = 1; Command.ModeRegisterDefinition = tmpmrd; /* Send the command */ HAL_SDRAM_SendCommand(hsdram, &Command, 0x1000); /* Set the refresh rate counter */ /* (7.81us x Freq) - 20 */ /* Set the device refresh counter */ HAL_SDRAM_ProgramRefreshRate(hsdram, 683); }
int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_FMC_Init(); MX_USART1_UART_Init(); SDRAM_Initialization_Sequence(&hsdram1); printf("sudaroot\r\n"); //使用SDRAM方法1 uint32_t i = 0; uint16_t sdramtest[10] __attribute__((at(0XD0000000))); for(i = 0; i < 10; i++) { sdramtest[i] = i; } for(i = 0; i < 10; i++) { printf("sdramtest[%d]:%d\r\n", i, sdramtest[i]); } //使用SDRAM方法2 uint32_t temp = 100; *(__IO uint32_t*)(0XD0000400) = temp; temp = 0; temp = *(__IO uint32_t*)(0XD0000400); printf("temp = %u\r\n", temp); while (1) { } }
最后说一下STM32 FMC地址映射关系,我使用的是SDRAM挂载在SDRAM Bank 2,所以开始地址是0xD0000000.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步