image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
在 fmc.c 中添加相关定义和函数配置ADRAM
/* USER CODE BEGIN 0 */
static FMC_SDRAM_CommandTypeDef Command;
/**
* @brief 延迟一段时间
* @param 延迟的时间长度
* @retval None
*/
static void SDRAM_delay(__IO uint32_t nCount)
{
__IO uint32_t index = 0;
for(index = (100000 * nCount); index != 0; index--)
{
}
}
/**
* @brief 对SDRAM芯片进行初始化配置
* @param None.
* @retval None.
*/
void SDRAM_InitSequence(void)
{
uint32_t tmpr = 0;
/* Step 3 --------------------------------------------------------------------*/
/* 配置命令:开启提供给SDRAM的时钟 */
Command.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
Command.CommandTarget = FMC_COMMAND_TARGET_BANK;
Command.AutoRefreshNumber = 1;
Command.ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT);
/* Step 2: Insert 100 us minimum delay */
/* Inserted delay is equal to 1 ms due to systick time base unit (ms) */
SDRAM_delay(1);
/* Step 5 --------------------------------------------------------------------*/
/* 配置命令:对所有的bank预充电 */
Command.CommandMode = FMC_SDRAM_CMD_PALL;
Command.CommandTarget = FMC_COMMAND_TARGET_BANK;
Command.AutoRefreshNumber = 1;
Command.ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT);
/* Step 6 --------------------------------------------------------------------*/
/* 配置命令:自动刷新 */
Command.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
Command.CommandTarget = FMC_COMMAND_TARGET_BANK;
Command.AutoRefreshNumber = 4;
Command.ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT);
/* Step 7 --------------------------------------------------------------------*/
/* 设置sdram寄存器配置 */
tmpr = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_2 |
SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
SDRAM_MODEREG_CAS_LATENCY_3 |
SDRAM_MODEREG_OPERATING_MODE_STANDARD |
SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
/* 配置命令:设置SDRAM寄存器 */
Command.CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
Command.CommandTarget = FMC_COMMAND_TARGET_BANK;
Command.AutoRefreshNumber = 1;
Command.ModeRegisterDefinition = tmpr;
/* Send the command */
HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT);
/* Step 8 --------------------------------------------------------------------*/
/* 设置刷新计数器 */
/*刷新速率 = (COUNT + 1) x SDRAM 频率时钟
COUNT =( SDRAM 刷新周期/行数) - 20*/
/* 64ms/8192=7.813us (7.813 us x FSDCLK) - 20 =683 */
HAL_SDRAM_ProgramRefreshRate(&sdramHandle, 683);
// FMC_SetRefreshCount(1386);
// /* 发送上述命令*/
// while(FMC_GetFlagStatus(FMC_BANK_SDRAM, FMC_FLAG_Busy) != RESET)
// {
// }
}
在 fmc.h 中添加相关定义
/* USER CODE BEGIN Private defines */
#define IS42S16400J_SIZE (32 * 1024 * 1024) //,32M字节
/*SDRAM 的bank选择*/
#define FMC_BANK_SDRAM FMC_Bank2_SDRAM
#define FMC_COMMAND_TARGET_BANK FMC_SDRAM_CMD_TARGET_BANK2
#define sdramHandle hsdram1
#define SDRAM_TIMEOUT ((uint32_t)0xFFFF)
#define SDRAM_BANK_ADDR ((uint32_t)0xD0000000)
/**
* @brief FMC 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)
void SDRAM_InitSequence(void);
/* USER CODE END Private defines */
在 main.c 中添加相关定义和函数
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
long long count=0,sdram_count=0;
uint32_t RadomBuffer[10000];
uint32_t ReadBuffer[10000];
#define SDRAM_SIZE (IS42S16400J_SIZE/4)
uint32_t *pSDRAM;
void SDRAM_Check(void);
/* USER CODE END Includes */
/* USER CODE BEGIN 4 */
void SDRAM_Check(void)
{
pSDRAM=(uint32_t*)SDRAM_BANK_ADDR;
count=0;
printf("开始写入SDRAM\r\n");
for(sdram_count=0;sdram_count<SDRAM_SIZE;sdram_count++)
{
*pSDRAM=RadomBuffer[count];
count++;
pSDRAM++;
if(count>=10000)
{
count=0;
}
}
printf("写入总字节数:%d\r\n",(uint32_t)pSDRAM-SDRAM_BANK_ADDR);
count=0;
pSDRAM=(uint32_t*)SDRAM_BANK_ADDR;
printf("开始读取SDRAM并与原随机数比较\r\n");
sdram_count=0;
for(;sdram_count<SDRAM_SIZE;sdram_count++)
{
if(*pSDRAM != RadomBuffer[count])
{
printf("数据比较错误——退出~\r\n");
break;
}
count++;
pSDRAM++;
if(count>=10000)
{
count=0;
}
}
printf("比较通过总字节数:%d\r\n",(uint32_t)pSDRAM-SDRAM_BANK_ADDR);
if(sdram_count == SDRAM_SIZE)
{
LED_GREEN;
printf("SDRAM测试成功\r\n");
}
else
{
LED_RED;
printf("SDRAM测试失败\r\n");
}
}
/* USER CODE END 4 */
在 void main() 中添加相关函数
/* USER CODE BEGIN 2 */
SDRAM_InitSequence();//对SDRAM芯片进行初始化配置
printf("\r\n野火STM32F429 SDRAM 读写测试例程\r\n");
/*初始化RNG模块产生随机数*/
hrng.Instance = RNG;
HAL_RNG_Init(&hrng);
printf("开始生成10000个SDRAM测试随机数\r\n");
for(count=0;count<10000;count++)
{
RadomBuffer[count]=HAL_RNG_GetRandomNumber(&hrng);
}
printf("10000个SDRAM测试随机数生成完毕\r\n");
SDRAM_Check();//测试读写10000个随机数,对比读写的数量
/* USER CODE END 2 */