SDRAM作为内存在嵌入式中必不可少,懂了SDRAM原理,初始化就非常简单,今天手把手教你SDRAM初始化。

我用的SOC:S3C2440,SDRAM:两片EM63A165组合

在开始本文的内容前,如果不了解SDRAM的话,先阅读这篇文章:详解内存SDRAM原理(P-Bank、L-Bank、刷新、预充电等)

嵌入式Linux学习系列全部文章:嵌入式Linux学习—从裸机到应用教程大全

1.  先捋一捋重要的部分

1.1 SDRAM读\写操作

根据SDRAM原理,我们可以总结出:

SDRAM读操作

1. 先发出芯片有效命令(ACTIVE),并锁定相应的L-BANK地址(BA0、BA1给出)和行地址(A0~A12给出)。

2. 芯片激活命令后必须等待大于tRCD(SDRAM的RAS到CAS的延迟指标)时间后,发出读命令。

3. CL(CAS延迟值)个时钟周期后,读出数据依次出现在数据总线上。

4. 在读操作的最后,要向SDRAM发出预充电(PRECHARGE)命令,以关闭已经激活的L-BANK。等待tRP时间(PRECHAREG命令后,相隔tRP时间,才可再次访问该行)后,可以开始下一次的读、写操作。

SDRAM写操作

1.先发出芯片有效命令(ACTIVE),并锁定相应的L-BANK地址(BA0、BA1给出)和行地址(A0~A12给出)。

2. 芯片有效命令发出后必须等待大于tRCD的时间后,发出写命令数据,待写入数据依次送到DQ(数据线)上。

3. 在最后一个数据写入后,延迟tWR(写入/校正时间)时间。发出预充电命令,关闭已经激活的页。等待tRP时间后,可以展开下一次操作。

读写操作都是由S3C2440的内存控制器完成的,但是其中的部分数据需要我们根据使用的SDRAM来设置。

从上面的读写总结来看,我们需要至少需要设置一下内容:

1. tRCD(SDRAM的RAS到CAS的延迟)

2. Trp:行地址选用预充电时间

3.CL(CAS延迟值)

4.tRP(预充电到RAS的延迟)

当然,肯定还有别的要设置,但以上是重点。

1.2 S3C2440存储地址空间

1.2.1 地址空间布局(Memory MAP)

  • S3C2440作为32位的CPU,可以使用的地址范围理论上达到4GB。除去用于连接外设的1GB地址空间外,还有一部分是CPU内部寄存器的地址,剩下的地址空间没有使用。
  • BANK0-BANK7 0x00000000-0x40000000
  • S3C2440的内部外设寄存器地址范围都处于0x48000000-0x5FFFFFFF  (GPIO-0x56000000)
  • SDRAM启始地址为:0x30000000(我的板子SDRAM在nGCS6)

1.2.2  SDRAM硬件接线图分析

  • SDRAM时钟有效信号SCKE;SDRAM时钟信号SCLK0/SCLK1
  • 数据掩码信号DQM0/DQM1/DQM2/DQM3(每个DQM控制8bit,防止写字节数据覆盖前面位-32bit操作的)
  • SDRAM片选信号nSCS0(它与nGCS6是同一引脚的两个功能)
  • SDRAM行地址选通脉冲信号nSRAS
  • SDRAM列地址选通脉冲信号nSCAS
  • 写允许信号nWE(它不是专用于SDRAM的)
  • EM63A165容量:4Banks x 4M x 16Bit   =  32Mbyte
  • SDRAM行地址线13根,列地址线9根(Row Address : RA0 ~ RA12, Column Address : CA0 ~ CA8),它们是复用的。

2. 读手册,设置寄存器

2.1 BWSCON寄存器(BUS WIDTH & WAIT CONTROL REGISTER)

STx:一次传输数据为32位,假如需要的数据小于32位,则需要掩码屏蔽功能,0时对写屏蔽,1时读写均屏蔽,而SDRAM读时,有内部屏蔽功能,所以只需要写屏蔽,设置为0

WSx:是否使用存储器的WAIT信号,通常设为0,(可以通过外部的“wait”信号延长总线的访问周期,也就是内存芯片向CPU发的,这里没有用到)

DWx:设置焊接存储器芯片的位宽,我的开发板使用两片容量为32M,位宽为16的SDRAM组成64M,32位存储器,因此DW7,DW6位设置为0b10,其它BANK不用设置采用默认值即可。

BANK0对应的是系统引导BANK,这4位比较特殊,它的设置是由硬件跳线决定的,因此不用设置

BWSCON设置结果:0x22000000

2.2 BANKCON6~BANKCON7 (BANK CONTROL REGISTER)

MT:设置BANK6的存储器类型,内存为SDRAM,设置为0b11,对应的应该设置Trcd和SCAN位,其它位和SDRAM无关

Trcd:RAS to CAS Delay行地址选通到列地址选通延迟,由内存芯片手册可知其Trcd为最少20ns,如果内存工作在100MHz,则该值至少要为2个时钟周期,因此设置为0b00

SCAN:SDRAM Column Address Number SDRAM的列地址数,我的内存芯片列地址数为9,设置为0b01

BANKCON6设置结果为:0x18001

2.3 REFRESH (REFRESH CONTROL REGISTER)

SDRAM的刷新有效,刷新频率设置寄存器(刷新)

REFEN:开启/关闭刷新功能,设置为1,开启刷新

TREFMD:SDRAM刷新模式,0=CBR/AutoRefresh,  1=Self Refresh,设置为0,自动刷新

Trp:行地址选通预充电时间,查内存芯片手册,发现最小值为18ns,HCLK=100M,周期10ns,因此设置为00就行。

Tsrc:单行刷新时间,查内存芯片手册,Trc最小为60ns/63ns,Trc=Tsrc+Trp,Tsrc设置为0b01即可。

Refresh Counter:内存存储单元刷新数,它通过下面公式计算出:

Refresh Counter = 2^11 + 1 – SDRAM时钟频率(MHz)* SDRAM刷新周期(uS)

SDRAM的刷新周期,也就是内存存储单元间隔需要多久进行一次刷新,前面内存工作原理分析可知电容数据保存上限为64ms,笔者使用内存芯片每个L-Bank共有8192行,因此每次刷新最大间隔为:64ms/8192 = 7.8125uS,如果内存工作在外部晶振频率12MHz下,Refresh Counter = 1955,如果内存工作在100MHz下,那么Refresh Counter = 1269(取大整数)

REFRESH寄存器设置为:

0x840000 + 1269 = 0x008404f5(HCLK = 100MHz)

2.4 BANKSIZE寄存器(BANKSIZE REGISTER)

设置内存的突发传输模式,省电模式和内存容量。

BURST_EN:是否开启突发模式, 0 = ARM内核禁止突发传输 1 = 开启突发传输,设置为1,开启突发传输

SCKE_EN:是否使用SCKE信号作为省电模式控制信号, 0 = 不使用SCKE信号作为省电模式控制信号 1 = 使用SCKE信号作为省电模式控制信号,通常设置为1

SCLK_EN: 设置向存储器输入工作频率,0 = 一直输入SCLK频率,即使没有内存操作也会输入, 1 = 仅当进行内存数据操作时才输入SCLK频率,通常设置为1

BK76MAP:设置Bank6/7的内存容量,笔者使用开发板内存为两片32M内存芯片并联成64M,它们全部都外接到Bank6上,因此选择0b001

BANKSIZE寄存器设置为:0xb1

2.5 SDRAM模式设置寄存器MRSRx (SDRAM MODE REGISTER SET REGISTER)

该寄存器用于设置CAS潜伏周期,可以手动设置的位只有CL[6:4]位,内存芯片手册说可以设置为2或3,CL=2,即0b010

MRSRB6设置为:0x00000020

3. 写代码和验证

makefile和启动代码就不给了,还不会的朋友,可以看看我之前的文章

嵌入式Linux入门-读数据手册,设置时钟,让代码跑得更快

#include <stdio.h>
#define BWSCON (*(volatile unsigned int *)0x48000000)
#define BANKCON6 (*(volatile unsigned int *)0x4800001C)
#define REFRESH (*(volatile unsigned int *)0x48000024)
#define BANKSIZE (*(volatile unsigned int *)0x48000028)
#define MRSRB6 (*(volatile unsigned int *)0x4800002C)#define GPFCON (*(volatile unsigned int *)0x56000050)
#define GPFDAT (*(volatile unsigned int *)0x56000054)
int sdram_test(void)
{volatile unsigned char *p = (volatile unsigned char *)0x30000000;int i;// write sdramfor (i = 0; i < 1000; i++)p[i] = 0x55;// read sdramfor (i = 0; i < 1000; i++)if (p[i] != 0x55)return -1;return 0;
}
int SDRAM_init(void)
{BWSCON = 0x22000000;BANKCON6 = 0x18001;REFRESH = 0x008404f5;BANKSIZE = 0xb1;MRSRB6 = 0x00000020;}
int main(void)
{   SDRAM_init();if(sdram_test()==0){GPFCON = 0x00000100;GPFDAT = 0;}return 0;
}

代码功能:初始化SDRAM,进行SDRAM测试,就是向SDRAM地址写入数据,再读出,测试成功LED灯就亮。

烧到板子上,发现灯亮了,再把初始化SDRAM_init();这一句给注释了,再烧到板子上,发现led灯不亮,

SDRAM实验成功。

嵌入式Linux入门-手把手教你初始化SDRAM(附代码)相关推荐

  1. 嵌入式Linux裸机开发(五)——SDRAM初始化

    嵌入式Linux裸机开发(五)--SDRAM初始化 一.SDRAM初始化流程 S5PV210有两个独立的DRAM控制器,一个最大支持512MB,一个最大支持1024MB,但两个控制器必须支持相同类型的 ...

  2. 【嵌入式开发】手把手教你4418/6818开发板屏幕修改 本文转自迅为: http://www.topeetboard.com 开发平台:iTOP-4418/6818开发板 44186818屏幕

    [嵌入式开发]手把手教你4418/6818开发板屏幕修改 本文转自迅为: http://www.topeetboard.com 开发平台:iTOP-4418/6818开发板 4418&6818 ...

  3. 嵌入式linux怎么入门,嵌入式linux入门六步走

    学习嵌入式linux怎样才能快速入门?这是很多出来华清远见参加嵌入式培训学员爱问的问题,这里做一个总结供大家参考,嵌入式linux入门可以概括为六步走: 第一步:学习基本的裸机编程 对于学硬件的人而言 ...

  4. 嵌入式 Linux 入门(五、Shell 脚本编程上:认识 Shell 脚本)

    大家好,是矜辰所致,嵌入式 Linux入 门第五课,本课开始简单学习一下 Shell 脚本编程. 目录 前言 一.Shell 脚本基础说明 1.1 什么是 Shell 脚本 1.2 Shell 脚本的 ...

  5. 嵌入式Linux入门经典笔记

    史上最牛的Linux内核学习方法论     点击下载 我的arm_linux移植笔记     点击下载 S3C2440完全开发流程     点击下载 Linux系统命令及其使用详解完整版     点击 ...

  6. Linux入门基础教程之Linux下软件安装

    Linux入门基础教程之Linux下软件安装 一.在线安装: sudo apt-get install 即可安装 如果在安装完后无法用Tab键补全命令,可以执行: source ~/.zshrc AP ...

  7. 分享:嵌入式Linux入门学习指导

    很多嵌入式linux初学者对嵌入式linux学习十分迷茫,不知道该怎么一步步学习,嵌入式linux学习方法,学习的流程步骤以及学习过程中需要看哪些好的书籍.下面凌阳教育嵌入式培训网就为大家整理的嵌入式 ...

  8. 嵌入式Linux入门13:应用层调试

    本文主要介绍应用程序的调试方法. 很多网友问我怎么调试内核,怎么查找代码bug.其实我的方法不多.一是靠经验,掉入的坑多了,做笔记回顾,自然就有了经验.二是靠printf/printk大法跟踪.三是利 ...

  9. 嵌入式 Linux 入门 环境篇(二、安装虚拟机 — 体验 Ubuntu 22.04)

    嵌入式 Linux入门 环境篇第二课,正好换了新电脑,更新 Ubuntu 虚拟机的安装, 体验一下 Ubuntu 22.04 ...... by 矜辰所致 前言 因为以前的电脑虚拟机环境我都配置好了, ...

  10. 嵌入式linux入门学习规划

    嵌入式linux入门学习规划 如何理解嵌入式系统 ◆嵌入式系统是面向用户.面向产品.面向应用的,它必须与具体应用相结合才会具有生命力.才更具有优势.因此可以这样理解上述三个面向的含义,即嵌入式系统是与 ...

最新文章

  1. activemq 开启监听_ActiveMQ 消息监听 MessageListener 的使用
  2. 九章算法班L8 Array Number
  3. HDFS命令行客户端使用,命令行客户端支持的命令参数,常用命令参数介绍
  4. 210221阶段三线程、信号量、互斥锁
  5. 10-30SQLserver基础--(备份和还原、分离和附加数据库)、语句查询操作
  6. 原创电子书:C#难点逐个击破
  7. 开头什么的肯定要自我介绍然后把它扔到置顶咯_~
  8. 观点|通过短生命周期和最小权限原则保护软件供应链安全
  9. slice 和splice 的区别 js
  10. 微信 for Mac 3.1.0 测试版发布,支持发朋友圈啦!
  11. SpringBoot 整合 JPA
  12. java 身份证地址提取籍贯_输入身份证号获取籍贯、出生日期、性别
  13. java时间轮定时器_算法 数据结构——时间轮定时器
  14. 计算机技术在材料物理专业的应用,东北大学材料物理专业要学哪些课程,好学吗?...
  15. PPT怎么用100张照片做照片墙?
  16. MuleSoft知识总结-9.使用Mule基本组件(Sub Flow,Set Payload,Logger,Flow Reference)
  17. Swift中隐藏某一页面的返回按钮
  18. 写在Doris毕业后的第一天
  19. yo搭建nodejs项目脚手架
  20. 计算机专业毕业实习心得

热门文章

  1. FRP分享 Padavan
  2. MATLAB图像分割的GUI设计
  3. openpyxl 获取worksheet颜色
  4. matlab 求解高次方程,Matlab求解多元高次方程组
  5. 警告: A docBase inside the host appBase has been specified, and will be ignore
  6. 极品婆媳龙争虎斗---终极PK王者之战(10)
  7. 微信关注公众号获取用户名的方法
  8. Excel怎么批量导入图片
  9. SQL Sever创库
  10. vmd安装包_VMD分子模拟软件下载