main.c
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2024 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usart.h"
#include "gpio.h"
#include "fmc.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "string.h"
#include <stdio.h>
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
#define EXT_SDRAM_SIZE (32 * 1024 * 1024)
uint32_t bsp_TestExtSDRAM(void);
uint32_t sdram_test()
{
uint32_t i = 0;
uint32_t temp = 0;
uint32_t sval = 0;
char msg[50];
// 写操作:将数据写入SDRAM
for (i = 0; i < EXT_SDRAM_SIZE; i += 16 * 1024)
{
*(volatile uint32_t *)(BANK5_SDRAM_ADDR + i) = temp;
temp++;
// 每次写入后打印当前写入的位置和数据
snprintf(msg, sizeof(msg), "Written value %ld at address %08lx\r\n", temp - 1, (BANK5_SDRAM_ADDR + i));
HAL_UART_Transmit(&huart1, (uint8_t*)msg, strlen(msg), 10000);
}
// 读操作:从SDRAM读取数据并验证
for (i = 0; i < EXT_SDRAM_SIZE; i += 16 * 1024)
{
temp = *(volatile uint32_t *)(BANK5_SDRAM_ADDR + i);
// 打印每次读取的值
snprintf(msg, sizeof(msg), "Read value %ld from address %08lx\r\n", temp, (BANK5_SDRAM_ADDR + i));
HAL_UART_Transmit(&huart1, (uint8_t*)msg, strlen(msg), 10000);
if (i == 0)
{
sval = temp;
}
else if (temp != (i / (16 * 1024)))
{
snprintf(msg, sizeof(msg), "Data mismatch at address %08lx: expected %08lx but read %08lx\r\n", (BANK5_SDRAM_ADDR + i), (i / (16 * 1024)), temp);
HAL_UART_Transmit(&huart1, (uint8_t*)msg, strlen(msg), 10000);
break;
}
}
// 最后打印SDRAM的总容量
snprintf(msg, sizeof(msg), "SDRAM Capacity: %ldKB\r\n", EXT_SDRAM_SIZE / 1024);
HAL_UART_Transmit(&huart1, (uint8_t*)msg, strlen(msg), 10000);
return 1;
}
uint8_t mpu_set_protection(uint32_t baseaddr, uint32_t size, uint32_t rnum, uint8_t de, uint8_t ap, uint8_t sen, uint8_t cen, uint8_t ben)
{
MPU_Region_InitTypeDef mpu_region_init_handle;
HAL_MPU_Disable(); /* ����MPU֮ǰ�ȹر�MPU,��������Ժ���ʹ��MPU */
mpu_region_init_handle.Enable = MPU_REGION_ENABLE; /* ʹ�ܸñ������� */
mpu_region_init_handle.Number = rnum; /* �������� */
mpu_region_init_handle.BaseAddress = baseaddr; /* ���û�ַ */
mpu_region_init_handle.DisableExec = de; /* �Ƿ�����ָ����� */
mpu_region_init_handle.Size = size; /* ���ñ��������С */
mpu_region_init_handle.SubRegionDisable = 0X00; /* ��ֹ������ */
mpu_region_init_handle.TypeExtField = MPU_TEX_LEVEL0; /* ����������չ��Ϊlevel0 */
mpu_region_init_handle.AccessPermission = (uint8_t)ap; /* ���÷���Ȩ��, */
mpu_region_init_handle.IsShareable = sen; /* �Ƿ���? */
mpu_region_init_handle.IsCacheable = cen; /* �Ƿ�cache? */
mpu_region_init_handle.IsBufferable = ben; /* �Ƿ�? */
HAL_MPU_ConfigRegion(&mpu_region_init_handle); /* ����MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); /* ����MPU */
return 0;
}
void mpu_memory_protection(void)
{
/* ����SDRAM����,��32M�ֽ� */
mpu_set_protection( 0xC0000000, /* ����ַ */
MPU_REGION_SIZE_32MB, /* ���� */
MPU_REGION_NUMBER6, 0, /* NUMER6,����ָ����� */
MPU_REGION_FULL_ACCESS, /* ȫ���� */
MPU_ACCESS_NOT_SHAREABLE, /* ��ֹ���� */
MPU_ACCESS_CACHEABLE, /* ����cache */
MPU_ACCESS_BUFFERABLE); /* �������� */
}
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MPU Configuration--------------------------------------------------------*/
/* 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();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
mpu_memory_protection();
HAL_UART_Transmit(&huart1, (uint8_t*)"SDRAM W9825G6KH Init success\r\n", strlen("SDRAM W9825G6KH Init success\r\n"), 10000);
// 测试SDRAM并发送测试结果消�???
uint32_t ret = 0;
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if(ret == 0)
ret = sdram_test();
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Supply configuration update enable
*/
HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
/** Configure the main internal regulator output voltage
*/
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSIState = RCC_HSI_DIV1;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 2;
RCC_OscInitStruct.PLL.PLLN = 64;
RCC_OscInitStruct.PLL.PLLP = 2;
RCC_OscInitStruct.PLL.PLLQ = 2;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
RCC_OscInitStruct.PLL.PLLFRACN = 0;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
|RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/* MPU Configuration */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
fmc.c
/* USER CODE BEGIN Header */
/**
******************************************************************************
* File Name : FMC.c
* Description : This file provides code for the configuration
* of the FMC peripheral.
******************************************************************************
* @attention
*
* Copyright (c) 2024 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "fmc.h"
/* USER CODE BEGIN 0 */
SDRAM_HandleTypeDef hsdram1;
/**
* @brief 发�?�SDRAM初始化序�???
* @param �???
* @retval �???
*/
void sdram_initialization_sequence(void)
{
uint32_t temp = 0;
/* SDRAM控制器初始化完成以后还需要按照如下顺序初始化SDRAM */
sdram_send_cmd(0, FMC_SDRAM_CMD_CLK_ENABLE, 1, 0); /* 时钟配置使能 */
HAL_Delay(100); /* 至少延时500us */
sdram_send_cmd(0, FMC_SDRAM_CMD_PALL, 1, 0); /* 对所有存储区预充电 */
sdram_send_cmd(0, FMC_SDRAM_CMD_AUTOREFRESH_MODE, 8, 0); /* 设置自刷新次数 */
/* 配置模式寄存器,SDRAM的bit0~bit2为指定突发访问的长度,
* bit3为指定突发访问的类型,bit4~bit6为CAS值,bit7和bit8为运行模式
* bit9为指定的写突发模式,bit10和bit11位保留位 */
temp = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 | /* 设置突发长度:1(可以是1/2/4/8) */
SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL | /* 设置突发类型:连续(可以是连续/交错) */
SDRAM_MODEREG_CAS_LATENCY_2 | /* 设置CAS值:2(可以是2/3) */
SDRAM_MODEREG_OPERATING_MODE_STANDARD| /* 设置操作模式:0,标准模式 */
SDRAM_MODEREG_WRITEBURST_MODE_SINGLE; /* 设置突发写模式:1,单点访问 */
sdram_send_cmd(0, FMC_SDRAM_CMD_LOAD_MODE, 1, temp); /* 设置SDRAM的模式寄存器 */
}
uint8_t sdram_send_cmd(uint8_t bankx, uint8_t cmd, uint8_t refresh, uint16_t regval)
{
uint32_t target_bank = 0;
FMC_SDRAM_CommandTypeDef command;
if (bankx == 0)
{
target_bank = FMC_SDRAM_CMD_TARGET_BANK1;
}
else if (bankx == 1)
{
target_bank = FMC_SDRAM_CMD_TARGET_BANK2;
}
command.CommandMode = cmd; /* 命令 */
command.CommandTarget = target_bank; /* 目标SDRAM存储区域 */
command.AutoRefreshNumber = refresh; /* 自刷新次�?? */
command.ModeRegisterDefinition = regval; /* 要写入模式寄存器的�?? */
if (HAL_SDRAM_SendCommand(&hsdram1, &command, 0X1000) == HAL_OK) /* 向SDRAM发�?�命�?? */
{
return 0;
}
else
{
return 1;
}
}
/**
* @brief 在指定地�??(WriteAddr+BANK5_SDRAM_ADDR)�??�??,连续写入n个字�??
* @param pbuf : 字节指针
* @param writeaddr : 要写入的地址
* @param n : 要写入的字节�??
* @retval �??
*/
void fmc_sdram_write_buffer(uint8_t *pbuf, uint32_t writeaddr, uint32_t n)
{
for (; n != 0; n--)
{
*(volatile uint8_t *)(BANK5_SDRAM_ADDR + writeaddr) = *pbuf;
writeaddr++;
pbuf++;
}
}
/**
* @brief 在指定地�??((WriteAddr+BANK5_SDRAM_ADDR))�??�??,连续读出n个字�??.
* @param pbuf : 字节指针
* @param readaddr : 要读出的起始地址
* @param n : 要写入的字节�??
* @retval �??
*/
void fmc_sdram_read_buffer(uint8_t *pbuf, uint32_t readaddr, uint32_t n)
{
for (; n != 0; n--)
{
*pbuf++ = *(volatile uint8_t *)(BANK5_SDRAM_ADDR + readaddr);
readaddr++;
}
}
/* USER CODE END 0 */
SDRAM_HandleTypeDef hsdram1;
/* FMC initialization function */
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_2;
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 = 7;
SdramTiming.RowCycleDelay = 7;
SdramTiming.WriteRecoveryTime = 5;
SdramTiming.RPDelay = 2;
SdramTiming.RCDDelay = 2;
if (HAL_SDRAM_Init(&hsdram1, &SdramTiming) != HAL_OK)
{
Error_Handler( );
}
/* USER CODE BEGIN FMC_Init 2 */
sdram_initialization_sequence(); /* 发�?�SDRAM初始化序�??? */
HAL_SDRAM_ProgramRefreshRate(&hsdram1, 839);
/* USER CODE END FMC_Init 2 */
}
static uint32_t FMC_Initialized = 0;
static void HAL_FMC_MspInit(void){
/* USER CODE BEGIN FMC_MspInit 0 */
/* USER CODE END FMC_MspInit 0 */
GPIO_InitTypeDef GPIO_InitStruct = {0};
if (FMC_Initialized) {
return;
}
FMC_Initialized = 1;
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_FMC;
PeriphClkInitStruct.FmcClockSelection = RCC_FMCCLKSOURCE_D1HCLK;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
/* Peripheral clock enable */
__HAL_RCC_FMC_CLK_ENABLE();
/** FMC GPIO Configuration
PF0 ------> FMC_A0
PF1 ------> FMC_A1
PF2 ------> FMC_A2
PF3 ------> FMC_A3
PF4 ------> FMC_A4
PF5 ------> FMC_A5
PC0 ------> FMC_SDNWE
PC2_C ------> FMC_SDNE0
PC3_C ------> FMC_SDCKE0
PF11 ------> FMC_SDNRAS
PF12 ------> FMC_A6
PF13 ------> FMC_A7
PF14 ------> FMC_A8
PF15 ------> FMC_A9
PG0 ------> FMC_A10
PG1 ------> FMC_A11
PE7 ------> FMC_D4
PE8 ------> FMC_D5
PE9 ------> FMC_D6
PE10 ------> FMC_D7
PE11 ------> FMC_D8
PE12 ------> FMC_D9
PE13 ------> FMC_D10
PE14 ------> FMC_D11
PE15 ------> FMC_D12
PD8 ------> FMC_D13
PD9 ------> FMC_D14
PD10 ------> FMC_D15
PD14 ------> FMC_D0
PD15 ------> FMC_D1
PG2 ------> FMC_A12
PG4 ------> FMC_BA0
PG5 ------> FMC_BA1
PG8 ------> FMC_SDCLK
PD0 ------> FMC_D2
PD1 ------> FMC_D3
PG15 ------> FMC_SDNCAS
PE0 ------> FMC_NBL0
PE1 ------> FMC_NBL1
*/
/* GPIO_InitStruct */
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 */
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_2|GPIO_PIN_3;
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(GPIOC, &GPIO_InitStruct);
/* 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 */
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 */
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_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);
/* USER CODE BEGIN FMC_MspInit 1 */
/* USER CODE END FMC_MspInit 1 */
}
void HAL_SDRAM_MspInit(SDRAM_HandleTypeDef* sdramHandle){
/* USER CODE BEGIN SDRAM_MspInit 0 */
/* USER CODE END SDRAM_MspInit 0 */
HAL_FMC_MspInit();
/* USER CODE BEGIN SDRAM_MspInit 1 */
/* USER CODE END SDRAM_MspInit 1 */
}
static uint32_t FMC_DeInitialized = 0;
static void HAL_FMC_MspDeInit(void){
/* USER CODE BEGIN FMC_MspDeInit 0 */
/* USER CODE END FMC_MspDeInit 0 */
if (FMC_DeInitialized) {
return;
}
FMC_DeInitialized = 1;
/* Peripheral clock enable */
__HAL_RCC_FMC_CLK_DISABLE();
/** FMC GPIO Configuration
PF0 ------> FMC_A0
PF1 ------> FMC_A1
PF2 ------> FMC_A2
PF3 ------> FMC_A3
PF4 ------> FMC_A4
PF5 ------> FMC_A5
PC0 ------> FMC_SDNWE
PC2_C ------> FMC_SDNE0
PC3_C ------> FMC_SDCKE0
PF11 ------> FMC_SDNRAS
PF12 ------> FMC_A6
PF13 ------> FMC_A7
PF14 ------> FMC_A8
PF15 ------> FMC_A9
PG0 ------> FMC_A10
PG1 ------> FMC_A11
PE7 ------> FMC_D4
PE8 ------> FMC_D5
PE9 ------> FMC_D6
PE10 ------> FMC_D7
PE11 ------> FMC_D8
PE12 ------> FMC_D9
PE13 ------> FMC_D10
PE14 ------> FMC_D11
PE15 ------> FMC_D12
PD8 ------> FMC_D13
PD9 ------> FMC_D14
PD10 ------> FMC_D15
PD14 ------> FMC_D0
PD15 ------> FMC_D1
PG2 ------> FMC_A12
PG4 ------> FMC_BA0
PG5 ------> FMC_BA1
PG8 ------> FMC_SDCLK
PD0 ------> FMC_D2
PD1 ------> FMC_D3
PG15 ------> FMC_SDNCAS
PE0 ------> FMC_NBL0
PE1 ------> FMC_NBL1
*/
HAL_GPIO_DeInit(GPIOF, 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);
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_0|GPIO_PIN_2|GPIO_PIN_3);
HAL_GPIO_DeInit(GPIOG, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_4
|GPIO_PIN_5|GPIO_PIN_8|GPIO_PIN_15);
HAL_GPIO_DeInit(GPIOE, 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);
HAL_GPIO_DeInit(GPIOD, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_14
|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1);
/* USER CODE BEGIN FMC_MspDeInit 1 */
/* USER CODE END FMC_MspDeInit 1 */
}
void HAL_SDRAM_MspDeInit(SDRAM_HandleTypeDef* sdramHandle){
/* USER CODE BEGIN SDRAM_MspDeInit 0 */
/* USER CODE END SDRAM_MspDeInit 0 */
HAL_FMC_MspDeInit();
/* USER CODE BEGIN SDRAM_MspDeInit 1 */
/* USER CODE END SDRAM_MspDeInit 1 */
}
/**
* @}
*/
/**
* @}
*/
fmc.h
/* USER CODE BEGIN Header */
/**
******************************************************************************
* File Name : FMC.h
* Description : This file provides code for the configuration
* of the FMC peripheral.
******************************************************************************
* @attention
*
* Copyright (c) 2024 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __FMC_H
#define __FMC_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern SDRAM_HandleTypeDef hsdram1;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_FMC_Init(void);
void HAL_SDRAM_MspInit(SDRAM_HandleTypeDef* hsdram);
void HAL_SDRAM_MspDeInit(SDRAM_HandleTypeDef* hsdram);
/* USER CODE BEGIN Prototypes */
extern SDRAM_HandleTypeDef g_sram_handle; /* SDRAM句柄 */
#define BANK5_SDRAM_ADDR ((uint32_t)(0XC0000000)) /* SDRAM�?始地�? */
/* 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)
uint8_t sdram_send_cmd(uint8_t bankx, uint8_t cmd, uint8_t refresh, uint16_t regval);
void fmc_sdram_write_buffer(uint8_t *pbuf, uint32_t writeaddr, uint32_t n);
void fmc_sdram_read_buffer(uint8_t *pbuf, uint32_t readaddr, uint32_t n);
void sdram_initialization_sequence(void);
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /*__FMC_H */
/**
* @}
*/
/**
* @}
*/