12.1 SDRAM 介绍

12.1.1 SDRAM 定义

  • SDRAM(Synchronous Dynamic Random Access Memory):同步动态随机存储器-内存条

    • 同步是指内存工作需要同步时钟,内部的命令的发送与数据的传输都以它为基准;
    • 动态是指存储阵列需要不断的刷新来保证数据不丢失;   对比:SRAM(静态的-触发器)
    • 随机是指数据不是线性依次存储,而是自由指定地址进行数据读写  对比:Flash(块)
  • DDR:DDR就是DDR SDRAM,是SDRAM的升级版。(DDR:double data rate,双倍速度的SDRAM)
  • SDRAM经历了几代:SDR DDR1 DDR2 DDR3 DDR4 - 速度越来越快(命名方式采取的读写速率)

12.1.2 SDRAM 工作原理

  • 先片选中SDRAM,再选择Bank,最后在数据读写时和表格的检索原理一样,先指定一个行(Row),再指定一个列 (Column),就可以准确地找到所需要的单元格,这就是内存芯片寻址的基本原理,参考SDRAM结构图(HY57V561620(L)T)

    • 4Mbit*4banks*16---->  32Mbyte ----> 2^5 * 2^20   需要25根地址线(地址线复用)
  • CPU发出片选信号nSCS0(与nGCS6是同一引脚)有效,选中SDRAM芯片
  • SDRAM有4个L-BANK,需要两个地址信号来选中其中一个,即BA0、BA1。
  • 对被选中的芯片进行同一的行/列(存储单元)寻址、
  • 找到存储单元后,被选中的芯片就要进行统一的数据传输。

12.2 存储地址空间

12.2.1 地址空间布局(Memory MAP)

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

  

12.2.2 存储地址与外设的关系

12.2.2.1 存储控制器特性

  • 支持小字节序、大字节序(通过软件选择);
  • 每个BANK的地址空间为128MB,总共1GB(8BANKs);
  • 可编程控制的总线宽度(8/16/32-bit),不过BANK0只能选择两种宽度(16/32-bit);
  • 总共8个BANK,BANK0~BANK5可以支持外接ROM、SRAM等,BANK6~BANK7除可以支持ROM、SRAM外,还支持SDRAM等;
  • BANK0~BANK6共7个BANK的起始地址是固定的;
  • BANK7的起始地址可编程选择;
  • BANK6、BANK7的地址空间大小是可编程控制的;
  • 每个BANK的访问周期均可编程控制;
  • 可以通过外部的“wait”信号延长总线的访问周期;
  • 在外接SDRAM时,支持自刷新(self-refresh)和省电模式(power down mode)

12.2.2.2 S3C2440 与存储器相关的引脚

  • S3C2440对外引出的27根地址线ADDR0~ADDR26的访问范围只有128MB(2^27)
  • CPU对外还引出了8根片选信号nGCS0~nGCS7,对应于BANK0~BANK7,当访问BANKx的地址空间时,nGCSx引脚输出低电平用来选中外接的设备。这样,每个nGCSx对应128MB地址空间,8个nGCSx信号总共就对应了1GB的地址空间。
  • 数据线有上32根,DATA0-DATA31。控制信号nOE,nWE,nWait,nGCS0-nGCS5  (数据手册-P49)
  • 开发板中NORFlash DM9000 SDRAM接在了BANK上(总线方式扩展外设)

12.2.3  硬件接线图分析

12.2.3.1 NOR Flash

JZ2440 选用的是 MX29LV160D T/B 的型号,它为 2M x 8bit 或 1M x 16bit 的大小,即为 2M/1M 空间大小。8/16 是位宽。

  • A0-A19:地址线    2^20 = 1M
  • D0-D15:数据线           16bit
  • BYTE:选择16/8bit模式,直接接高电平(选择了16bit模式)
    • 因为S3C2440 的BANK0 只支持(16bit/32bit )的位宽,而 NOR Flash 是接在 BANK0上的,所以只能拉高选择16 bit 模式
  • CE --  NGCS0 (BANK0)
  • OE WE RESET
  • VCC VSS
  • CPU_ADDR1 ---  NOR_ADDR0 (忽略了最低位)

12.2.3.2 SDRAM

  • BANK0~BANK5的连接方式都是相似的,BANK6连接SDRAM时复杂一点,CPU提供了一组用于SDRAM的信号CS --- BANK6,它的首地址为0x30000000
  • SDRAM时钟有效信号SCKE;SDRAM时钟信号SCLK0/SCLK1
  • 数据掩码信号DQM0/DQM1/DQM2/DQM3(每个DQM控制8bit,防止写字节数据覆盖前面位-32bit操作的)
  • SDRAM片选信号nSCS0(它与nGCS6是同一引脚的两个功能)
  • SDRAM行地址选通脉冲信号nSRAS
  • SDRAM列地址选通脉冲信号nSCAS
  • 写允许信号nWE(它不是专用于SDRAM的),在 JZ2440 中使用的是EM63A165TS ,两个 32M 的SDRAM
  • HY57V561620(L)T容量:4Banks x 4M x 16Bit   =  32Mbyte,早

    • CPU需要64Mbyte(26根地址线)0x03(0x00)
    • CPU_ADDR2---- SDRAM_ADDR0
  • SDRAM行地址线13根,列地址线9根(Row Address : RA0 ~ RA12, Column Address : CA0 ~ CA8),它们是复用的
  • S3C2440发送一个地址为0x30001000:
    • 当nSRAS有效时,ADDR2-ADDR14发出的是行地址信号,对应bit[23-11]
    • 当nSCAS有效果时,ADDR2-ADDR10发出的是列地址信号,对应bit[10-2]
  • 硬件接线图参考数据手册上给的值,当数据线是32位时,最低两位是没有使用的,一个地址对应的是四个字节为了和字节地址统一,不接bit[1-0]到SDRAM中。
  • 注意:
    • 逻辑上:

      • 采用按字节编址的方式,每一个地址对应一个字节单元(与存储单元字节数无关)-CPU端设置
    • 物理上:
      • 存储单元:每一个地址对应的存储空间,就是一个存储单元
      • 存储器总容量的字节数 = 总的地址数 X 存储单元字节数
      • 通过扩展地址线/数据线来扩展容量,比如我们内存模块是采用 16M*8bit的内存颗粒,那么我们使用4个颗粒进行字扩展(数据线),成为16M*32bit,使用4个颗粒进行容量扩展(地址线)变为64M*8bit

  

12.3 存储器控制器

12.3.1 时序图

  • 时序是表达指令执行中各控制信号在时间上的相互关系,由于有了时序才能让 IC 有条不紊的工作。
  • 时序图读法:
    • 从上到下,从左到右,高电平在上,低电平在下,高组态在中间。
    • 双线表示可能高也可能低,视数据而定。
    • 交叉线表示状态的高低变化点,可以是高变低,也可以是低变高,也可以不变。
  • 时序图的看法:
    • 按照从上到下,从左到右的顺序,每到一个突变点(从0变为1,或从1变为0)时,记录各信号的值,进而分析可知其相应的功能。

12.3.2 寄存器设置

  • 存储控制器共有13各寄存器,BANK0-BANK5 只需要设置 BWSCON 和 BANKCONx(x 为 0~5)两个寄存器;
  • BANK6、BANK7 外接 SDRAM 时,除 BWSCON 和 BANKCONx(x 为6、7)外,还需要设置 REFRESH、BANKSIZE、MRSRB6、MRSRB7 等 4 各寄存器:
    • BWSCON:

      • STx 用于设置启用 UB/LB(0)
      • WSx 是否使用存储器的 WAIT 信号(0)
      • DWx 用于设置 BANK 位宽
    • BANKCONx(x 为 0 - 5):用于控制外接设备的访问时序,使用默认的 0x700 即可满足要求
    • BANKCONx(x 为 6、7):
      • MT[16 - 15] 设置接的是 ROM/SRAM[00] 还是 SDRAM[11],如果是 00 的话,其他设备和 BANKCONx(x 为 0 - 5) 一样;当 MT 设置成 SDRAM 还需要设置 Trcd[3:2],RAStoCAS(delay 设置推荐为 01),Scan[1:0](SDRAM 列地址位数)

12.4 SDRAM 初始化

Makefile

 # 获取当前工作目录
CURRDIR = $(shell pwd) # 头文件所在目录
INCDIR = $(CURRDIR) # 交叉编译工具链的绝对路径
CROSS_COMPILE = ~/work/s3c2440/tools/gcc-3.4.-glibc-2.3./bin/arm-linux- # 编译器工具
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm
STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump # 编译器标识位设置
CFLAGS :=
AFLAGS :=
LDFLAGS :=
CFLAGS :=
AFLAGSL := # 目标文件设置
objs := startup.o sdram.o all: clean s3c2440.bin # 执行编译的过程
s3c2440.bin: $(objs)
$(LD) -Ttext 0x00000000 -o s3c2440_elf $^
$(OBJCOPY) -O binary -S s3c2440_elf $@
$(OBJDUMP) -D -m arm s3c2440_elf > s3c2440.dis %.o:%.c
$(CC) -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -ffreestanding -c -o $@ $< %.o:%.S
$(CC) -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -ffreestanding -c -o $@ $< clean:
rm -f *.bin *_elf *.dis *.o

startup.S

 .equ        MEM_CTL_BASE,       0x48000000
.equ SDRAM_BASE, 0x30000000 .text
.global _start
_start:
bl disable_watch_dog @ 关闭WATCHDOG,否则CPU会不断重启
bl memsetup @ 设置存储控制器
bl copy_steppingstone_to_sdram @ 复制代码到SDRAM中
ldr pc, =on_sdram @ 跳到SDRAM中继续执行 @ 栈是先入后出,SDRAM 的地址为 0x30000000,64M 大小的结束地址为 0x34000000
on_sdram:
ldr sp, =0x34000000 @ 设置堆栈, 此时 pc 指向了栈顶
bl main halt_loop:
b halt_loop @ WTCON 寄存器允许用户使能或禁止看门狗定时器、从 个不同源选择时钟信号、使能或禁止中断和使能或禁止看门狗定时器输出。
@ 看门狗定时器是用于恢复 S3C2440A 上电后若有故障重时新启动;如果不希望控制器重新启动,则应该禁止看门狗定时器。
@ 如果用户希望使用看门狗定时器作为普通定时器,则应使能中断并且禁止看门狗定时器。
@ STR{条件} 源寄存器,<存储器地址>
@ STR指令用于从源寄存器中将一个 位的字数据传送到存储器中。
disable_watch_dog:
@ 往 WATCHDOG 寄存器写 即可,操作 WTCON 寄存器
mov r1, #0x53000000
mov r2, #0x0
str r2, [r1]
mov pc, lr @ 返回 @ S3C2440A 引导代码可以在外部 NAND Flash 存储器上执行。
@ 为了支持 NAND Flash 的 BootLoader,S3C2440A 配备了一个内置的 SRAM 缓冲器,叫做“Steppingstone”。
@ 引导启动时,NAND Flash 存储器的开始 4K 字节将被加载到 Steppingstone 中并且执行加载到 Steppingstone 的引导代码。
copy_steppingstone_to_sdram:
@ 将Steppingstone 的 4K 数据全部复制到 SDRAM 中去
@ Steppingstone 起始地址为 0x00000000,SDRAM 中起始地址为 0x30000000 mov r1, #
ldr r2, =SDRAM_BASE
mov r3, #*
:
ldr r4, [r1],# @ 从Steppingstone读取4字节的数据,并让源地址加4
str r4, [r2],# @ 将此4字节的数据复制到SDRAM中,并让目地地址加4
cmp r1, r3 @ 判断是否完成:源地址等于Steppingstone的未地址?
bne 1b @ 若没有复制完,继续
mov pc, lr @ 返回 @ 存储控制器设置
memsetup:
@ 设置存储控制器以便使用SDRAM等外设 mov r1, #MEM_CTL_BASE @ 存储控制器的13个寄存器的开始地址
adrl r2, mem_cfg_val @ 这13个值的起始存储地址
add r3, r1, # @ * =
:
ldr r4, [r2], # @ 读取设置值,并让r2加4
str r4, [r1], # @ 将此值写入寄存器,并让r1加4
cmp r1, r3 @ 判断是否设置完所有13个寄存器
bne 1b @ 若没有写成,继续
mov pc, lr @ 返回 .align
mem_cfg_val:
@ 存储控制器13个寄存器的设置值
@ BWSCON 总线宽度和等待控制寄存器
@ ‭ 0000‬
.long 0x22011110 @ BWSCON
@ BANKCON0 Bank0 控制寄存器
@ ‭ 0000‬
@ 设置了访问周期为 各时钟
.long 0x00000700 @ BANKCON0
@ BANKCON1 Bank· 控制寄存器
.long 0x00000700 @ BANKCON1
@ BANKCON2 Bank2 控制寄存器
.long 0x00000700 @ BANKCON2
@ BANKCON3 Bank3 控制寄存器
.long 0x00000700 @ BANKCON3
@ BANKCON4 Bank4 控制寄存器
.long 0x00000700 @ BANKCON4
@ BANKCON5 Bank5 控制寄存器
.long 0x00000700 @ BANKCON5
@ BANKCON6 Bank6 控制寄存器
@ ‭ 0101‬
@ - bit 有效:
@ [:] :即 MT 设置为同步 DRAM 即 SDRAM
@ 存储器类型 = ROM 或 SRAM [MT=]( 位),下面的数据设置为0,只有[:]有效
@ [:]
@ [:]
@ [:]
@ [:]
@ [:]
@ 存储器类型 = SDRAM [MT=]( 位)时候:
@ [:] :Trcd RAS 到 CAS 的延迟,设置为 各时钟(根据 SDRAM 的芯片手册设置)
@ [:] :SCAN 列地址数,设置为 列,同样根据 SDRAM 手册设置
.long 0x00018005 @ BANKCON6
@ BANKCON7 Bank7 控制寄存器
.long 0x00018005 @ BANKCON7
@ REFRESH SDRAM 刷新控制寄存器 [: ] 有效
@ ‭ 0011‬
@ 具体看芯片手册
.long 0x008C07A3 @ REFRESH
.long 0x000000B1 @ BANKSIZE 可变 Bank 大小寄存器
@ 当代码在 SDRAM 中运行时一定不要改变 MRSR 寄存器
@ 睡眠模式中,SDRAM 必须使能 SDRAM 自刷新模式
.long 0x00000030 @ MRSRB6 模式寄存器组寄存器 Bank6
.long 0x00000030 @ MRSRB7

sdram.c

 /**
* 将0x56000050 强转为 unsigned long 型指针,并取这个地址的值
* volatile 关键字:防止编译器优化,在应用层上多线程变量,在嵌入式中外设寄存器
*/
#define GPFCON (*(volatile unsigned long *)0x56000050)
#define GPFDAT (*(volatile unsigned long *)0x56000054)
#define GPFUP (*(volatile unsigned long *)0x56000058) /** 设置 GPFCON 的 引脚为输出 */
#define GPF4_OUT ( << ( * ))
#define GPF5_OUT ( << ( * ))
#define GPF6_OUT ( << ( * )) static void delay_ms(unsigned long ms); int main(void)
{
/** 将LED1-3对应的GPF4//6三个引脚设为输出 */
GPFCON = GPF4_OUT | GPF5_OUT | GPF6_OUT; unsigned long i = ;
while(){
delay_ms();
GPFDAT = (~(i<<)); // 根据i的值,点亮LED1,2,4
if(++i == )
i = ;
}
} static void delay_ms(unsigned long ms)
{
unsigned int i; while(ms--) {
for(i = ; i < 1200; i++);
}
}

十二、S3C2440 裸机 — SDRAM的更多相关文章

  1. s3c2440裸机-时钟编程(二、配置时钟寄存器)

    s3c2440裸机编程-时钟编程(二.配置时钟寄存器) 1.2440时钟时序 下图是2440时钟配置时序: 1.上电后,nRESET复位信号拉低,此时cpu还无法取指令工作. 2.nRESET复位信号 ...

  2. 【转载】s3c2440裸机开发调试环境(MDK4.6,Jlink v8,mini2440)

    用于arm裸机程序开发的IDE基本有 以下3个:MDK,IAR,还有ADS.具体它们的具体情况在这里我就不多说了,百度一下就明白了.由于之前开发c51,stm32时候都使用了MDK开发环境,而且MDK ...

  3. 前端开发中SEO的十二条总结

    一. 合理使用title, description, keywords二. 合理使用h1 - h6, h1标签的权重很高, 注意使用频率三. 列表代码使用ul, 重要文字使用strong标签四. 图片 ...

  4. CRL快速开发框架系列教程十二(MongoDB支持)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  5. 我的MYSQL学习心得(十二) 触发器

    我的MYSQL学习心得(十二) 触发器 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数 ...

  6. Web 前端开发精华文章推荐(jQuery、HTML5、CSS3)【系列十二】

    2012年12月12日,[<Web 前端开发人员和设计师必读文章>系列十二]和大家见面了.梦想天空博客关注 前端开发 技术,分享各种增强网站用户体验的 jQuery 插件,展示前沿的 HT ...

  7. 第十二章Fundamental Data Types 基本数据类型

    目录: 12.1 数值概论 12.2整数 12.3浮点数 12.4 字符和字符串 12.5布尔变量 12.6枚举类型 12.7具名常量 12.8数组 12.9创建你自己的类型 12.1   数值概论 ...

  8. [分享] IT天空的二十二条军规

    Una 发表于 2014-9-19 20:25:06 https://www.itsk.com/thread-335975-1-1.html IT天空的二十二条军规 第一条.你不是什么都会,也不是什么 ...

  9. Bootstrap <基础三十二>模态框(Modal)插件

    模态框(Modal)是覆盖在父窗体上的子窗体.通常,目的是显示来自一个单独的源的内容,可以在不离开父窗体的情况下有一些互动.子窗体可提供信息.交互等. 如果您想要单独引用该插件的功能,那么您需要引用  ...

随机推荐

  1. 如何使用Loadrunner Controller 监控服务器的系统资源

    (1)保证装有loadrunner Controller的控制机和被监控的目标机(服务器)之间能够ping通,在同一个网段内,保证两台机器用administrator登陆. (2)Win + R, s ...

  2. flutter 添加全局环境变量

    flutter安装好了之后 要添加全局环境变量才可以在终端通过flutter命令来操作 安装flutter环境变量 vim ~/.bash_profile (不存在就创建,添加下面一行命令) expo ...

  3. 在 vue 中用 transition 实现轮播效果

    概述 今天我接到一个需求:轮播效果.本来我是打算使用 Swiper 实现的,但是想起来貌似 transition 也能实现.于是就试了下,真的可以,还挺简单的,于是就记录下来,供以后开发时参考,相信对 ...

  4. 阶段3 3.SpringMVC·_01.SpringMVC概述及入门案例_02.SpringMVC框架的介绍

    Spring MVC 的入口是 Servlet, 而 Struts2 是 Filter Spring MVC 是基于方法设计的,而Struts2是基于类,Struts2每次执行都会创建一个动作类.所以 ...

  5. 四十八:数据库之alembic常用命令和经典错误的解决办法

    常用命令:1.init:创建一个alembic仓库2.reversion:创建一个新的版本3.--autogenerate:自动将当前模型的修改,生成迁移脚本4.-m:message,可以记录本次迁移 ...

  6. Function程序设计及应用

    Function也称为函数,它是SAP中一个独物的程序模式,一般是一段单独的程序代码,可独立执行或直接被SAP其他程序所调用.Function支持远程访问模式,即提供接口供SAP程序使用(如VB,.N ...

  7. c++ 函数后面有个 const

    非静态成员函数后面加const,类似如下函数: class testClass{ public: void testClass() const{ /*...*/} private: /*...*/ } ...

  8. java:Hibernate框架3(使用Myeclipse逆向工程生成实体和配置信息,hql语句各种查询(使用hibernate执行原生SQL语句,占位符和命名参数,封装Vo查询多个属性,聚合函数,链接查询,命名查询),Criteria)

    1.使用Myeclipse逆向工程生成实体和配置信息: 步骤1:配置MyEclipse Database Explorer: 步骤2:为项目添加hibernate的依赖: 此处打开后,点击next进入 ...

  9. C++编译错误提示 [Error] name lookup of 'i' changed for ISO '

    在VC 6 中,i的作用域范围是函数作用域,在for循环外仍能使用变量i 即: for (int i = 0; i < n; ++i) {         //…… } cout<< ...

  10. Element el-table-column组件列宽度设置百分比无效

    问题 使用Element table组件时,给列设置百分比宽度无效(width="30%") 解决 用属性min-width="3"代替属性width=&quo ...