2 Star 3 Fork 1

稀风/LVGL

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
SDRAM简介.md 14.76 KB
一键复制 编辑 原始数据 按行查看 历史
稀风 提交于 2024-03-02 21:23 . 新增:FMC配置

使用SDRAM原因

  • 一般的 MCU 接口屏,比如 SPI 屏,8080 接口屏等是可以不需要外置显存的。这些屏幕可以通过发送命令当方式告诉屏幕坐标,然后再发送对应的像素数据
  • 但是 RGB 接口屏没命令可以发,一般是告诉 LTDC 一个内存地址,由 LTDC 控制器去内存拿像素值不断去扫描刷新屏幕的
  • 我们的屏幕是 1024*600 的,颜色格式 RGB565 ,所以需要 1024*600*2 = 1,228,800 字节 = 1200K 字节内存作为屏幕显存。MCU 芯片本身自带的 RAM 大小不够,所以要用到外部 SDRAM 或者 SRAM。我们这里用到的是 W9825G6KH 这颗 SDRAM,容量 32MByte

SDRAM简介

  • SDRAM,英文名是:Synchronous Dynamic Random Access Memory,即同步动态随机存储器,相较于 SRAM(静态存储器),SDRAM 具有:容量大和价格便宜的特点。 STM32H743 支持 SDRAM,因此,我们可以外挂 SDRAM,从而大大降低外扩内存的成本。

  • 当前开发板使用的 SDRAM 型号是 W9825G6KH,其内部结构框图如下图所示:

  • 接下来,我们结合上面的图,对 SDRAM 的几个重要知识点进行介绍。

SDRAM信号线

  • SDRAM 信号线如下表所示:
    信号线 说明
    CLK 时钟信号,在该时钟的上升沿采集输入信号
    CKE 时钟使能,禁止时钟时,SDRAM 会进入自刷新模式
    CS# 片选信号,低电平有效
    RAS# 行地址选通信号,低电平时,表示行地址
    CAS# 列地址选通信号,低电平时,表示列地址
    WE# 写使能信号,低电平有效
    A0~A12 地址线(行/列)
    BA0,BA1 BANK 地址线
    DQ0~15 数据线
    DQML,DQMH 数据掩码,表示 DQ 的有效部分

存储单元

  • SDRAM 的存储单元(称之为:BANK)是以阵列的形式排列的,如下图所示:

  • 对于这个存储阵列,我们可以将其看成是一个表格,只需要给定行地址和列地址,就可以确定其唯一位置,这就是 SDRAM 寻址的基本原理。而一个 SDRAM 芯片内部,一般又有 4 个这样的存储单元(BANK),所以,在 SDRAM 内部寻址的时候,先指定 BANK 号和行地址,然后再指定列地址,就可以查找到目标地址。

  • SDRAM 的存储结构示意图,如下所示:

  • 寻址的时候,首先 RAS 信号为低电平,选通行地址,地址线 A0~A12 所表示的地址,会被传输并锁存到行地址译码器里面,最为行地址,同时 BANK 地址线上面的 BS0,BS1 所表示的 BANK 地址,也会被锁存,选中对应的 BANK,然后, CAS 信号为低电平,选通列地址,地址线A0~A12 所表示的地址,会被传输并锁存到列地址译码器里面,作为列地址,这样,就完成了一次寻址。

  • W9825G6KH 的存储结构为:行地址:8192 个;列地址:512 个; BANK 数: 4 个;位 宽:16 位;这样,整个芯片的容量为: 8192*512*4*16=32M 字节。

数据传输

  • 在完成寻址以后,数据会通过数据线 DQ0~DQ15 写入(或读出)到存储阵列。
  • 特别注意:因为 SDRAM 的位宽,可以达到 32 位,也就是最多有 32 条数据线,在实际使用的时候,我们可能会以:8 位、16 位、24 位和 32 位等宽度来读写数据,这样的话,并不是每条数据线,都会被使用到,未被用到的数据线上面的数据,必须被忽略,这个时候就需要用到数据掩码( DQM)线来控制了,每一个数据掩码线,对应 8 个位的数据,低电平表示对应数据位有效,高电平表示对应数据位无效。
  • 以 W9825G6KH 为例,假设以 8 位数据访问, 我们只需要 DQ0~DQ7 的数据,而 DQ8~DQ15 的数据需要忽略,此时,我们只需要设置 LDQM 为低电平, UDQM 为高电平,就可以了。

控制命令

  • SDRAM 的驱动需要用到一些命令,我们列出几个常用的命令给大家做讲解,如下表所示:
    命令 CS RAS CAS WE DQM ADDR DQ
    NO-Operation L H H H x x x
    Active L L H H x Bank/Row x
    Read L H L H L/H Bank/Col DATA
    Write L H L L L/H Bank/Col DATA
    Precharge L L H L x A10=H/L x
    Refresh L L L H x x x
    Mode Register Set L L L L x MODE x
    Burst Stop L H H L x x DATA

NO-Operation

  • NO-Operation,即空操作命令,用于选中 SDRAM,防止 SDRAM 接受错误的命令,为接下来的命令发送做准备。

Active

  • Active,即激活命令,该命令必须在读写操作之前被发送,用于设置所需要的 Bank 和行地址(同时设置这 2 个地址),Bank 地址由 BS0,BS1(也写作 BA0,BA1,下同)指定,行地址由 A0~A12 指定,时序图如下所示:

Read/Write

  • Read/Write,即读/写命令,在发送完激活命令后,再发送列地址就可以完成对 SDRAM 的寻址,并进行读写操作了,读/写命令和列地址的发送,是通过一次传输完成的,如下图所示:

  • 列地址由 A0~A9 指定,WE 信号控制读/写命令,高电平表示读命令,低电平表示写命令,各条信号线的状态,在 CLK 的上升沿被锁存到芯片内部。

Percharge

  • Percharge,即预充电指令,用于关闭 Bank 中所打开的行地址。由于 SDRAM 的寻址具有独占性,所以在进行完读写操作后,如果要对同一 Bank 的另一行进行寻址,就要将原来有效(打开)的行关闭,重新发送行/列地址。Bank 关闭现有行,准备打开新行的操作就叫做预充电(Percharge)。预充电命令时序,如下图所示:

  • 预充电命令可以通过独立的命令发送,也可以在每次发送读/写命令的时候,使用地址线 A10,来设置自动预充电。在发送读/写命令的时候,当 A10=1,则使能所有 Bank 的预充电,在读/写操作完成后,自动进行预充电。这样,下次读/写操作之前,就不需要再发预充电命令了,从而提高读/写速度。

Refresh

  • Refresh,即刷新命令,用于刷新一行数据。SDRAM 里面存储的数据,需要不断的进行刷新操作才能保留住,因此刷新命令对于 SDRAM 来说,尤为重要。预充电命令和刷新命令,都可以实现对 SDRAM 数据的刷新,不过预充电仅对当前打开的行有效(仅刷新当前行),而刷新命令,则可以依次对所有的行进行刷新操作。
  • 总共有两种刷新操作:自动刷新(Auto Refresh)和自我刷新(Self Refresh),在发送 Refresh 命令时,如果 CKE 有效(高电平),则使用自动刷新模式,否则使用自我刷新模式。不论是何种刷新方式,都不需要外部提供行地址信息,因为这是一个内部的自动操作。
  • 自动刷新: SDRAM 内部有一个行地址生成器(也称刷新计数器)用来自动的依次生成要刷新的行地址。由于刷新是针对一行中的所有存储体进行,所以无需列寻址。刷新涉及到所有 Bank,因此在刷新过程中,所有 Bank 都停止工作,而每次刷新所占用的时间为 9 个时钟周期(PC133 标准),之后就可进入正常的工作状态,也就是说在这 9 个时钟期间内,所有工作指令只能等待而无法执行。刷新操作必须不停的执行,完成一次所有行的刷新所需要的时间,称为刷新周期,一般为 64ms。显然,刷新操作肯定会对 SDRAM 的性能造成影响,但这是没办法的事情,也是 DRAM 相对于 SRAM(静态内存,无需刷新仍能保留数据)取得成本优势的同时所付出的代价。
  • 自我刷新:主要用于休眠模式低功耗状态下的数据保存,在发出自动刷新命令时,将 CKE 置于无效状态(低电平),就进入了自我刷新模式,此时不再依靠系统时钟工作,而是根据内部的时钟进行刷新操作。在自我刷新期间除了 CKE 之外的所有外部信号都是无效的(无需外部提供刷新指令),只有重新使 CKE 有效(高电平)才能退出自刷新模式并进入正常操作状态。

Mode Register Set

  • Mode Register Set,即设置模式寄存器。 SDRAM 芯片内部有一个逻辑控制单元,控制单元的相关参数由模式寄存器提供,我们通过设置模式寄存器命令,来完成对模式寄存器的设置,这个命令在每次对 SDRAM 进行初始化的时候,都需要用到。

  • 发送该命令时,通过地址线来传输模式寄存器的值,W9825G6KH 的模式寄存器描述如下图所示:

  • 由图可知,模式寄存器的配置分为几个部分:

    1. Burst Length,即突发长度(简称 BL),通过 A0~A2 设置,是指在同一行中相邻的存储单元连续进行数据传输的方式,连续传输所涉及到存储单元(列)的数量就是突发长度。
    • 前面我们说的读/写操作,都是一次对一个存储单元进行寻址,如果要连续读/写就还要对当前存储单元的下一个单元进行寻址,也就是要不断的发送列地址与读/写命令(行地址不变,所以不用再对行寻址)。虽然由于读/写延迟相同可以让数据的传输在 I/O 端是连续的,但它占用了大量的内存控制资源,在数据进行连续传输时无法输入新的命令,效率很低。
    • 为此,人们开发了突发传输技术,只要指定起始列地址与突发长度,内存就会依次地自动对后面相应数量的存储单元进行读/写操作而不再需要控制器连续地提供列地址。 这样,除了第一个数据的传输需要若干个周期外,其后每个数据只需一个周期的即可获得。
    • 非突发连续读取模式:不采用突发传输而是依次单独寻址,此时可等效于 BL=1。虽然可以让数据是连续的传输,但每次都要发送列地址与命令信息,控制资源占用极大。突发连续读取模式:只要指定起始列地址与突发长度,寻址与数据的读取自动进行,而只要控制好两段突发读取命令的间隔周期(与 BL 相同)即可做到连续的突发传输。 至于 BL 的数值,也是不能随便设或在数据进行传输前临时决定,而是在初始化的时候,通过模式寄存器设置命令,进行设置。目前可用的选项是 1、 2、 4、 8、全页(Full Page),常见的设定是 4 和 8。若传输长度小于突发长度,则需要发送 Burst Stop(停止突发)命令,结束突发传输。
    1. Addressing Mode,即突发访问的地址模式,通过 A3 设置,可以设置为:Sequential(顺序)或 Interleave(交错)。顺序方式,地址连续访问,而交错模式则地址是乱序的,一般选连续模式。
    2. CAS Latency,即列地址选通延迟(简称 CL)。在读命令(同时发送列地址)发送完之后,需要等待几个时钟周期, DQ 数据线上的数据,才会有效,这个延迟时间,就叫 CL,一般设置为 2/3 个时钟周期,如下图所示:

    • 特别注意:列地址选通延迟(CL),仅在读命令的时候有效果,在写命令的时候,并不需要这个延迟。
    1. Write Mode,即写模式,用于设置单次写的模式,可以选择突发写入或者单次写入。

初始化

  • SDRAM 上电后,必须进行初始化,才可以正常使用。SDRAM 初始化时序图如下图所示:

  • 初始化过程分为五步:

  • ① 上电,此步,给 SDRAM 供电,使能 CLK 时钟,并发送 NOP(No Operation 命令),注意,上后,要等待最少 200us,再发送其他指令。

  • ② 发送预充电命令,给所有 Bank 预充电。

  • ③ 发送自动刷新命令,这一步,至少要发送 8 次自刷新命令,每一个自刷新命令之间的间隔时间为 tRC。

  • ④ 设置模式寄存器,这一步,发送模式寄存器的值,配置 SDRAM 的工作参数。配置完成后,需要等待 tMRD(也叫 tRSC),使模式寄存器的配置生效,才能发送其他命令。

  • ⑤ 完成,经过前面四步的操作,SDRAM 的初始化就完成了,接下来就可以发送激活命令和读/写命令,进行数据的读/写了。

  • 这里提到的 tRC、tMRD 和 tRSC 见 SDRAM 的芯片数据手册。

写操作

  • 在完成对 SDRAM 的初始化后,我们就可以对 SDRAM 进行读写操作了,写操作时序图如下所示:

  • SDRAM 的写流程如下:

  • ① 发送激活命令,此命令同时设置行地址和 BANK 地址,发送该命令后,需要等待 tRCD 时间,才可以发送写命令。

  • ② 发送写命令,在发送完激活命令,并等待 tRCD 后,发送写命令,该命令同时设置列地址,完成对 SDRAM 的寻址。同时,将数据通过 DQ 数据线,存入 SDRAM。

  • ③ 使能自动预充电,在发送写命令的同时,拉高 A10 地址线,使能自动预充电,以提高读写效率。

  • ④ 执行预充电,预充电在发送激活命令的 tRAS 时间后启动,并且需要等待 tRP 时间,来完成。

  • ⑤ 完成一次数据写入,最后,发送第二个激活命令,启动下一次数据传输。这样,就完成了一次数据的写入。

读操作

  • 前面介绍了 SDRAM 的写操作,接下来我们看读操作时序,如下图所示:

  • SDRAM 的读流程如下:

  • ① 发送激活命令,此命令同时设置行地址和 BANK 地址,发送该命令后,需要等待 tRCD 时间,才可以发送读命令。

  • ② 发送写命令,在发送完激活命令,并等待 tRCD 后,发送读命令,该命令同时设置列地址,完成对 SDRAM 的寻址。读操作还有一个 CL 延迟( CAS Latency),所以需要等待给定的 CL 延迟(2 个或 3 个 CLK)后,再从 DQ 数据线上读取数据。

  • ③ 使能自动预充电,在发送读命令的同时,拉高 A10 地址线,使能自动预充电,以提高读写效率。

  • ④ 执行预充电,预充电在发送激活命令的 tRAS 时间后启动,并且需要等待 tRP 时间来完成。

  • ⑤ 完成一次数据写入,最后,发送第二个激活命令,启动下一次数据传输。这样就完成了一次数据的读取。

  • SDRAM 的简介,就给大家介绍到这里,以上,tRCD、tRAS 和 tRP 等时间参数,见 SDRAM 的数据手册,且在后续配置 FMC 的时候需要用到。

马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/thin-wind/lvgl.git
git@gitee.com:thin-wind/lvgl.git
thin-wind
lvgl
LVGL
main

搜索帮助

246c6175 1850385 950819b3 1850385