STM32F767 FMC SDRAM W9825G6KH 低功耗模式下自我刷新

/* Private variables ---------------------------------------------------------*/

SDRAM_HandleTypeDef hsdram1;

/* USER CODE BEGIN PV */


/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_FMC_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

#define DATA_SIZE 10000
#define DATA_ADDR 380

static void Sdram_SendCommand(uint32_t CommandMode, uint32_t CommandTarget, uint32_t AutoRefreshNumber, uint32_t ModeRegisterDefinition)
{
	FMC_SDRAM_CommandTypeDef Command;
	
	Command.AutoRefreshNumber = AutoRefreshNumber;
	Command.CommandMode = CommandMode;
	Command.CommandTarget = CommandTarget;
	Command.ModeRegisterDefinition = ModeRegisterDefinition;
	
	HAL_SDRAM_SendCommand(&hsdram1, &Command, 0);
}

static void Sdram_Init_Sequence(void)
{
	uint32_t ModeRegisterDefinition;
//	uint16_t Mode_WB;
//	uint16_t Mode_Op;
//	uint16_t Mode_CasLatency;
//	uint16_t Mode_Bt;
//	uint16_t Mode_BurstLength;
	
	Sdram_SendCommand(FMC_SDRAM_CMD_CLK_ENABLE, FMC_SDRAM_CMD_TARGET_BANK1, 0, 0);
	
	delay_us(200);
	
	Sdram_SendCommand(FMC_SDRAM_CMD_PALL, FMC_SDRAM_CMD_TARGET_BANK1, 0, 0);
	
	Sdram_SendCommand(FMC_SDRAM_CMD_AUTOREFRESH_MODE, FMC_SDRAM_CMD_TARGET_BANK1, 1, 0);
	
	//SDRAMÅäÖòÎÊý
	#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)

	ModeRegisterDefinition=(uint32_t)SDRAM_MODEREG_BURST_LENGTH_1          |	//ÉèÖÃÍ»·¢³¤¶È:1(¿ÉÒÔÊÇ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,µ¥µã·ÃÎÊ

	Sdram_SendCommand(FMC_SDRAM_CMD_LOAD_MODE, FMC_SDRAM_CMD_TARGET_BANK1, 1, ModeRegisterDefinition);
	
	HAL_SDRAM_ProgramRefreshRate(&hsdram1, 824);
}

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* 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_FMC_Init();
  /* USER CODE BEGIN 2 */
	
	//HAL_GPIO_WritePin(GPIOF, GPIO_PIN_6|GPIO_PIN_7, GPIO_PIN_SET);
	
	delay_init(216);
	delay_ms(500);
	
	Sdram_Init_Sequence();
	
	#define SDRAM_ADDR 0xc0000000
	
	#define DATA_LEN 0xffff
	static uint8_t data_old[DATA_LEN];
	static uint8_t data_new[DATA_LEN];
	static uint16_t i;
	for(i = 0; i < DATA_LEN; i++)
	{
		*(uint8_t*)(SDRAM_ADDR + i) = i;
	}
	for(i = 0; i < DATA_LEN; i++)
	{
		data_old[i] = *(uint8_t*)(SDRAM_ADDR + i);
	}
	
	Sdram_SendCommand(FMC_SDRAM_CMD_SELFREFRESH_MODE, FMC_SDRAM_CMD_TARGET_BANK1, 1, 0);
	
	HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI);
	SystemClock_Config();
	
	Sdram_SendCommand(FMC_SDRAM_CMD_NORMAL_MODE, FMC_SDRAM_CMD_TARGET_BANK1, 1, 0);
	
	for(i = 0; i < DATA_LEN; i++)
	{
		data_new[i] = *(uint8_t*)(SDRAM_ADDR + i);
	}
	
	for(i = 0; i < DATA_LEN; i++)
	{
		if(data_new[i] != data_old[i]) break;
	}
	if(i < DATA_LEN)
	{
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);
	}
	else
	{
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
	}
	
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		
  }
  /* USER CODE END 3 */
}
/* FMC initialization function */
static void MX_FMC_Init(void)
{

  /* USER CODE BEGIN FMC_Init 0 */

  /* USER CODE END FMC_Init 0 */

  FMC_SDRAM_TimingTypeDef SdramTiming = {0};

  /* USER CODE BEGIN FMC_Init 1 */

  /* USER CODE END FMC_Init 1 */

  /** Perform the SDRAM1 memory initialization sequence
  */
  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_0;
  /* SdramTiming */
  SdramTiming.LoadToActiveDelay = 16;
  SdramTiming.ExitSelfRefreshDelay = 16;
  SdramTiming.SelfRefreshTime = 16;
  SdramTiming.RowCycleDelay = 16;
  SdramTiming.WriteRecoveryTime = 16;
  SdramTiming.RPDelay = 16;
  SdramTiming.RCDDelay = 16;

  if (HAL_SDRAM_Init(&hsdram1, &SdramTiming) != HAL_OK)
  {
    Error_Handler( );
  }

  /* USER CODE BEGIN FMC_Init 2 */

  /* USER CODE END FMC_Init 2 */
}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOF_CLK_ENABLE();
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOG_CLK_ENABLE();
  __HAL_RCC_GPIOE_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);

  /*Configure GPIO pin : PH2 */
  GPIO_InitStruct.Pin = GPIO_PIN_2;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);

  /*Configure GPIO pin : PB1 */
  GPIO_InitStruct.Pin = GPIO_PIN_1;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /*Configure GPIO pins : PA9 PA10 */
  GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /* EXTI interrupt init*/
  HAL_NVIC_SetPriority(EXTI2_IRQn, 3, 0);
  HAL_NVIC_EnableIRQ(EXTI2_IRQn);

}

总结:
1、首先对SDRAM写数据,然后读出来,MCU进入停止模式,通过按键中断EXTI唤醒MCU,再次读SDRAM数据,与之前读出来的数据进行对比,结果为相同
2、进入低功耗前设置SDRAM FMC_SDRAM_CMD_SELFREFRESH_MODE模式,退出低功耗后设置SDRAM FMC_SDRAM_CMD_NORMAL_MODE模式,主要是两个函数Sdram_SendCommand(FMC_SDRAM_CMD_SELFREFRESH_MODE, FMC_SDRAM_CMD_TARGET_BANK1, 1, 0);与Sdram_SendCommand(FMC_SDRAM_CMD_NORMAL_MODE, FMC_SDRAM_CMD_TARGET_BANK1, 1, 0);
3、事实上屏蔽以上两个函数,进入停止模式前和唤醒后读出来的数据也是一样的(或许进入停止模式后时间相隔长一点再唤醒数据会不一样吧?猜测)
4、
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
W9825G6KH-6I是一种外部SDRAM芯片,用于提供较大的运行内存,特别适用于需要缓存显示屏的情况。它具有1280*800分辨率的显示屏,每帧缓存需要1Mb~3Mb的内存。在STM32F4xx内部无法运行,因此需要使用外部缓存。需要注意的是,该芯片在掉电后数据会迅速丢失,重启后需要特别注意这一特性。SDRAM和SRAM有所区别,引脚和程序也不通用。一般情况下,我们使用SDRAM,因为它的性价比高且有丰富的资料支持。SDRAM的结构复杂,但使用起来相对简单。初始化后,只需要记住一个地址即可,程序上可以忘记它的存在。W9825G6KH-6I是一种常用的SDRAM芯片,市场上有很多可替代的芯片,价格在15元左右。在硬件连接方面,可以参考原理图和引脚说明进行连接。在程序使用方面,需要进行初始化和基本函数的调用,然后进行正常使用。总结起来,对于W9825G6KH-6I的使用,需要将SDRAM模式中的CAS latency设置为3,并将SDCLK周期设置为2个FMC周期。此外,还需要注意突发读使能等相关设置。在主函数中调用SDRAM_Cmd_Init()和SDRAM_Test()函数即可。如果初始化指令出现问题,可以通过修改下载方式为under reset,然后按住复位键,点击下载键,复位后立即松开来解决问题。如果有其他问题或需要源码,请在评论区下方留言或留下邮箱联系。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* [STM32F4xx SDRAM(更新中)](https://blog.csdn.net/zhouml_msn/article/details/90052820)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [STM32H750 SDRAM W9825G6KH-6](https://blog.csdn.net/smallerlang/article/details/128061724)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [STM32F429IGT6项目准备5——使用STM32CubeMX配置SDRAM](https://blog.csdn.net/qq_42039294/article/details/112221396)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值