基于SMT32CUBEMX的SDRAM

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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值