1. 项目概述与核心价值
在嵌入式硬件开发,尤其是基于ARM架构的SoC系统设计中,外部存储器控制器(External Memory Controller, EMC)的时序配置往往是决定系统稳定性和性能上限的关键,却也最容易成为新手工程师的“滑铁卢”。我手头这份NXP LH79524/LH79525的芯片手册,关于EMC波形的那几十页内容,初看就是一堆让人眼花缭乱的时序图、寄存器缩写和参数表格。但正是这些枯燥的波形,决定了你的Nor Flash能否正确启动、SDRAM跑在什么频率、以及整个系统在极端温度下会不会出现偶发性的数据错误。
很多工程师习惯于直接套用参考设计或评估板的配置,对EMC寄存器的设置“不求甚解”,只要板子能跑起来就万事大吉。然而,当产品需要更换内存芯片、提升运行频率或者优化功耗时,问题就来了:系统变得不稳定,数据读写出错,调试起来犹如大海捞针。其根本原因,往往是对EMC如何产生这些控制信号、每个时序参数如何受寄存器影响缺乏深入理解。本文将以LH79524/LH79525的EMC为例,抛开数据手册中冰冷的图表,从一线工程师的视角,拆解静态内存(SRAM, Nor Flash等)读写时序背后的设计逻辑、配置方法以及那些手册上不会写的调试经验和避坑指南。无论你是正在评估这颗芯片,还是已经在产品中应用它,理解这些内容都将帮助你构建更稳健、性能可预测的嵌入式存储子系统。
2. EMC核心工作机制与设计思路拆解
在深入波形之前,我们必须先建立对LH79524/LH79525 EMC工作模式的整体认知。这个EMC模块并非一个简单的“信号发生器”,而是一个高度可配置的时序状态机,其核心任务是在SoC内部高速的AHB总线时钟(HCLK)与外部相对低速的存储器器件之间,扮演一个“节奏协调者”的角色。
2.1 时钟域转换与等待状态(Wait State)的本质
SoC内部以HCLK为节拍运行,速度可能达到几十甚至上百MHz。而外部存储器,尤其是低成本、低功耗的静态存储器,其访问时间(tACC, tWC)通常远慢于一个HCLK周期。EMC解决这个速度失配问题的核心机制就是“等待状态”。你可以把一次存储器访问(读或写)想象成一次标准的“握手”流程:SoC发出请求(地址有效),然后等待外部设备回应(数据有效),最后完成交易。
- 一个等待状态 = 一个额外的HCLK周期:这是手册里明确指出的基础。当EMC启动一次访问时,它会自动插入由
SWAITRDx(读等待)或SWAITWRx(写等待)寄存器配置的固定数量的等待周期。在这段时间内,EMC会保持控制信号(如nOE, nWE)的有效状态,并持续采样数据总线(读操作)或维持数据输出(写操作),等待存储器芯片完成内部操作。 - 为什么需要可编程的等待状态?因为不同的存储器芯片速度不同。一颗70ns访问时间的Nor Flash和一颗10ns访问时间的SRAM,需要的等待周期数天差地别。通过软件配置等待状态寄存器,同一套硬件设计可以适配不同型号、不同速度等级的存储器,极大地提升了设计的灵活性和可扩展性。
2.2 关键控制信号的角色解析
LH79524/LH79525的EMC为每个外部存储区域(通常由片选信号nCSx划分)生成一组控制信号。理解每个信号的职责是看懂时序图的前提:
- nCSx (Chip Select):片选信号,低有效。这是区域选择的“总开关”。当EMC要访问某个地址空间时,对应的nCSx信号拉低,告知该区域内的存储器芯片:“注意,接下来的操作是针对你的”。在时序中,nCSx的断言(变低)标志着一次访问交易的开始。
- nOE (Output Enable):输出使能,低有效。仅用于读操作。当nOE有效时,它命令被选中的存储器芯片将其内部数据驱动到数据总线(D[31:0])上。SoC会在nOE撤销(变高)的边沿采样数据总线,锁存读取的数据。
- nWE (Write Enable) / nBLEx (Byte Lane Enable):写使能或字节使能,低有效。仅用于写操作。nWE是通用的写使能,用于控制写操作。nBLEx(如nBLE0, nBLE1等)则用于8位或16位宽度的设备,实现对特定字节的写入。在波形中,nWE/nBLEx的有效脉冲宽度直接决定了数据被写入存储器芯片的“窗口”时间。
- nWAIT:这是一个由外部设备驱动的输入信号,低有效。它是实现动态延长访问周期的关键。当外部设备(如一个慢速的CPLD或特殊接口芯片)觉得EMC预设的固定等待状态还不够时,可以主动拉低nWAIT信号,告诉EMC:“我还没准备好,请再等等”。EMC会采样这个信号,并据此插入额外的等待周期。这为连接那些时序不标准或响应时间可变的设备提供了可能。
2.3 寄存器配置与波形生成的映射关系
手册中的波形图不是凭空画出来的,每一个信号边沿的位置、脉冲的宽度,都直接由一组特定的EMC控制寄存器决定。对于静态内存控制器(SMC)部分,主要涉及以下几组寄存器(以Bank x为例):
SWAITRDx:读等待状态寄存器。定义在nOE有效后,到nOE撤销前,需要插入的HCLK周期数。SWAITWRx:写等待状态寄存器。定义在nWE有效后,到nWE撤销前,需要插入的HCLK周期数。SWAITOENx:输出使能延迟寄存器。控制nOE信号在nCSx有效后,延迟多少个HCLK周期才有效。用于满足存储器芯片的地址建立时间(tAS)要求。SWAITWENx:写使能延迟寄存器。控制nWE信号在nCSx有效后,延迟多少个HCLK周期才有效。同样用于满足写时序的建立时间。
配置这些寄存器时,工程师需要根据目标存储器芯片的数据手册中的AC时序参数(如tRC, tWC, tOE, tWE等),结合SoC的HCLK频率,进行周密的计算。这个过程就是硬件时序设计的核心。
3. 静态内存读写波形深度解析与实操要点
现在,我们结合手册中的图表,逐一拆解关键波形,并解释每个阶段在硬件上的实际意义和配置方法。
3.1 零等待状态读周期(Figure 17)分析
手册中的Figure 17展示的是最理想、最快的读操作。我们把它翻译成工程师的语言:
配置前提:
SWAITRDx = 0,SWAITOENx = 0。这意味着不插入额外的读等待,且nOE立即使能。时序相位分解:
- T0 (起点):在HCLK的某个上升沿,EMC将地址
A[23:0]驱动到地址总线上,并同时断言(拉低)nCSx信号。此时,nOE也几乎同时被拉低(因为SWAITOENx=0)。这个阶段对应存储器芯片的地址建立时间(tAS)。 - T1 (数据捕获点):经过一个HCLK周期后,在下一个HCLK上升沿,EMC会撤销nOE(拉高)。nOE的上升沿告诉SoC:“现在数据总线上的值是稳定的,可以采样了”。SoC在内部锁存数据
D[31:0]。同时,nCSx也在此时或稍后撤销。 - T2 (地址保持):地址信号会在数据被捕获后,继续保持有效一个HCLK周期(图中标注的‘C’阶段),以满足存储器芯片对地址保持时间(tAH)的要求。
- T0 (起点):在HCLK的某个上升沿,EMC将地址
核心结论与计算:一次零等待状态的读操作,最短需要2个HCLK周期(从nCSx有效到nCSx无效)。假设HCLK=50MHz(周期20ns),那么最短读周期为40ns。这意味着,你选用的存储器芯片的读周期时间(tRC)必须小于或等于40ns,否则无法在此配置下可靠工作。
实操心得:
SWAITOENx设为0是最激进的做法,要求PCB布线非常好,地址到存储器的延迟极小。在实际产品中,尤其是板子空间紧张、走线较长时,建议适当增加SWAITOENx的值(如1或2),为地址信号留出足够的建立时间裕量,这是提升系统抗干扰能力的一个小技巧。
3.2 零等待状态写周期(Figure 18)分析
写操作通常比读操作多一个阶段,因此时序也稍长。
配置前提:
SWAITWRx = 0,SWAITWENx = 0。时序相位分解:
- T0:HCLK上升沿,地址
A[23:0]有效,nCSx断言。 - T1:关键区别点。与读操作不同,
nWE(或nBLEx)不会立即有效。EMC会固定延迟一个HCLK周期,在T1时刻才断言nWE。同时,要写入的数据D[31:0]也在此时刻附近变得有效。这个延迟是为了确保在写使能有效前,地址和数据都已经在总线上稳定了足够的时间(满足tAS和tDS)。 - T2:再经过一个HCLK周期(因为
SWAITWRx=0),在T2时刻,EMC撤销nWE。nWE的上升沿指示外部存储器芯片锁存当前数据总线上的值。 - T3:
nCSx撤销,地址和数据总线继续保持一个周期(‘C’阶段)后释放。
- T0:HCLK上升沿,地址
核心结论与计算:一次零等待状态的写操作,最短需要3个HCLK周期。同样以50MHz HCLK计算,最短写周期为60ns。你选用的存储器芯片的写周期时间(tWC)必须小于等于60ns。
注意事项:对于8位或16位宽度的设备使用字节使能(
nBLEx)时,其时序与nWE完全相同。这意味着你不能为不同的字节通道设置不同的写时序。如果你的设计中有多个不同速度的8位设备挂在同一数据总线的不同字节上,时序必须按最慢的那个设备来配置。
3.3 带等待状态的读写波形(Figure 19 & 20)
这是实际项目中最常见的场景。以Figure 19(3等待状态读)为例:
- 配置:
SWAITRDx = 0x3。 - 时序变化:在地址有效、nCSx和nOE断言后,EMC不会在第一个HCLK上升沿后就撤销nOE。相反,它会“等待”3个完整的HCLK周期。直到第4个上升沿(即延迟了3个等待状态后),nOE才被撤销,数据被采样。整个读周期被延长为
2 + SWAITRDx个HCLK周期(此例为5个周期)。 - 设计意义:这允许你连接速度更慢的存储器。例如,一个读访问时间为100ns的Nor Flash,在50MHz HCLK下,一个周期20ns,至少需要5个周期(100ns)。因此,你需要设置
SWAITRDx >= 3(因为零等待已占2周期,3个等待状态增加60ns,总计4周期80ns仍不够,需设置为4等待,总计6周期120ns,留有20ns裕量)。计算等待状态数的公式是:所需HCLK周期数 = CEIL(存储器芯片tRC / HCLK周期时间),而SWAITRDx = 所需HCLK周期数 - 2。
Figure 20展示了2个写等待状态的配置(SWAITWENx=0,SWAITWRx=2)。关键点是nWE的有效宽度被扩展了。在零等待写中,nWE有效宽度是1个HCLK周期(T1到T2)。现在,它变成了1 + SWAITWRx个周期,即3个HCLK周期(T1到T3之后)。这给了存储器芯片更长的数据写入时间。
3.4 nWAIT信号的动态扩展机制(Figure 11-16)
nWAIT是应对不确定性延迟的终极武器。手册Figure 11-16的几张图虽然复杂,但讲清楚了一个核心规则:nWAIT信号并不是在任何时候被采样到低电平都会起作用的。
- 采样与忽略窗口:EMC只在每个HCLK的上升沿采样nWAIT。更重要的是,它有一个“忽略窗口”。以读操作为例(Figure 11),只有当内部等待状态计数器减到
WST-3(即SWAITRDx - 3)及之后,采样到的低电平nWAIT才会被“排队”(Queued),从而插入额外的延迟。在此窗口之前采样到的nWAIT低电平会被忽略(Sampled and Ignored)。 - 为什么这样设计?这是为了给外部设备一个明确的“响应期限”。如果外部设备在访问周期很早期就拉低nWAIT,EMC会认为这可能是一个毛刺或错误信号而忽略它。设备需要在访问周期的后半段(临近结束时)仍然需要更多时间,才拉低nWAIT,这样设计更可靠。它确保了nWAIT信号是用于处理“预期内但稍长”的延迟,而非应对完全不可预测的早期故障。
- 对设计的影响:如果你使用nWAIT功能,外部设备(如FPGA、CPLD)的逻辑设计必须遵守这个时序窗口。它需要在EMC访问周期开始后的特定时间点(由
SWAITRDx/WRx值决定)之后,才能拉低nWAIT,并且需要在EMC预期的时间段内保持低电平。
4. 寄存器配置实战与计算示例
理解了波形,最终要落地到寄存器的配置上。我们以一个具体的场景为例,演示完整的计算和配置过程。
4.1 设计场景定义
假设我们为LH79525设计一个外部Nor Flash启动存储器,选用芯片型号为Spansion S29GL064N(仅作示例)。关键时序参数如下(从其数据手册获取):
- HCLK频率:50 MHz(周期 T = 20 ns)
- Nor Flash参数:
- 读周期时间
tRC=90 ns - 输出使能有效到数据有效
tOE=25 ns - 片选有效到输出有效
tCE=90 ns - 地址建立时间
tAS=0 ns(通常很小) - 地址保持时间
tAH=10 ns - 写周期时间
tWC=90 ns - 写使能脉宽
tWP=35 ns
- 读周期时间
4.2 读时序配置计算
我们的目标是配置SWAITRDx和SWAITOENx,确保EMC产生的时序满足Flash芯片的所有要求。
确定最小读周期所需HCLK数: Flash要求
tRC = 90ns。HCLK周期为20ns。所需周期数 = CEILING(90ns / 20ns) = CEILING(4.5) = 5 个HCLK周期。 一次读操作至少需要2个基础周期(见3.1节),因此需要插入的等待状态数为:SWAITRDx = 5 - 2 = 3。校验输出使能时间: EMC的nOE有效时间等于
(1 + SWAITRDx) * HCLK周期。SWAITRDx=3,所以nOE有效时间为4 * 20ns = 80ns。 Flash要求tOE <= 25ns,这个条件非常宽松,80ns远大于25ns,完全满足。实际上,tOE参数是限制nOE有效后数据多久能出来的最大值,我们提供的有效时间更长,没有问题。校验片选有效到输出有效时间: EMC的nCSx有效到nOE撤销(数据采样点)的时间为
(2 + SWAITRDx) * HCLK周期 = 5 * 20ns = 100ns。 Flash要求tCE <= 90ns。100ns > 90ns,满足要求。如果计算结果小于tCE,就需要增加SWAITRDx。配置SWAITOENx: 这个寄存器控制nOE相对于nCSx的延迟。Flash的
tAS为0,理论上可以设为0。但考虑到PCB走线延迟,建议设置1个周期的裕量,即SWAITOENx = 1。这意味着nCSx有效后,延迟1个HCLK周期(20ns)nOE才有效,为地址信号到达Flash留出更多建立时间。
4.3 写时序配置计算
确定最小写周期所需HCLK数: Flash要求
tWC = 90ns。所需周期数 = CEILING(90ns / 20ns) = 5 个HCLK周期。 一次写操作至少需要3个基础周期(见3.2节),因此需要插入的写等待状态数为:SWAITWRx = 5 - 3 = 2。校验写使能脉宽: EMC的nWE有效时间为
(1 + SWAITWRx) * HCLK周期 = 3 * 20ns = 60ns。 Flash要求tWP >= 35ns。60ns > 35ns,满足要求。配置SWAITWENx: 与
SWAITOENx类似,控制nWE的延迟。同样出于裕量考虑,设为1,即SWAITWENx = 1。
4.4 配置代码示例(C语言风格)
假设Nor Flash连接在EMC的Bank 0,地址范围为0x6000 0000。
// 假设 EMC 寄存器基地址为 0xFFE0 8000 #define EMC_BASE 0xFFE08000 #define SMC_BANK0_OFFSET 0x200 // Bank0 控制寄存器组偏移 typedef struct { volatile uint32_t CONFIG; // 配置寄存器(数据宽度等) volatile uint32_t WAITRD; // 读等待寄存器 volatile uint32_t WAITWR; // 写等待寄存器 volatile uint32_t WAITOEN; // 输出使能延迟 volatile uint32_t WAITWEN; // 写使能延迟 // ... 其他寄存器 } SMC_Bank_TypeDef; #define SMC_BANK0 ((SMC_Bank_TypeDef *)(EMC_BASE + SMC_BANK0_OFFSET)) void NorFlash_EMC_Init(void) { // 1. 配置存储器位宽(例如16位)、使能Bank等(略) // SMC_BANK0->CONFIG = ...; // 2. 配置读时序参数 (根据上述计算) SMC_BANK0->WAITRD = 3; // SWAITRD0 = 3 SMC_BANK0->WAITOEN = 1; // SWAITOEN0 = 1 // 3. 配置写时序参数 SMC_BANK0->WAITWR = 2; // SWAITWR0 = 2 SMC_BANK0->WAITWEN = 1; // SWAITWEN0 = 1 // 4. 如果需要,配置nWAIT引脚功能(通常为GPIO输入模式并映射到EMC功能) // ... }5. 常见问题排查与调试经验实录
即使计算无误,实际硬件调试中仍会遇到各种问题。以下是我在多个项目中总结的EMC相关问题的排查思路。
5.1 问题:系统不稳定,偶发性读写出错,尤其在高温或低温下。
- 排查思路:
- 检查时序裕量:这是最常见的原因。回顾第4节的计算,我们使用了“刚好满足”或“最小满足”的参数。在实际环境中,电源噪声、温度变化导致的器件参数漂移、PCB信号完整性都会侵蚀时序裕量。经验法则:至少保留20%-30%的时序裕量。对于上述例子,读周期我们用了100ns满足90ns要求,裕量约11%。在严苛环境下可能不够。尝试将
SWAITRDx增加到4(总周期120ns),看问题是否消失。 - 检查电源和去耦:EMC接口是高速数字信号,瞬间电流大。确保存储器芯片和SoC的电源引脚有充足、就近的退耦电容(如100nF + 10uF组合)。用示波器测量电源轨,看在进行大量连续内存访问时是否有明显的电压跌落或毛刺。
- 检查信号完整性:使用示波器(最好带高速探头)直接测量nCSx、nOE、nWE、地址线和数据线。关注:
- 过冲和下冲:如果幅度超过Vih/Vil范围,可能误触发。通常需要在信号线上串联小电阻(22-33欧姆)进行阻抗匹配。
- 信号边沿:是否陡峭?缓慢的边沿会增加开关时间,吃掉时序裕量。
- 交叉干扰:数据线之间、地址线之间是否有串扰?确保PCB布线遵守等长、间距原则。
- 检查时序裕量:这是最常见的原因。回顾第4节的计算,我们使用了“刚好满足”或“最小满足”的参数。在实际环境中,电源噪声、温度变化导致的器件参数漂移、PCB信号完整性都会侵蚀时序裕量。经验法则:至少保留20%-30%的时序裕量。对于上述例子,读周期我们用了100ns满足90ns要求,裕量约11%。在严苛环境下可能不够。尝试将
5.2 问题:写入数据正常,但读回的数据不正确(特定位翻转)。
- 排查思路:
- 重点检查数据总线:这通常是数据线连接问题或总线冲突。首先确认PCB上数据线(D0-D31)没有虚焊、短路。如果是16位设备,检查高16位数据线是否被错误上拉/下拉。
- 检查字节使能配置:如果你使用的是8位或16位设备,并启用了
nBLEx信号,请确认nBLEx的映射是否正确。例如,向一个16位设备的低字节(地址0x6000 0000)写入,应该是nBLE0有效,而nBLE1无效。配置错误会导致数据写入错误的字节通道。 - 检查上拉/下拉电阻:未使用的数据总线位,建议通过电阻(如10kΩ)上拉到电源或下拉到地,避免浮空引入噪声。LH79524/LH79525数据手册的“UNUSED INPUT SIGNAL CONDITIONING”章节也强调了这一点。
5.3 问题:使用nWAIT功能时,访问会超时或挂死。
- 排查思路:
- 确认nWAIT引脚配置:首先确认连接nWAIT的SoC引脚已正确配置为EMC功能(而非GPIO),并且方向为输入。
- 验证nWAIT信号波形:用示波器同时捕获nCSx和nWAIT信号。确保nWAIT信号在EMC的“采样窗口”内(即等待状态计数器到达
WST-3之后)被拉低,并且低电平宽度足够(手册要求最小2个HCLK周期)。一个常见的错误是外部设备拉低nWAIT的时间太早或太短。 - 检查外部设备驱动能力:nWAIT是输入信号,但外部设备必须有足够的驱动能力来可靠地拉低它,尤其是在有较长走线或负载的情况下。如果怀疑驱动能力,可以在SoC端的nWAIT引脚上加一个弱上拉电阻(如4.7kΩ),确保无驱动时为高电平。
5.4 调试工具与技巧
- 逻辑分析仪是你的好朋友:这是分析EMC时序最直观的工具。连接HCLK(或使用一个同步的时钟)、nCSx、nOE/nWE、地址线和数据线。设置触发条件(如nCSx下降沿),捕获一次完整的读写波形。然后测量关键时间参数(如nCSx有效到nOE无效、nWE脉宽等),与计算值及Flash芯片手册要求进行对比。
- 利用SoC的GPIO模拟或监测:在调试初期,如果不确定配置是否正确,可以暂时将nCSx、nOE等关键控制信号先配置为GPIO输出,用软件模拟一个最简单的读写时序,验证硬件连接和存储器芯片基本功能是否正常。这能帮你隔离是EMC配置问题还是更底层的硬件问题。
- 从保守配置开始:在第一次调试时,不要使用计算出的最小值。将
SWAITRDx、SWAITWRx等参数设置得大一些(比如读/写都设置成10),让周期足够长。如果此时读写正常,再逐步减小数值,直到找到临界点,然后加上足够的裕量。这比一开始就卡在临界值附近调试要高效得多。
6. 动态内存(SDRAM)控制器波形要点提示
虽然本文重点在静态内存,但LH79524/LH79525的EMC也包含SDRAM控制器。其原理更为复杂,涉及行激活、列选通、预充电、刷新等命令序列。手册中的Figure 21和22展示了突发读和写操作的波形。
- 核心差异:SDRAM时序由一系列标准命令(ACTIVE, READ, WRITE, PRECHARGE等)组成,这些命令通过RAS、CAS、WE、CS等信号的组合在时钟边沿发出。时序参数如tRCD(RAS to CAS Delay)、tCAS(CAS Latency)、tRP(Precharge Time)等,需要配置到EMC的SDRAM相关寄存器中。
- 配置关键:SDRAM的配置必须严格遵循其数据手册。重点配置寄存器包括:
- 控制寄存器:设置数据位宽、CAS延迟、突发长度等。
- 时序寄存器:配置tRCD, tRP, tRAS, tWR等参数对应的时钟周期数。
- 刷新寄存器:配置刷新周期。
- 调试难点:SDRAM问题常常表现为“跑一段时间后死机”或“大量数据搬运时出错”,这很可能与刷新时序不当、电源完整性差或PCB布局导致的信号完整性问题有关。调试SDRAM对示波器要求更高,通常需要差分探头来精确测量时钟和数据选通(DQS)信号。
7. 电路板设计与布局的实践经验
手册最后部分关于电路板布局的建议绝非空话,对于运行在几十MHz的并行总线,布局布线至关重要。
- 等长布线:对于地址总线和数据总线,组内信号(如所有数据线D0-D15)应尽可能等长。这可以减少信号偏移(skew),确保所有位同时到达,避免建立/保持时间违例。误差控制在50-100 mil(1.27-2.54mm)以内是常见要求。
- 终端匹配:如手册所述,LH79524/LH79525的输出边沿很快。如果走线较长(例如超过几英寸),末端反射会成为问题。除了串联小电阻(源端匹配)外,对于点对点拓扑,在接收端(存储器芯片)对地并联一个几十欧姆的电阻也可能有帮助,但这会增加功耗和设计复杂度,需要根据仿真或实测决定。
- 电源去耦:在每个存储器芯片的电源引脚附近(最好是芯片背面),放置一个0.1uF的陶瓷电容。在Bank的电源入口处,放置一个10uF的钽电容或大容量陶瓷电容。这是抑制同步开关噪声(SSN)的标准做法。
- 地平面完整性:为高速信号提供完整、低阻抗的返回路径。尽量避免在地址/数据线的下方分割地平面。密集的过孔会破坏地平面,布线时需注意。
理解LH79524/LH79525的EMC时序,归根结底是在理解SoC与外部世界通信的“语言”。数据手册上的波形图是这种语言的语法规则,而寄存器配置则是组词造句。通过精确的计算、谨慎的配置,并结合扎实的调试手段,你就能让这套系统流畅稳定地运行。记住,在嵌入式硬件里,时序是数字电路的血液,而EMC就是确保血液正确泵送的心脏。多花时间琢磨这些波形和参数,在后续的系统调试和问题排查中,这些投入会以十倍百倍的价值回报给你。