SDRAM
Posted st-home
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SDRAM相关的知识,希望对你有一定的参考价值。
环境:STM32F769discovery板
SDRAM芯片:用的MT48LC4M32B2B5-6A 16Mbyte (sdram和flash一般标的容量都是bit)
硬件图:
第一步 配置FMC控制器:
由硬件图可以看出 时钟芯片使能SDRAM BANK0 且MT48LC4M32B2B5-6A有4块BANK(一般的SDRAM都有4块),地址线和数据线可由硬件图确定。
sdram有两种刷新操作:自动刷新( Auto Refresh)和自我刷新( Self Refresh),在发送 Refresh命令时,如果 CKE 有效(高电平),则使用自动刷新模式,否则使用自我刷新模式。
第二步 配置FMC参数
@Param1: FMC可以同时控制两个SDRAM ,如下图所示,本次实验用的SDRAM 1,地址为0xc0000000
@Param2:列地址线 column 28 = 256 此处为8
@Param3:行地址线 row 可由datasheet中的参数确认:212 = 4k 此处为12
@Param4:column address select latency 列地址选择延时 即在发送激活命令后,会将行地址一起发送过去,当发送read命令后,会将列地址一起发送过去,CL就是发送过列地址后,QD数据线上的数据在延时多少周期后有效:SDRAM时钟可由SDRAM common clock二分频或者三分频,为保证速度,我们HCLK/2 = 108MHZ 即一个时钟周期9.26ns
由上图可知:CL为18ns等于2个时钟周期,但是考虑冗余设计,此处选择3个时钟周期
@Param5:默认关闭写保护
@Param6:对HCLK分频,支持2分频或者三分频
@Param7:突发读使能:如果要连续读/写就还要对当前存储单元的下一个单元进行寻址,也就是要不断的发送列地址与读/写命令(行地址不变,所以不用再对行寻址)只要指定起始列地址与突发长度,内存就会依次地自动对后面相应数量的存储单元进行读/写操作而不再需要控制器连续地提供列地址。 这样,除了第一个数据的传输需要若干个周期外,其后每个数据只需一个周期的即可获得。在SDRAM的初始化队列函数中设置
@Param8:这两个位可定义在 CAS 延迟后延后多少个 HCLK 时钟周期读取数据( 00~10,表示 0~2 )。 这里,我们设置为 00 即可。
第三步 SDRAM时序参数
以下所有时序参数均可在datasheet中计算可得
@Param1:加载模式寄存器到激活状态延时
@Param2:退出自我刷新模式延时:
由第二步可知,一个时钟周期为9.26ns,此处为70ns一共7个时钟周期
@Param3:自我刷新周期
第一个为商业工业级64ms(6个时钟周期)刷新一次 第二个为汽车级16ms;我们使用64ms
@Param4:行循环延时
注意,发送行地址的时候为激活命令,此处的名称为激活命令到激活命令7个时钟周期
@Param5:写恢复时间
如图为两个时钟周期
@Param6:SDRAM行预充电延时
如图为两个时钟周期
@Param7:行到列延时
第四步 SDRAM初始化序列
1 第一步:上电并且时钟使能 2 /* Step 1: Configure a clock configuration enable command */ 3 Command.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE; 4 Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; 5 Command.AutoRefreshNumber = 1; //发送一次 6 Command.ModeRegisterDefinition = 0; 7 /* Send the command */ 8 HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT); 9 第二步:上电后至少等待200us才能发送其他命令,Hal库提供的最小延时为1ms所以 10 /* Step 2: Insert 100 us minimum delay */ 11 /* Inserted delay is equal to 1 ms due to systick time base unit (ms) */ 12 HAL_Delay(1); 13 第三步:发送预充电命令 14 /* Step 3: Configure a PALL (precharge all) command */ 15 Command.CommandMode = FMC_SDRAM_CMD_PALL; 16 Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; 17 Command.AutoRefreshNumber = 1; //发送一次 18 Command.ModeRegisterDefinition = 0; 19 20 /* Send the command */ 21 HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT); 22 第四步:发送自动刷新命令 23 24 /* Step 4: Configure an Auto Refresh command */ 25 Command.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE; 26 Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; 27 Command.AutoRefreshNumber = 8; //至少发送8次自刷新命令 28 Command.ModeRegisterDefinition = 0; 29 30 /* Send the command */ 31 HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT); 32 33 第五步:发送SDRAM模式寄存器参数 34 /* Step 5: Program the external memory mode register */ 35 tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 |36 SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |37 SDRAM_MODEREG_CAS_LATENCY_3 |38 SDRAM_MODEREG_OPERATING_MODE_STANDARD |39 SDRAM_MODEREG_WRITEBURST_MODE_SINGLE; 40 41 Command.CommandMode = FMC_SDRAM_CMD_LOAD_MODE; 42 Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; 43 Command.AutoRefreshNumber =1; 44 Command.ModeRegisterDefinition = tmpmrd; //SDRAM寄存器内容 45 46 /* Send the command */ 47 HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT); 48 第六步:设置自刷新率值 49 /* Step 6: Set the refresh rate counter */ 50 /* Set the device refresh rate */ 51 HAL_SDRAM_ProgramRefreshRate(&hsdram1, RefreshCount); 52 RefreshCount计算: 53 COUNT = (SDRAM刷新周期/行数)/SDRAM时钟周期 54 64ms / 4096 / 9.26ns +20(考虑冗余) 9.26ns为(HCLK/2)
以上是关于SDRAM的主要内容,如果未能解决你的问题,请参考以下文章
对黑金AX301中sdram数据读取demo代码中的几个疑问的探索