SDRAM(Synchronous Dynamic Random Access Memory,同步动态随机存储器)也便是一般所说的内存。内存的作业原理、操控时序、及相关操控器的装备办法一向是嵌入式体系学习、开发进程中的一个难点。咱们从其硬件的视点来剖析其原理,然后再引出SDRAM的驱动编写进程。
内存是代码的履行空间,以PC机为例,程序是以文件的方法保存在硬盘里边的,程序在运转之前先由操作体系装载入内存中,因为内存是RAM(随机拜访存储器),能够经过地址去定位一个字节的数据,CPU在履行程序时将PC的值设置为程序在内存中的开端地址,CPU会顺次的从内存里取址,译码,履行,在内存没有被初始化之前,内存好比是未建好的房子,是不能读取和存储数据的,因而咱们要想让MTOS运转在内存里有必要进行内存的初始化。
通用存储设备:
在介绍内存作业原理之前有必要了解下存储设备的存储方法:ROM,RAM
lROM(Read-Only Memory):只读存储器,是一种只能读出事前所存数据的固态半导体存储器。其特性是一旦贮存材料就无法再将之改动或删去。一般用在不需常常改变材料的电子或电脑体系中,材料并且不会因为电源封闭而消失。如:PC里边的BIOS。
lRAM(Random Access Memory):随机拜访存储器,存储单元的内容可按需随意取出或存入,且存取的速度与存储单元的方位无关的存储器。能够了解为,当你给定一个随机有用的拜访地址,RAM会回来其存储内容(随机寻址),它拜访速度与地址的无关。这种存储器在断电时将丢掉其存储内容,故首要用于存储短时刻内随机拜访运用的程序。计算机体系里内存地址是一个四字节对齐的地址(32位机),CPU的取指,履行,存储都是经过地址进行的,因而它能够用来做内存。
RAM依照硬件规划的不同,随机存储器又分为DRAM(Dynamic RAM)动态随机存储器和SRAM(Static RAM)静态随机存储器。
lDRAM:它的根本原件是小电容,电容能够在两个极板上短时刻内保存电荷,能够经过南北极之间有无电压差代表计算机里的0和1,因为电容的物理特性,要定时的为其充电,不然数据会丢掉。对电容的充电进程叫做改写,可是制造工艺较简略,体积小,便于集成化,常常做为计算机里内存制造原件。比方:PC的内存,SDRAM, DDR, DDR2, DDR3等,缺陷:因为要定时改写存储介质,存取速度较慢。
lSRAM:它是一种具有停止存取功用的内存,不需求改写电路即能保存它内部存储的数据。因而其存取速度快,可是体积较大,功耗大,本钱高,常用作存储容量不高,但存取速度快的场合,比方CPU的L1 cache,L2cache(一级,二级缓存),寄存器。
为了满意开发的需求MINI2440在出厂时搭载了三种存储介质:
(1)NOR FLASH(2M):ROM存储器,一般用来保存BootLoader,引导体系发动
(2)NAND FLASH(256M,类型不相同,Nandflash巨细不相同):保存操作体系映像文件和文件体系
(3)SDRAM(64M):内存,履行程序
lNORFLASH:它的特色是支撑XIP芯片内履行(eXecute In Place),这样运用程序能够直接在Flash闪存内运转,不必再把代码读到体系RAM中,也便是说能够随机寻址。NOR FLASH的本钱较高。
lNAND FLASH:它能供给极高的单元密度,能够抵达高存储密度,并且写入和擦除的速度也很快。其本钱较低,不支撑XIP。可做嵌入式里的数据存储介质。如:手机存储卡,SD卡等。
1.1.1S3C2440存储器地址段(Bank)
S3C2440对外引出了27根地址线ADDR0~ADDR26,它最多能够寻址128MB,而S3C2440的寻址空间能够抵达1GB,这是因为S3C2440将1GB的地址空间分红了8个BANKS(Bank0~Bank7),其间每一个BANK对应一根片选信号线nGCS0~nGCS7,当拜访BANKx的时分,nGCSx管脚电平拉低,用来选中外接设备,S3C2440经过8根选信号线和27根地址线,就能够拜访1GB。如图2-48所示。
图2-48 S3C2440存储器BANK
如图所示,左边图对应不运用Nandflash发动时(经过跳线设置),存储器Bank分布图,一般在这种发动方法里挑选Norflash发动,将Norflash焊接在Bank0,体系上电后,CPU从Bank0的开端地址0x00000000开端取指运转。
上图右侧是挑选从Nandflash引导发动(经过跳线设置),体系上电后,CPU会主动将Nandflash里前4K的数据复制到S3C2440内部一个4K巨细SRAM类型存储器里(叫做Steppingstone),然后从Steppingstone取指发动。
其间Bank0~Bank5能够焊接ROM或SRAM类型存储器,Bank6~Bank7能够焊接ROM,SRAM,SDRAM类型存储器,也便是说,S3C2440的SDRAM内存应该焊接在Bank6~Bank7上,最大支撑内存256M,Bank0~Bank5一般焊接一些用于引导体系发动小容量ROM,具体焊接什么样存储器,多大容量,依据每个开发板生产商不同而不同,比方MINI2440开发板将2M的Norflash焊接在了Bank0上,用于寄存体系引导程序Bootloader,将两片32M,16Bit位宽SDRAM内存焊接在Bank6和Bank7上,并联构成64M,32位内存。
因为S3C2440是32位芯片,理论上讲能够抵达4GB的寻址规模,除掉上述8个BANK用于衔接外部设备,还有一部分的地址空间是用于设备特别功用寄存器,其他地址没有被运用。
表2-14 S3C2440设备寄存器地址空间
外接设备 |
开端地址 |
完毕地址 |
存储操控器 |
0x48000000 |
0x48000030 |
USB Host操控器 |
0x49000000 |
0x49000058 |
中止操控器 |
0x4A000000 |
0x4A00001C |
DMA |
0x4B000000 |
0x4B0000E0 |
时钟和电源办理 |
0x4C000000 |
0x4C000014 |
LCD操控器 |
0x4D000000 |
0x4D000060 |
NAND FLASH操控器 |
0x4E000000 |
0x4E000014 |
摄像头接口 |
0x4F000000 |
0x4F0000A0 |
UART |
0x50000000 |
0x50008028 |
脉宽调制计时器 |
0x51000000 |
0x51000040 |
USB设备 |
0x52000140 |
0x5200026F |
WATCHDOG计时器 |
0x53000000 |
0x53000008 |
I%&&&&&%操控器 |
0x54000000 |
0x5400000C |
IIS操控器 |
0x55000000 |
0x55000012 |
I/O端口 |
0x56000000 |
0x560000B0 |
实时时钟RTC |
0x57000040 |
0x5700008B |
A/D转换器 |
0x58000000 |
0x58000010 |
SPI |
0x59000000 |
0x59000034 |
SD接口 |
0x5A000000 |
0x5A000040 |
AC97音频编码接口 |
0x5B000000 |
0x5B00001C |
1.1.2SDRAM内存作业原理
SDRAM的内部是一个存储阵列。阵列就好像表格相同,将数据“填”进去。在数据读写时和表格的检索原理相同,先指定一个行(Row),再指定一个列(Column),咱们就能够精确地找到所需求的单元格,这便是内存芯片寻址的根本原理,如图2-49所示。
图2-49内存行,列地址寻址示意图
这个单元格(存储阵列)就叫逻辑Bank(Logical Bank,下文简称L-Bank)。因为技能、本钱等原因,不可能只做一个全容量的L-Bank,并且最重要的是,因为SDRAM的作业原理约束,单一的L-Ban k将会形成十分严峻的寻址抵触,大幅下降内存功率。所以人们在SDRAM内部分割成多个L-Bank,现在根本都是4个(这也是SDRAM规范中的最高L-Bank数量),由此可见,在进行寻址时就要先确认是哪个L-Bank,然后在这个选定的L-Bank中挑选相应的行与列进行寻址。因而对内存的拜访,一次只能是一个L-Bank作业。如图2-50:
图2-50内存存储单元
当对内存进行操作时(见下图),先要确认操作L-Bank,因而要对L-Bank进行挑选。在内存芯片的外部管脚上多出了两个管脚BA0, BA1,用来片选4个L-Bank。如前所述,32位的地址长度因为其存储结构特色,分红了行地址和列地址。经过下面的内存结构图可知,内存外接管脚地址线只需13根地址线A0~A12,它最多只能寻址8M内存空间,究竟运用什么机制来完结对64M内存空间进行寻址的呢?SDRAM的行地址线和列地址线是分时复用的,即地址要分两次送出,先送出行地址(nSRAS行有用操作),再送出列地址(nSCAS列有用操作)。这样,能够大幅度削减地址线的数目,进步器材的功用和制造工艺复杂度。但寻址进程也会因而而变得复杂。实际上,现在的SDRAM一般都以L-Bank为根本寻址目标的。由L-Bank地址线BAn操控L-Bank间的挑选,行地址线和列地址线贯穿衔接一切的L-Bank,每个L-Bank的数据的宽度和整个存储器的宽度相同,这样,能够加速数据的存储速度。一起,BAn还能够使未被选中的L-Bank作业于低功耗的形式下,然后下降器材的功耗。
图2-51 HY57561620内部结构图
开发板内存操控器管脚接线(以MINI2440开发板为例):
(1)确认BA0、BA1的接线
表2-15 BA0、BA1接线
Bank Size:外接内存容量巨细(HY57561620是4Mbit*16bit*4Bank*2Chips/8=64MB)
Bus Width:总线宽度 (两片16位HY57561620,并联成32位)
Base Component:单个芯片容量(bit)(256Mb)
Memory Configration:内存装备((4M*16*4banks)*2Chips )
由硬件手册Bank Address管脚衔接装备表可知,运用A[25:24]两根地址线作为Bank片选信号,正好两根接线能够片选每个存储单元的4个BANKS。
(2)确认其它接线
SDRAM内存是焊接在BANK6~BANK7上的,其焊接管脚,如图2-52:
图2-52 S3C2440 16位宽内存芯片
上图是S3C2440供给的两片16位芯片并联衔接示意图,An是CPU地址总线,其间A2~A14为内存芯片寻址总线,之所以地址寻址总线从A2开端是因为内存地址都是按字节对齐的,,A24,A25为L-Bank片选信号,Dn为CPU数据总线,其它为对应操控信号线。
表2-16内存芯片各管脚阐明
外接管脚名 |
内接管脚名 |
全称 |
描绘 |
A2~A14 |
A0~A12 |
Address |
地址线 |
D0 ~D31 |
DQ0~DQ31 |
Data Input/Output |
数据线 |
A24,A25 |
BA0,BA1 |
Bank Address |
L-BANK片选信号 |
DQM0~DQM3 |
LDQM, UDQM |
Data Input/Output Mask |
高,低字节数据掩码信号 |
SCKE |
SCKE |
Clock Enable |
输入时钟有用信号 |
SCLK |
SCLK |
Clock |
输入时钟 |
nSCS0 |
nSCS |
General Chip Select |
片选信号(它与nGCS6是同一管脚的两个功用) |
nSRAS |
nSRAS |
Row Address Strobe |
行地址选通信号 |
nSCAS |
nSCAS |
Column Address Strobe |
列地址选通信号 |
nWE |
newnWE |
Write Enable |
写入有用信号 |
咱们经过S3C2440 16位宽内存芯片接线图能够看出,两片内存芯片只需两个当地不相同,LDQM, UDQM和数据总线DQn接线方法不相同。
因为存储芯片位宽为16位,一次能够进行两个字节的读取。可是,一般操作体系里最小寻址单位是1字节,因而内存操控器有必要要确保能够拜访内存里每一个字节。UDQM,LDQM别离代表16位数据的高,低字节读取信号,
当读取数据时,LDQM /UDQM别离用来操控16位数据中凹凸字节能否被读取,当LDQM /UDQM为低电平时,对应的高/低字节就能够被读取,假如LDQM /UDQM为高电平时,对应的高/低字节就不能被读取。
当向内存里写入数据时,LDQM /UDQM操控数据能否被写入,当LDQM /UDQM为低电平时,对应的高/低字节就能够被写入,假如LDQM /UDQM为高电平时,对应的高/低字节就不能被写入。经过对LDQM /UDQM信号的操控能够操控对两个存储芯片存储数据,因为两个存储单元的地址线是通用的,他们都能接收到CPU宣布的地址信号,可是,发给两个存储单元的LDQM /UDQM信号是不同的,以此来区别一个字的凹凸字节。
S3C2440A为32位CPU,也便是说其数据总线和地址总线宽度都是32位(能够了解为32根线一端衔接CPU内部,别的一端衔接向内存操控器),那么内存数据的输入/输出端也要确保是32位总线,MINI2440上选用两片16位宽总线内存芯片并联构成32位总线。其间一个芯片衔接到CPU数据总线的低16位,别的一个芯片衔接到数据总线上的高16位,并联成32位总线,因而两个芯片的输入/输出总线衔接到CPU总线上的不同管脚上。
1.1.3SDRAM的读操作
SDRAM进行读操作时,先向地址线上送上要读取数据的地址,经过前面的常识了解到,地址被分红3部分,行地址,列地址,L-Bank片选信号。片选(L-Bank的定址)操作和行有用操作能够一起进行。
在CS、L-Bank定址的一起,RAS(nSRAS行地址选通信号)也处于有用状况。此刻An地址线则发送具体的行地址。A0~A12,共有13根地址线(可表明8192行),A0~A12的不同数值就确认了具体的行地址。因为行有用的一起也是相应L-Bank有用,所以行有用也可称为L-Bank有用。
行地址确认之后,就要对列地址进行寻址了。可是,地址线仍然是行地址所用的A0~A12。没错,在SDRAM中,行地址与列地址线是复用的。列地址复用了A0~A8,共9根(可表明512列)。那么,读/写的指令是怎样宣布的呢?其实没有一个信号是发送读或写的清晰指令的,而是经过芯片的可写状况的操控来抵达读/写的意图。明显WE信号(nWE)便是一个要害。WE无效时,当然便是读取指令。有用时,便是写指令。
SDRAM根本操作指令,经过各种操控/地址信号的组合来完结(H代表高电平,L代表低电平,X表明高,低电平均没有影响)。此表中,除了自改写指令外,一切指令都是默许CKE(SCKEl输入时钟频率有用)有用。列寻址信号与读写指令是一起宣布的。尽管地址线与行寻址共用,但CAS(nSCAS列地址选通信号)信号则能够区别开行与列寻址的不同,合作A0~A8,A9~A11来确认具体的列地址。
读取指令与列地址一块宣布(当WE为低电平是即为写指令)可是,在发送列读写指令时有必要要与行有用指令有一个距离,这个距离被界说为tRCD,即RAS to CAS Delay(RAS至CAS推迟),这个很好了解,在地址线上送完行地址之后,要比及行地址安稳定位后再送出列地址,tRCD是SDRAM的一个重要时序参数,相关数值参看对应芯片硬件手册。一般tRCD以时钟周期(tCK,Clock Time)数为单位,比方笔者MINI2440所用内存芯片里边写到tRCD为20nst,假如将来内存作业在100MHz,那么RCD至少要为2个时钟周期,RCD=2。
图2-53SDRAM读操作时序图
在选定列地址后,就现已确认了具体的存储单元,剩余便是等候数据经过数据I/O通道(DQ)输出到内存数据总线上了。可是在列地址选通信号CAS宣布之后,仍要经过必定的时刻才干有数据输出,从CAS与读取指令宣布到第一笔数据输出的这段时刻,被界说为CL(CAS Latency,CAS埋伏期)。因为CL只在读取时呈现,所以CL又被称为读取埋伏期(RL,Read Latency)。CL的单位与tRCD相同,也是时钟周期数,具体耗时由时钟频率决议(笔者官方手册CL=3)。不过,CAS并不是在经过CL周期之后才送达存储单元。实际上CAS与RAS相同是瞬间抵达的。因为芯片体积的原因,存储单元中的电容容量很小,所以信号要经过扩大来确保其有用的识别性,这个扩大/驱动作业由S-AMP担任。但它要有一个准备时刻才干确保信号的发送强度,这段时刻咱们称之为tAC(Access Time from CLK,时钟触发后的拜访时刻)。
1.1.4SDRAM预充电操作
从存储体的结构图上能够看出,本来逻辑状况为1的电容在读取操作后,会因放电而变为逻辑0。因为SDRAM的寻址具有独占性,所以在进行完读写操作后,假如要对同一L-Bank的另一行进行寻址,就要将原先操作行封闭,从头发送别/列地址。在对原先操作行进行封闭时,DRAM为了在封闭当时行时坚持数据,要对存储体华夏有的信息进行重写,这个充电重写和封闭操作行进程叫做预充电,发送预充电信号时,意味着先履行存储体充电,然后封闭当时L-Bank操作行。预充电中重写的操作与改写操作(后边具体介绍)相同,只不过预充电不是定时的,而仅仅在读操作今后履行的。
1.1.5SDRAM突发操作
突发(Burst)是指在同一行中相邻的存储单元接连进行数据传输的方法,接连传输所涉及到存储单元(列)数量便是突发长度(Burst Length,简称BL)。
在现在,因为内存操控器一次读/写P-Bank位宽的数据,也便是8个字节,可是在实际中小于8个字节的数据很少见,所以一般都要经过多个周期进行数据的传输,上文写到的读/写操作,都是一次对一个存储单元进行寻址,假如要接连读/写,还要对当时存储单元的下一单元进行寻址,也便是要不断的发送列地址与读/写指令(行地址不变,所以不必再对地寻址)。尽管因为读/写推迟相同能够让数据传输在I/O端是接连的,可是它占用了很多的内存操控资源,在数据进行接连传输时无法输入新的指令功率很低。为此,引进了突发传输机制,只需指定开端列地址与突发长度,内存就会顺次主动对后边相应长度数据的数据存储单元进行读/写操作而不再需求操控器接连地供给列地址,这样,除了第一笔数据的传输需求若干个周期(首要是之间的推迟,一般的是tRCD + CL)外,这以后每个数据只需一个周期即可。
总结下:
SDRAM的根本读操作需求操控线和地址线相合作地宣布一系列指令来完结。先宣布芯片有用指令(ACTIVE),并确定相应的L-BANK地址(BA0、BA1给出)和行地址(A0~A12给出)。芯片激活指令后有必要等候大于tRCD(SDRAM的RAS到CAS的推迟目标)时刻后,宣布读指令。CL(CAS推迟值)个时钟周期后,读出数据顺次呈现在数据总线上。在读操作的最终,要向SDRAM宣布预充电(PRECHARGE)指令,以封闭现已激活的L-BANK。等候tRP时刻(PRECHAREG指令后,相隔tRP时刻,才可再次拜访该行)后,能够开端下一次的读、写操作。SDRAM的读操作支撑突发形式(Burst Mode),突发长度为1、2、4、8可选。
1.1.6SDRAM写操作
SDRAM的根本写操作也需求操控线和地址线相合作地宣布一系列指令来完结。先宣布芯片有用指令,并确定相应的L-BANK地址(BA0、BA1给出)和行地址(A0~A12给出)。芯片有用指令宣布后有必要等候大于tRCD的时刻后,宣布写指令数据,待写入数据顺次送到DQ(数据线)上。在最终一个数据写入后,推迟tWR时刻。宣布预充电指令,封闭现已激活的页。等候tRP时刻后,能够打开下一次操作。写操作能够有突发写和非突发写两种。突发长度同读操作。
图2-54 SDRAM写操作时序图
1.1.7SDRAM的改写
SDRAM之所以成为DRAM便是因为它要不断进行改写(Refresh)才干保存住数据,因而它是SDRAM最重要的操作。
改写操作与预充电中重写的操作相同,都是用S-AMP先读再写。但为什么有预充电操作还要进行改写呢?因为预充电是对一个或一切L-Bank中的作业行操作,并且是不定时的,而改写则是有固定的周期,顺次对一切行进行操作,以保存那些很长时刻没阅历重写的存储体中的数据。但与一切L-Bank预充电不同的是,这儿的行是指一切L-Bank中地址相同的行,而预充电中各L-Bank中的作业行地址并不是必定是相同的。那么要隔多长时刻重复一次改写呢?现在公认的规范是,存储体中电容的数据有用保存期上限是64ms(毫秒,1/1000秒),也便是说每一行改写的循环周期是64ms。这样改写时刻距离便是:64m/行数s。咱们在看内存规范时,常常会看到4096 Refresh Cycles/64ms或8192 Refresh Cycles/64ms的标识,这儿的4096与8192就代表这个芯片中每个L-Bank的行数。改写指令一次对一行有用,改写距离也是随总行数而改变,4096行时为15.625μs(微秒,1/1000毫秒),8192行时就为7.8125μs。改写操作分为两种:Auto Refresh,简称AR与Self Refresh,简称SR。不论是何种改写方法,都不需求外部供给行地址信息,因为这是一个内部的主动操作。关于AR,SDRAM内部有一个行地址生成器(也称改写计数器)用来主动的顺次生成行地址。因为改写是针对一行中的一切存储体进行,所以无需列寻址,或者说CAS在RAS之前有用。所以,AR又称CBR(CAS Before RAS,列提早于行定位)式改写。因为改写涉及到一切L-Bank,因而在改写进程中,一切L-Bank都停止作业,而每次改写所占用的时刻为9个时钟周期(PC133规范),之后就可进入正常的作业状况,也便是说在这9个时钟期间内,一切作业指令只能等候而无法履行。64ms之后则再次对同一行进行改写,如此循环往复进行循环改写。明显,改写操作必定会对SDRAM的功用形成影响,但这是没办法的作业,也是DRAM相关于SRAM(静态内存,无需改写仍能保存数据)获得本钱优势的一起所支付的价值。SR则首要用于休眠形式低功耗状况下的数据保存,这方面最著名的运用便是STR(Suspend to RAM,休眠挂起于内存)。在宣布AR指令时,将CKE置于无效状况,就进入了SR形式,此刻不再依托体系时钟作业,而是依据内部的时钟进行改写操作。在SR期间除了CKE之外的一切外部信号都是无效的(无需外部供给改写指令),只需从头使CKE有用才干退出自改写形式并进入正常操作状况。
SDRAM相关寄存器:
(1)BWSCON寄存器(BUS WIDTH & WAIT CONTROL REGISTER)
表2-17 SDRAM操控寄存器(BWSCON)
依据开发板的存储器装备和芯片类型,设置每个BANK焊接芯片的位宽和等候状况
BWSCON,每4位对应一个BANK,这4位别离表明:
lSTx:发动/制止SDRAM的数据掩码引脚(UB/LB),SDRAM没有凹凸位掩码引脚,此位为0,SRAM衔接有UB/LB管脚,设置为1
注:UB/LB数据掩码引脚用来操控芯片读取/写入的高字节和低字节(比照硬件手册SDRAM和SRAM的接线图)
lWSx:是否运用存储器的WAIT信号,一般设为0
lDWx:设置焊接存储器芯片的位宽,笔者开发板运用两片容量为32M,位宽为16的SDRAM组成64M,32位存储器,因而DW7,DW6位设置为0b10,其它BANK不必设置选用默许值即可。
lBANK0对应的是体系引导BANK,这4位比较特别,它的设置是由硬件跳线决议的,因而不必设置
lBWSCON设置成果:0x22000000
(2)BANKCON0~BANKCON5 (BANK CONTROL REGISTER)
表2-18 BANKCON0~BANKCON5操控寄存器(BANKCON0~BANKCON5)
这6个寄存器用来设置对应BANK0~BANK5的拜访时序,选用默许值0x700即可
(3)BANKCON6~BANKCON7 (BANK CONTROL REGISTER)
表2-19 BANKCON6~BANKCON7操控寄存器(BANKCON6~BANKCON7)
因为内存都焊接在这两个BANK上,因而内存驱动首要是对这两个寄存器进行设置
lMT:设置BANK6~BANK7的存储器类型,
00=ROM or SRAM 01=保存
10=保存11=SDRAM
内存为SDRAM,设置为0b11,对应的应该设置Trcd和SCAN位,其它位和SDRAM无关
lTrcd:RAS to CAS Delay行地址选通到列地址选通推迟,这个参数请看后边的内存作业原理扩展部分解说,笔者内存芯片为HY57V561620,由其芯片手册可知其Trcd为最少20ns,假如内存作业在100MHz,则该值至少要为2个时钟周期,一般设置为3个时钟周期,因而设置为0b01
lSCAN:SDRAM Column Address Number SDRAM的列地址数,笔者内存芯片为HY57V561620,列地址数为9,设置为0b01
lBANK6,BANK7设置成果为:0x18005
(4)REFRESH (REFRESH CONTROL REGISTER)
表2-20改写频率设置寄存器(REFRESH)
SDRAM的改写有用,改写频率设置寄存器(改写)
lREFEN:敞开/封闭改写功用,设置为1,敞开改写
lTREFMD:SDRAM改写形式,0=CBR/AutoRefresh,1=Self Refresh,设置为0,主动改写
lTrp:行地址选通预充电时刻,一般设置为0b00即可
lTsrc:单行改写时刻,设置为0b11即可。
lRefresh 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(取大整数)
lREFRESH寄存器设置为:
0x8e0000 + 1269 = 0x008e04f5(HCLK = 100MHz)
0x8e0000 + 1955 = 0x008e07a3(HCLK = 12MHz)
(5)BANKSIZE寄存器(BANKSIZE REGISTER)
表2-21 BANKSIZE寄存器(BANKSIZE)
设置内存的突发传输形式,省电形式和内存容量。
lBURST_EN:是否敞开突发形式,0 = ARM内核制止突发传输1 =敞开突发传输,设置为1,敞开突发传输
lSCKE_EN:是否运用SCKE信号作为省电形式操控信号,0 =不运用SCKE信号作为省电形式操控信号1 =运用SCKE信号作为省电形式操控信号,一般设置为1
lSCLK_EN: 设置向存储器输入作业频率,0 =一向输入SCLK频率,即便没有内存操作也会输入,1 =仅当进行内存数据操作时才输入SCLK频率,一般设置为1
lBK76MAP:设置Bank6/7的内存容量,笔者运用开发板内存为两片32M内存芯片并联成64M,它们悉数都外接到Bank6上,因而挑选0b001
lBANKSIZE寄存器设置为:0xb1
(6)SDRAM形式设置寄存器MRSRx (SDRAM MODE REGISTER SET REGISTER)
表2-22 SDRAM形式设置寄存器(MRSRx)
该寄存器用于设置CAS埋伏周期,能够手动设置的位只需CL[6:4]位,经过前面内存作业原理可知,笔者运用开发板CL=3,即0b011
lMRSR6,MRSR7设置为:0x00000030
1.1.8内存驱动试验
设置该工程加载时运转时地址为0x30000000,如图2-55所示:
图2-55设置加载时运转时地址
init.s:本程序文件首要完结了,封闭看门狗,初始化内存,复制ROM数据到内存中,然后跳往内存中履行xmain函数,从xmain函数回来之后,将悉数led点亮,进入死循环。
;
;内存初始化试验
;
AREA Init, CODE, READONLY
ENTRY
start
; close watchdog
ldr r0, = 0x53000000;将看门狗操控寄存器地址放入r0
mov r1, #0
str r1, [r0];设置看门狗操控寄存器的值为0
bl initmem;跳转到initmem代码段,初始化内存
bl copyall;跳转到数据复制代码段,将ROM中数据复制到内存中
IMPORT xmain;引进main.c中的xmain函数
ldr sp, =0x34000000;调用C程序之前先初始化栈指针
ldr lr, =endxmain;设置xmain函数的回来地址
ldr pc, =xmain;跳转到C程序中的xmain函数的入口处履行
endxmain
ldr r0, =0x56000010; LED的GPIO接口装备寄存器
ldr r1, =0x00015400; GPIO装备数据
str r1, [r0];设置GPIO
ldr r0, =0x56000014; LED操控寄存器地址
ldr r1, =0x0;悉数LED亮
str r1,[r0]
loop
b loop;死循环
copyall
IMPORT |Image$$RO$$Base|;引进编译器Image$$RO$$Base符号变量
IMPORT |Image$$RW$$Limit|;引进编译器Image$$RW$$Limit符号变量
ldr r0, = |Image$$RO$Base|;获得Image$$RO$Base域基址的值
ldr r1, = |Image$$RW$$Limit|;获得Image$$RW$Base域完毕地址的值
ldr r2, =0x0;数据复制源地址
copyallloop
teq r0,r1;测验是否复制完结
beq quitcopyallloop;复制完结,跳往quitcopyallloop退出
ldr r3, [r2], #4;四字节加载
str r3, [r0], #4;四字节存储
b copyallloop;回来持续履行
quitcopyallloop
mov pc, lr;调用回来
initmem;内存初始化
ldr r0, =0x48000000;加载内存相关寄存器首地址r0
ldr r1, =0x48000034;加载内存相关寄存器尾地址到r1
adr r2, memdata;将寄存器装备数据地址段首地址加载到r2
initmemloop
ldr r3, [r2], #4;循环设置存寄存器
str r3, [r0], #4
teq r0, r1
bne initmemloop;循环到最终一个寄存器时退出函数
mov pc,lr
memdata
DCD0x22000000;BWSCON
DCD0x00000700;BANKCON0
DCD0x00000700;BANKCON1
DCD0x00000700;BANKCON2
DCD0x00000700;BANKCON3
DCD0x00000700;BANKCON4
DCD0x00000700;BANKCON5
DCD0x00018005;BANKCON6
DCD0x00018005;BANKCON7
DCD0x008e07a3;REFRESH
DCD0x000000b1;BANKSIZE
DCD0x00000030;MRSRB6
DCD0x00000030;MRSRB7
END
main.c:本程序文件首要完结led灯的初始化,然后四个led灯循环翻滚亮5遍,xmain函数回来。
/* C言语函数*/
/*端口F寄存器预界说*/
#defineGPBCON(*(volatile unsigned long *)0x56000010)
#defineGPBDAT(*(volatile unsigned long *)0x56000014)
#defineLEDS(1<<5|1<<6|1<<7|1<<8)
#defineDELAYVAL(0x1ffff)
extern int delay(int time);/*声明外部声明汇编函数*/
int i = 5;
int xmain()
{
GPBCON= 0x00015400;//GPF4–GPF7设置为output
while(i > 0) {
//第一个LED灯亮
GPBDAT=(GPBDAT&(~LEDS)) | (1<<6|1<<7|1<<8);
delay(DELAYVAL);//调用汇编言语编写的延时程序
//第二个LED灯亮
GPBDAT=(GPBDAT&(~LEDS)) | (1<<5|1<<7|1<<8);
delay(DELAYVAL);//调用汇编言语编写的延时程序
//第三个LED灯亮
GPBDAT=(GPBDAT&(~LEDS)) | (1<<5|1<<6|1<<8);
delay(DELAYVAL);//调用汇编言语编写的延时程序
//第四个LED灯亮
GPBDAT=(GPBDAT&(~LEDS)) | (1<<5|1<<6|1<<7);
delay(DELAYVAL);//调用汇编言语编写的延时程序
i–;
}
return 0;
}
delay.s:本程序文件首要一般汇编来完结延时功用。
;汇编指令延时程序
EXPORT delay
AREADELAY,CODE,READONLY;该伪指令界说了一个代码段,段名为Init,特点只读
;下面是推迟子程序
delay
sub r0,r0,#1;r0=r0-1
cmp r0,#0x0;将r0的值与0相比较
bne delay;比较的成果不为0(r0不为0),持续调用delay,不然履行下一条句子
mov pc,lr;回来
END;程序完毕符
内存的初始化也能够用下面的C程序完结:
C言语版别:
#defineMEM_CTL_BASE0x48000000
#defineMEM_CTL_END0x48000034
/* SDRAM 13个寄存器的值*/
unsigned longconstmem_cfg_val[]={//声明数组寄存内存操控器设置数据
0x22000000,//BWSCON
0x00000700,//BANKCON0
0x00000700,//BANKCON1
0x00000700,//BANKCON2
0x00000700,//BANKCON3
0x00000700,//BANKCON4
0x00000700,//BANKCON5
0x00018005,//BANKCON6
0x00018005,//BANKCON7
0x008e07a3,//REFRESH(HCLK = 12MHz,该值为0x008e07a3
//HCLK = 100MHz 0x008e04f5)
0x000000b1,//BANKSIZE
0x00000030,//MRSRB6
0x00000030,//MRSRB7
};
void mem_init(void)
{
inti = 0;
unsigned long *p = (unsigned long *)MEM_CTL_BASE;
for(; i < (MEM_CTL_END - MEM_CTL_BASE)/4; i++)
p[i] = mem_cfg_val[i];
}