/* 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、