cubemx配置sdram

一、sdram介绍

SDRAM,英文名是: Synchronous Dynamic Random Access Memory,即同步动态随机存储器,相较于 SRAM(静态存储器), SDRAM 具有:容量大和价格便宜的特点。

二、W9825G6KH芯片介绍

2.1 芯片内部结构

芯片内部结构如下图
在这里插入图片描述

2.2 芯片引脚说明

  • CLK:时钟信号,在该时钟的上升沿采集输入信号
  • CKE:时钟使能,禁止时钟时, SDRAM 会进入自刷新模式
  • CS:片选信号,低电平有效
  • RAS:行地址选通信号,低电平时,表示行地址
  • CAS:列地址选通信号,低电平时,表示列地址
  • WE:写使能信号,低电平有效
  • A0~A12:地址线(行/列)
  • BS0, BS1:BANK 地址线
  • DQ0~15:数据线
  • LDQM,UDQM:数据掩码,表示 DQ 的有效部分

2.3 芯片工作原理

2.3.1 寻址

  • 首先 RAS 信号为低电平,选通行地址,地址线 A0~A12 所表示的地址,会被传输并锁存到行地址译码器里面,作为行地址,同时 BANK 地址线上面的 BS0, BS1 所表示的 BANK 地址,也会被锁存,选中对应的 BANK。
  • 然后, CAS 信号为低电平,选通列地址,地址线 A0~A12 所表示的地址,会被传输并锁存到列地址译码器里面,作为列地址,这样,就完成了一次寻址。
    总结:RAS低电平期间,选择BANK和行地址;CAS低电平期间,选择列地址。

2.3.2 数据传输

寻址过后,就可以读写sdram中的数据。

三、cubemx配置

W9825G6KH地址线A0~A12共13位,内部有4个bank,数据从DQ0到DQ15共16位,这里使用两片W9825G6KH组成32位,每片提供32M字节的sdram,两片可提供64M字节的sdram。
在这里插入图片描述
列地址A0-A8共9个位,行地址A0-A12共13个位。
在这里插入图片描述
配置W9825G6KH的延时参数如下:
在这里插入图片描述

四、sdram的使用

初始化时序

//SDRAM配置参数
#define SDRAM_MODEREG_BURST_LENGTH_1             ((u16)0x0000)
#define SDRAM_MODEREG_BURST_LENGTH_2             ((u16)0x0001)
#define SDRAM_MODEREG_BURST_LENGTH_4             ((u16)0x0002)
#define SDRAM_MODEREG_BURST_LENGTH_8             ((u16)0x0004)
#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL      ((u16)0x0000)
#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED     ((u16)0x0008)
#define SDRAM_MODEREG_CAS_LATENCY_2              ((u16)0x0020)
#define SDRAM_MODEREG_CAS_LATENCY_3              ((u16)0x0030)
#define SDRAM_MODEREG_OPERATING_MODE_STANDARD    ((u16)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((u16)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE     ((u16)0x0200)
//发送命令函数,下面的初始化时序需要使用
u8 SDRAM_Send_Cmd(u8 bankx,u8 cmd,u8 refresh,u16 regval)
{
    
    
    u32 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,0XFFFF)==HAL_OK) //向SDRAM发送命令
    {
    
    
        return 0;  
    }
    else return 1;    
}
//发送SDRAM初始化序列
void SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram)
{
    
    
	u32 temp=0;

    //SDRAM控制器初始化完成以后还需要按照如下顺序初始化SDRAM
    SDRAM_Send_Cmd(0,FMC_SDRAM_CMD_CLK_ENABLE,1,0); //时钟配置使能
    HAL_Delay(1);                                  //至少延时200us
	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=(u32)SDRAM_MODEREG_BURST_LENGTH_4          |	//设置突发长度: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的模式寄存器
    
    //刷新频率计数器(以SDCLK频率计数),计算方法:
	//COUNT=SDRAM刷新周期/行数-20=SDRAM刷新周期(us)*SDCLK频率(Mhz)/行数
    //我们使用的SDRAM刷新周期为64ms,SDCLK=200/2=100Mhz,行数为8192(2^13).
	//所以,COUNT=64*1000*100/8192-20=677
	HAL_SDRAM_ProgramRefreshRate(hsdram,677);	
}	

测试函数

#define Bank5_SDRAM_ADDR    ((uint32_t)(0XC0000000)) //SDRAM开始地址
u16 testsram[250000] __attribute__((at(0XC0000000)));//测试用数组
//SDRAM内存测试	    
for(cnt=0;cnt<250000;cnt++)
{
    
    
	testsram[cnt]=cnt;					 
}
for(ts=0;ts<250000;ts++)
{
    
    
	printf("testsram[%d]:%d\r\n",cnt,testsram[cnt]);
}

输出结果
将存储在sdram中的数组的数据打印出来,我们可以将数据通过__attribute__定义在sdram里,这就是sdram的用法。
在这里插入图片描述

参考例程

我的码云地址:cubemx配置sdram例程

猜你喜欢

转载自blog.csdn.net/weixin_43810563/article/details/114761836