硬汉嵌入式论坛

 找回密码
 立即注册
查看: 195|回复: 3
收起左侧

[SDRAM] SDRAM初始化问题,无法初始化,并且重新上电无法清除数据

[复制链接]

8

主题

31

回帖

55

积分

初级会员

积分
55
发表于 2025-10-20 16:35:35 | 显示全部楼层 |阅读模式
我的SDRAM的数据重新上电后好像清除不了,而且全局初始化也不是初始化为零,上一次我把SDRAM_Buf1 在main函数内赋值为了999,后面无论全局初始化为什么,最后打印出来都是999;然后我将SDRAM_Buf2 初始化为0,结果全局的初始化好像就是不生效的,打印出来是117835012。
然而地址什么的打印出来倒是正确的。

[C] 纯文本查看 复制代码
__attribute__((section (".RAM_SDRAM"))) uint32_t SDRAM_Buf1 = 1000;

__attribute__((section (".RAM_SDRAM"))) uint32_t SDRAM_Buf2 = 0;

/* USER CODE END 0 */



/**

  * @brief  The application entry point.

  * @retval int

  */

int main(void)

{



  /* USER CODE BEGIN 1 */



  /* USER CODE END 1 */



  /* MPU Configuration--------------------------------------------------------*/

  MPU_Config();



  /* Enable the CPU Cache */



  /* Enable I-Cache---------------------------------------------------------*/

  SCB_EnableICache();



  /* Enable D-Cache---------------------------------------------------------*/

  SCB_EnableDCache();



  /* MCU Configuration--------------------------------------------------------*/



  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */

  HAL_Init();



  /* USER CODE BEGIN Init */



  /* USER CODE END Init */



  /* Configure the system clock */

  SystemClock_Config();



  /* USER CODE BEGIN SysInit */



  /* USER CODE END SysInit */



  /* Initialize all configured peripherals */

  MX_GPIO_Init();

  MX_USART1_UART_Init();

  MX_FMC_Init();

  /* USER CODE BEGIN 2 */



	Set_Current_USART(USART1_IDX);

	printf("SDRAM 初始化通过!\r\n");



//	// 测试 SDRAM 读写

//	uint16_t test_val = 1234;

//	*(uint16_t*)0xC0000000 = test_val;  // 向 SDRAM 地址写入值

//	uint16_t read_val = *(uint16_t*)0xC0000000;  // 从 SDRAM 地址读取值

//	printf("SDRAM Test: write=%d, read=%d\r\n", test_val, read_val);

//	// 若读写值一致,说明 SDRAM 硬件和初始化正常

	printf("SDRAM_Buf1 = %d\r\n", SDRAM_Buf1);

	printf("&SDRAM_Buf1 = %p\r\n", &SDRAM_Buf1);



	printf("SDRAM_Buf2 = %d\r\n", SDRAM_Buf2);

	printf("&SDRAM_Buf2 = %p\r\n", &SDRAM_Buf2);





  /* USER CODE END 2 */



  /* Infinite loop */

  /* USER CODE BEGIN WHILE */

  while (1)

  {



  }

}


MPU配置:


SDRAM配置:



这是我放在_main前提前将fmc sdram初始化的函数
[C] 纯文本查看 复制代码
#define SDRAM_Size 32*1024*1024                                 //32M字节
#define SDRAM_BANK_ADDR     ((uint32_t)0xC0000000) 				// FMC SDRAM 数据基地址
#define FMC_COMMAND_TARGET_BANK   FMC_SDRAM_CMD_TARGET_BANK1	// SDRAM 的bank选择
#define SDRAM_TIMEOUT     ((uint32_t)0x1000) 					// 超时判断时间
 
#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) 

extern FMC_SDRAM_CommandTypeDef command;// 控制指令
extern void SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command);
extern void SystemInit_ExtMemCtl(void);

///******************************************************************************************************
//*	函 数 名: SystemInit_ExtMemCtl
//*	入口参数: 无
//*	返 回 值: 无
//*	函数功能: 初始化外部 SDRAM 控制器
//*	说    明: 此函数用于初始化 FMC 外设,配置 GPIO 引脚,并对 SDRAM 进行初始化和参数配置。
//*             仅在定义了 DATA_IN_ExtSDRAM 时执行相关操作。
//* 作用:		在进入main函数之前就对FMC进行初始化(很重要!!!!!)
//*******************************************************************************************************/
void SystemInit_ExtMemCtl(void)
{
	#if defined (DATA_IN_ExtSDRAM)
	//--------------------------------------------------------------------
	// 变量定义
	//--------------------------------------------------------------------
	FMC_SDRAM_TimingTypeDef SdramTiming = {0};
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	__IO uint32_t tmpmrd = 0;
	uint32_t FMC_Initialized = 0;
	if (FMC_Initialized) {
			return;
	}FMC_Initialized = 1;
	//--------------------------------------------------------------------
	// 时钟使能
	//--------------------------------------------------------------------
	__HAL_RCC_FMC_CLK_ENABLE();
	//--------------------------------------------------------------------
	// GPIO初始化
	//--------------------------------------------------------------------
	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_2|GPIO_PIN_3|GPIO_PIN_5;
	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_PIN_7;
	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);
	//--------------------------------------------------------------------
	// FMC-SDRAM初始化
	//--------------------------------------------------------------------
	hsdram1.Instance = FMC_SDRAM_DEVICE;
	/* hsdram1.Init */
	hsdram1.Init.SDBank = FMC_SDRAM_BANK1;
	hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_9;
	hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_13;
	hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16;
	hsdram1.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
	hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_3;
	hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
	hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
	hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE;
	hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_1;
	/* SdramTiming */
	SdramTiming.LoadToActiveDelay = 2;
	SdramTiming.ExitSelfRefreshDelay = 8;
	SdramTiming.SelfRefreshTime = 6;
	SdramTiming.RowCycleDelay = 6;
	SdramTiming.WriteRecoveryTime = 4;
	SdramTiming.RPDelay = 2;
	SdramTiming.RCDDelay = 2;
	if (HAL_SDRAM_Init(&hsdram1, &SdramTiming) != HAL_OK)
	{
	Error_Handler( );
	}
	
	
	SDRAM_Initialization_Sequence(&hsdram1,&command);//配置SDRAM
	#endif
}

FMC_SDRAM_CommandTypeDef command;// 控制指令
/******************************************************************************************************
*	函 数 名: SDRAM_Initialization_Sequence
*	入口参数: hsdram - SDRAM_HandleTypeDef定义的变量,即表示定义的sdram
*				 Command	- 控制指令
*	返 回 值: 无
*	函数功能: SDRAM 参数配置
*	说    明: 配置SDRAM相关时序和控制方式
*******************************************************************************************************/
void SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command)
{
	__IO uint32_t tmpmrd = 0;
   register __IO uint32_t index;
	/* Configure a clock configuration enable command 时钟配置使能*/
	Command->CommandMode 				= FMC_SDRAM_CMD_CLK_ENABLE;	// 开启SDRAM时钟 
	Command->CommandTarget 				= FMC_COMMAND_TARGET_BANK; 	// 选择要控制的区域
	Command->AutoRefreshNumber 	    	= 1;
	Command->ModeRegisterDefinition 	= 0;
 
	HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);	// 发送控制指令
	  /* Delay */
  for (index = 0; index<10000; index++);
 
	/* Configure a PALL (precharge all) command 对所有存储区域预充电*/ 
	Command->CommandMode 				= FMC_SDRAM_CMD_PALL;		// 预充电命令
	Command->CommandTarget 				= FMC_COMMAND_TARGET_BANK;	// 选择要控制的区域
	Command->AutoRefreshNumber 		    = 1;
	Command->ModeRegisterDefinition 	= 0;
 
	HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);  // 发送控制指令
 
	/* Configure a Auto-Refresh command 设置自动刷新次数*/ 
	Command->CommandMode 				= FMC_SDRAM_CMD_AUTOREFRESH_MODE;	// 使用自动刷新
	Command->CommandTarget 				= FMC_COMMAND_TARGET_BANK;          // 选择要控制的区域
	Command->AutoRefreshNumber			= 8;                                // 自动刷新次数
	Command->ModeRegisterDefinition 	= 0;
 
	HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);	// 发送控制指令
 
	/* Program the external memory mode register */
    //配置模式寄存器,SDRAM的bit0-bit2为指定突发访问的长度
    //bit3为指定突发访问的类型,bit4-bit6为CAS值,bit7和bit8为运行模式
    //bit9为指定的写突发模式,bit10和bit11位保留位
	tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_2               |//设置突发长度:2(可以是1/2/4/8)
							SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL   |//设置突发类型:连续(可以是连续/交错)
							SDRAM_MODEREG_CAS_LATENCY_3           |//设置CAS值:3(可以是2/3)
							SDRAM_MODEREG_OPERATING_MODE_STANDARD |//设置操作模式:0,标准模式
							SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;  //设置突发写模式:1,单点访问
 
	Command->CommandMode            = FMC_SDRAM_CMD_LOAD_MODE;	// 加载模式寄存器命令
	Command->CommandTarget          = FMC_COMMAND_TARGET_BANK;	// 选择要控制的区域
	Command->AutoRefreshNumber 		= 1;
	Command->ModeRegisterDefinition = tmpmrd;
 
	HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);	// 发送控制指令
    
	//刷新频率计数器(以SDCLK频率计数),计算方法:
	//COUNT=SDRAM刷新周期/行数-20=SDRAM刷新周期(us)*SDCLK频率(Mhz)/行数
    //我们使用的SDRAM刷新周期为64ms,SDCLK=240/2=120Mhz,行数为8192(2^13).
	//所以,COUNT=64*1000*120/8192-20=918(20为刷新等待冗余)
	HAL_SDRAM_ProgramRefreshRate(hsdram, 918);  // 配置刷新率
}



回复

使用道具 举报

8

主题

31

回帖

55

积分

初级会员

积分
55
 楼主| 发表于 2025-10-21 08:08:37 | 显示全部楼层
现在大概知道了为什么掉电不丢失,可能某个电容放电太慢导致的,昨晚吃个饭回来之后就掉电丢失了。但是为什么无法在全局初始化中初始化SDRAM中的变量中初始化变量呢
回复

使用道具 举报

8

主题

31

回帖

55

积分

初级会员

积分
55
 楼主| 发表于 2025-10-21 14:22:55 | 显示全部楼层
此贴终结,原因是引脚有一两个没对好
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
119430
QQ
发表于 2025-10-21 14:29:40 | 显示全部楼层
sssuuu 发表于 2025-10-21 08:08
现在大概知道了为什么掉电不丢失,可能某个电容放电太慢导致的,昨晚吃个饭回来之后就掉电丢失了。但是为什 ...

这个现象是正常的,因为SDRAM初始化是在MDK的__main函数里面完成的,如果你还没有初始化SDRAM,全局变量是没法在初始化接到赋初始值的。

所以如果你要解决,就要在启动初始化前,初始化好SDRAM才可以
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-11-22 04:11 , Processed in 0.058024 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表