1.STM32CUBEMX配置(选择FMC模块,需要根据芯片配置参数)
SDRAM配置
参数配置
时钟配置
2.驱动层(配合内存管理使用)
/*
* dSDRAM.c
*
* Created on: 2023/12/5
* Author: WZX
*/
#include "dSDRAM.h"
#include <stddef.h>
static SDRAM_TypeDef_t *sdram;
/*********************************************************************
* @fn dSDRAM_Init
*
* @brief SDRAM初始化.
*
* @param sdram_t:sdram指针
*
* @return none
*/
void dSDRAM_Init(SDRAM_TypeDef_t *sdram_t)
{
if(sdram_t == NULL)
{
return;
}
sdram = sdram_t;
sdram->SDRAM_Init();
}
/*********************************************************************
* @fn dSDRAM_ReadBuffer
*
* @brief SDRAM读取数据.
*
* @param pBuffer:读数据源地址指针
*
* @param ReadAddress:读地址
*
* @param BufferSize:读数据长度
*
* @return none
*/
void dSDRAM_ReadBuffer(uint32_t *pBuffer, uint32_t ReadAddress, uint32_t BufferSize)
{
volatile uint32_t read_pointer = (uint32_t)ReadAddress;
while(sdram->SDRAM_Status() != 0);
for(; BufferSize != 0; BufferSize--)
{
*pBuffer++ = *(volatile uint32_t *)(sdram->SDRAM_Address + read_pointer);
read_pointer += 4;
}
}
/*********************************************************************
* @fn dSDRAM_WriteBuffer
*
* @brief sdram写数据.
*
* @param pBuffer:写数据源地址指针
*
* @param ReadAddress:写地址
*
* @param BufferSize:写数据长度
*
* @return none
*/
void dSDRAM_WriteBuffer(uint32_t *pBuffer, uint32_t WriteAddress, uint32_t BufferSize)
{
volatile uint32_t write_pointer = (uint32_t)WriteAddress;
sdram->SDRAM_WriterPotection_Disable();
while(sdram->SDRAM_Status() != 0);
for(; BufferSize != 0; BufferSize--)
{
*(uint32_t *) (sdram->SDRAM_Address + write_pointer) = *pBuffer++;
write_pointer += 4;
}
}
/*
* dSDRAM.h
*
* Created on: 2023/12/5
* Author: WZX
*/
#ifndef _DSDRAM_H_
#define _DSDRAM_H_
#include <stdint.h>
typedef struct
{
uint32_t SDRAM_Address;
uint8_t (*SDRAM_Init)(void);
uint8_t (*SDRAM_Status)(void);
uint8_t (*SDRAM_WriterPotection_Disable)(void);
} SDRAM_TypeDef_t;
void dSDRAM_Init(SDRAM_TypeDef_t *sdram_t);
void dSDRAM_ReadBuffer(uint32_t *pBuffer, uint32_t ReadAddress, uint32_t BufferSize);
void dSDRAM_WriteBuffer(uint32_t *pBuffer, uint32_t WriteAddress, uint32_t BufferSize);
#endif
3.SDRAM初始化
/*
* Cmd_SDRAM.c
*
* Created on: 2023/12/5
* Author: 王震霄
*/
#include "Cmd_SDRAM.h"
#include "dSDRAM.h"
#include "Wos_Malloc.h"
#include "stm32h7xx.h"
extern SDRAM_HandleTypeDef hsdram1;
static uint8_t sdram_init(void);
static uint8_t sdram_status(void);
static uint8_t sdram_writeprotection_disable(void);
uint8_t SDRAM_Test(void);
#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)
/*********************************************************************
* @fn Cmd_SDRAM_Init
*
* @brief SDRAM初始化.
*
* @param none
*
* @return none
*/
void Cmd_SDRAM_Init(void)
{
static SDRAM_TypeDef_t sdram_temp;
sdram_temp.SDRAM_Address = 0xD0000000;
sdram_temp.SDRAM_Init = sdram_init;
sdram_temp.SDRAM_Status = sdram_status;
sdram_temp.SDRAM_WriterPotection_Disable = sdram_writeprotection_disable;
dSDRAM_Init(&sdram_temp);
Wos_Meminit(WOS_SRAMEX);
}
//
static uint8_t sdram_init(void)
{
FMC_SDRAM_CommandTypeDef Command;
uint32_t tmpr = 0;
/* Step 1 ----------------------------------------------------------------*/
/* 配置命令:开启提供给SDRAM的时钟 */
Command.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
Command.AutoRefreshNumber = 1;
Command.ModeRegisterDefinition = 0;
/* 发送配置命令 */
HAL_SDRAM_SendCommand(&hsdram1, &Command, 0xFFFF);
/* Step 2: 延时100us */
HAL_Delay(1);
/* Step 3 ----------------------------------------------------------------*/
/* 配置命令:对所有的bank预充电 */
Command.CommandMode = FMC_SDRAM_CMD_PALL;
Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
Command.AutoRefreshNumber = 1;
Command.ModeRegisterDefinition = 0;
/* 发送配置命令 */
HAL_SDRAM_SendCommand(&hsdram1, &Command, 0xFFFF);
/* Step 4 ----------------------------------------------------------------*/
/* 配置命令:自动刷新 */
Command.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
Command.AutoRefreshNumber = 8;
Command.ModeRegisterDefinition = 0;
/* 发送配置命令 */
HAL_SDRAM_SendCommand(&hsdram1, &Command, 0xFFFF);
/* Step 5 ----------------------------------------------------------------*/
/* 设置sdram寄存器配置 */
tmpr = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 |
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_SDRAM_CMD_TARGET_BANK2;
Command.AutoRefreshNumber = 1;
Command.ModeRegisterDefinition = tmpr;
/* 发送配置命令 */
HAL_SDRAM_SendCommand(&hsdram1, &Command, 0xFFFF);
/* Step 6 ----------------------------------------------------------------*/
/* 设置刷新计数器 */
/* 刷新周期=64ms/8192行=7.8125us */
/* COUNT=(7.8125us x Freq) - 20 */
/* 设置自刷新速率 */
HAL_SDRAM_ProgramRefreshRate(&hsdram1, 824);
return 0;
}
static uint8_t sdram_status(void)
{
if(HAL_SDRAM_GetState(&hsdram1) != HAL_SDRAM_STATE_RESET)
{
return 0;
}
return 1;
}
static uint8_t sdram_writeprotection_disable(void)
{
if(HAL_SDRAM_WriteProtection_Disable(&hsdram1) == HAL_OK)
{
return 0;
}
return 1;
}