SDRAM:Synchronous Dynamic Random Access Memory,同步动态随机存储器,同步是指内存工作需要同步时钟,内部的命令的发送与数据的传输都以它为基准;动态是指存储阵列需要不断的刷新来保证数据不丢失;随机是指数据不是线性依次存储,而是自由指定地址进行数据读写

一.内部结构

原理图如下:

存储逻辑结构:

可以看出SDRAM的内部是一个阵列,就像表格一样,其寻址方式是按照块、行、列来的,即先选定SDRAM芯片,然后发出块信号确定那一块,再发出行信号确定哪一行,再发出列信号确定哪一列。

CPU对SDRAM的访问可以分为以下几步:

  • CPU对存储控制器发出统一编址
  • 内存控制器发出片选信号,选定SDRAM芯片
  • 选定哪一个Bank(通过ADDR24、ADDR25信号线选定,总共4个Bank)
  • 对选定的Bank进行行列寻址
  • 找到对应的地址,通过32根数据线进行数据传输(原理图中是32位)

看起来很简单,但是我们要考虑到,不同规格SDRAM对应着不同的寻址方式,因为不同的SDRAM可能行列数不一样,对时序要求不一样,所以在访问SDRAM之前,我们要配置存储控制器中的一些寄存器来匹配SDRAM!!!

二.相关寄存器

存储控制器一共有13个寄存器,6种寄存器,对BANK0~BANK5进行访问时,只需要配置BWSCON和BANKCONx寄存器,但是对SDRAM访问,不仅仅需要对这俩个寄存器进行配置,还需要额外配置4个寄存器。

下面以访问SDRAM为例子介绍一下这些寄存器(按照芯片手册中的顺序来介绍):

BWSCON

位宽&等待控制寄存器

  • ST6:决定是否使用SDRAM的数据掩码,对SDRAM时为0,对SRAM时为1。
  • WS6:决定是否使用WAIT信号,一般不使用。(WAIT信号就是在SDRAM没准备好的时候,由SDRAM发给CPU,请求延迟一段时间)
  • DW6:决定BANK位宽,自然是32位。

所以,BWSCON寄存器要或运算的值为:0x02000000

BANKCON6

BANK控制寄存器,用来控制外接设备的访问时序的,BANK0~BANK5默认0X0700

对于SDRAM的访问,我们需要配置的就是图中阴影部分的:

  • MT:决定BANK外接的是SDRAM还是SRAM,SDRAM选择11.

  • Trcd:行列信号之间的延迟时间,根据芯片手册得知最小为21ns,而我们的HCLK时钟为100MHz,一个clock10ns,所以保险起见选择30ns,即:01。

  • SCAN:设置列地址位,这里使用的SDRAM列地址一共9位,所以为:01.

所以,BANKCON6寄存器要或运算的值为:0x00018005

REFRESH

刷新控制寄存器,用来控制SDRAM的刷新模式和刷新频率。我们知道,SDRAM中的存储阵列需要不断的刷新来保证数据不丢失,所以就要配置刷新控制寄存器。

  • REFEN:决定使能刷新功能,当然是开启了,值为:1

  • TREFMD:刷新的模式,一般自动刷新,值为:0

  • Trp:根据芯片手册得知20ns保险,对应2clocks,值为:00

  • Tsrc:默认即可

  • Refresh Counter:刷新计数的值,查SDRAM的手册可得8192个刷新周期为64ms,则每一个刷新周期为7.8125ns,通过公式计算可得刷新计数的值为:1955
    所以,REFRESH寄存器要或运算的值为:0x008c07a3

BANKSIZE

  • BURST_EN:决定是否允许突发传输,值为:1。
  • SCKE_EN:决定是否使用SCKE信号来决定省电模式,值为:1。
  • SCLK_EN:决定SCLK时钟信号的产生模式,值为:1。
  • BK76MAP:决定BANK6、BANK7的大小,这里SDRAM是64M,所以值为:001。(BANK0~BANK5的大小是128M固定的,BANK6、BANK7的大小是可以控制的)

所以,BANKSIZE寄存器要或运算的值为:0x000000b1

MRSR

SDRAM模式设置寄存器

只有CL的值是可以修改的,查询芯片手册:

可知,CL可以是2clock或者是3clock,保险起见,值为:011

所以,MRSR寄存器要或运算的值为:0x00000030

/**********************************************************************************************************************/
综上所述,对SDRAM初始化的代码为:

void SDRAM_Init(void)
{
/* 对BANK6进行配置 以访问SDRAM */
BWSCON |= 0x02000000;//对SDRAM使用数据掩码、不使用WAIT信号、设置BANK6位宽32bit
BANKCON6 = 0x00018005;//BANK6外接SDRAM、行列信号间延迟3clocks、设置列地址位数
REFRESH = 0x008c07a3;//配置刷新模式及刷新计数值
BANKSIZE = 0x000000b1;//设置BANK6大小为64MB
MRSRB6 = 0x00000030;//设置CL为3clocks
}

三.读写SDRAM

对SDRAM进行配置之后,进行读写操作,看看写进去的值和读出来的值是否统一。

测试就直接写在main.c中吧:

#include "s3c2440_soc.h"
#include "uart.h" void SDRAM_Init(void)
{
/* 对BANK6进行配置 以访问SDRAM */
BWSCON |= 0x02000000;//对SDRAM使用数据掩码、不使用WAIT信号、设置BANK6位宽32bit
BANKCON6 = 0x00018005;//BANK6外接SDRAM、行列信号间延迟3clocks、设置列地址位数
REFRESH = 0x008c07a3;//配置刷新模式及刷新计数值
BANKSIZE = 0x000000b1;//设置BANK6大小为64MB
MRSRB6 = 0x00000030;//设置CL为3clocks
} int SDRAM_Test(void)
{
/* BANK6 基地址0x30000000 */
volatile unsigned char *p = (volatile unsigned char *)(0x30000000);
int n;
/* 写入20Byte数据 */
for( n=0;n<20;n++ )
{
*(p+n) = 0xbb;
} for( n=0;n<20;n++ )
{
if( 0xbb != *(p+n) )
return 0;
} return 1;
} int main(void)
{
SDRAM_Init();
uart0_init(); if( SDRAM_Test() )
puts("OK!!!\n");
else
puts("NOT OK!!!\n"); return 0; }

代码亲测可以。

最新文章

  1. linux的点滴积累
  2. 加速chrome之Vimium快捷键
  3. NDK设置C++编译器版本号
  4. 安装SQL Server2008时 检测时有“重启计算机”失败
  5. Eclipse的快捷键及常用设置
  6. html进阶css(2)
  7. Andriod中自定义Dialog样式的Activity点击空白处隐藏软件盘(Dialog不消失)
  8. .Net Core 系列:2、ADO.Net 基础
  9. js string类型时间转换成Date类型
  10. scrapy meta不用pipe用命令-o
  11. shell脚本使用技巧7--cat
  12. centos7 安装python3.6 脚本
  13. [leetcode]449. Serialize and Deserialize BST序列化反序列化二叉搜索树(尽量紧凑)
  14. Android中Activity的四种开发模式
  15. top k
  16. 【转载】 C#中数组、ArrayList和List三者的区别
  17. 关系型数据库MySQL主从同步-读写分离
  18. LeetCode 536----Construct Binary Tree from String
  19. CentOS6.5和RedHat6.5下以rpm方式安装mysql-5.6.20
  20. 详细解读KMP模式匹配算法

热门文章

  1. Java实验项目三——宠物商店
  2. APP-SECURITY-404 组件导出漏洞复现
  3. HCNA Routing&amp;Switching之静态路由
  4. ADC采集电流相关知识
  5. CF1444D Rectangular Polyline[题解]
  6. Django基础08篇 filter&amp;tag
  7. 根据序列号查IP
  8. 数组去重汇总—v客学院技术分享
  9. 网络损伤仪WANsim--不同的部署方式
  10. [考试总结]noip模拟9