1. 项目概述与EMIF核心价值
在嵌入式DSP系统开发中,外部存储器接口(External Memory Interface, EMIF)的设计往往是决定系统性能、成本和可靠性的关键一环。它不仅仅是处理器与外部存储芯片之间的一组物理连线,更是数据吞吐的“高速公路”和系统启动的“第一道门”。对于像TI TMS320C6745/6747这类高性能浮点DSP来说,其内置的EMIFA和EMIFB接口,提供了从低速、非易失性存储到高速、大容量易失性存储的完整解决方案。理解并熟练配置这两个接口,意味着你能为DSP系统搭配最合适的“内存外设”,无论是存放启动代码的NOR Flash,存储海量数据的NAND Flash,还是作为高速数据缓冲的SDRAM。
我接触过不少项目,初期因为EMIF配置不当,导致系统不稳定、数据出错甚至无法启动,排查起来非常耗时。这份文档虽然提供了详尽的寄存器列表和电气参数,但对于实际动手配置的工程师来说,中间还缺了关键的“临门一脚”:如何将这些寄存器位域、时序参数翻译成可运行的初始化代码?不同存储芯片混搭时,地址空间如何划分?时序裕量到底留多少才安全?这篇文章,我就结合自己踩过的坑和成功的项目经验,把TMS320C674x的EMIFA和EMIFB接口从原理到配置,掰开揉碎了讲清楚,目标是让你看完就能动手,配完就能稳定跑起来。
2. EMIFA接口深度解析:异步存储与SDRAM的混合舞台
EMIFA是C6745/6747上两个外部存储器接口之一,它的设计非常具有实用性,主打一个“混合”与“灵活”。你可以把它想象成一个多功能I/O扩展坞,既能接U盘(异步存储器),也能接高速固态硬盘(SDRAM)。
2.1 异步存储器支持:不仅仅是片选和读写
异步存储器的核心特点是“请求-响应”模式,没有统一的时钟同步,完全靠控制信号线(如片选CE#、输出使能OE#、写使能WE#)和地址/数据线的时序配合来完成操作。EMIFA为此提供了高度可编程的时序控制器。
关键特性与配置逻辑:
- 数据总线宽度:ZKB封装支持16位,PTP封装支持8位。这直接决定了你一次能存取的数据量。选择16位总线可以提升带宽,但需要占用更多DSP引脚。
- 四个异步片选(
EMA_CS[5:2]):这意味着你可以同时挂接最多四块不同的异步存储芯片,每块芯片占据独立的地址空间。例如,EMA_CS[2]接NOR Flash存放核心代码,EMA_CS[3]接NAND Flash存放文件系统,EMA_CS[4]接一块SRAM作为临时缓冲区。 - 可编程时序参数:这是异步接口配置的灵魂。每个片选都有独立的配置寄存器(
CE2CFG~CE5CFG),你需要根据存储芯片的数据手册,设置以下几个关键时间参数(单位是EMIF时钟周期):- 建立时间(Setup):地址/控制信号有效到读/写选通信号有效之间的时间。确保地址线稳定后,才发出读/写命令。
- 选通时间(Strobe):读/写选通信号(
OE#/WE#)保持有效的持续时间。这必须大于存储芯片要求的数据存取时间(tAA/tWC)。 - 保持时间(Hold):读/写选通信号无效后,地址/控制信号继续保持有效的时间。确保数据被可靠地锁存或写入。
- 总线周转时间(Turn Around):在读写操作之间切换时,总线需要的高阻态时间,防止总线冲突。
实操心得:配置异步时序的“安全法则”数据手册给出的参数通常是最小值。在实际配置时,我强烈建议采用“最小值 + 裕量”的原则。例如,某NOR Flash的读周期时间tRC最小为70ns。假设你的EMIF时钟(EMA_CLK)是100MHz(周期10ns),那么RST(读选通时间)至少需要设置为7个周期(70ns)。为了系统在电压、温度波动下依然稳定,我会设置成8或9个周期。计算时序时,务必使用最慢的时钟频率(即EMA_CLK可能的最长周期)来核算,这样才能覆盖所有工作条件。
2.2 NAND Flash控制器的特殊加成
EMIFA对NAND Flash的支持不是简单的GPIO模拟,而是内置了硬件控制器,这带来了巨大便利:
- 硬件ECC引擎:支持对512字节数据块进行1位(汉明码)或4位(BCH码)的ECC计算和校验。在读写NAND时,控制器会自动计算ECC值,你可以将其存入OOB(备用区)。读取时,控制器会自动校验并报告错误。这极大地减轻了CPU负担,并提高了数据可靠性。
- 专用控制信号:提供了
ALE(地址锁存使能)和CLE(命令锁存使能)信号线,符合标准NAND接口协议,无需再用GPIO模拟。 - 就绪/忙信号(
EMA_WAIT):可以连接NAND的R/B#引脚,实现硬件等待。当NAND操作未完成时,此信号拉低,EMIFA会自动插入等待周期,实现无阻塞访问。
注意事项:Bootloader对片选的约定文档里提到了一个至关重要的细节:芯片内部的Bootloader对启动设备所在的片选有硬性要求。对于NOR启动模式,Bootloader固定从EMA_CS[2]所接的NOR Flash中读取第一段引导代码。对于NAND启动模式,则固定从EMA_CS[3]所接的NAND Flash中读取。如果你的硬件设计把启动Flash接到了EMA_CS[4],那么芯片将无法直接启动。当然,你可以在EMA_CS[2]或[3]上放一小段“二级引导程序”,再由它去加载EMA_CS[4]上的主程序,但这增加了复杂性。所以,硬件设计阶段就必须规划好。
2.3 SDRAM支持:作为“第二接口”
在ZKB封装的C6745/6747上,EMIFA除了异步接口,还提供了一个16位宽的SDRAM接口,使用专用的EMA_CS[0]片选。这相当于给你的系统增加了一块高速的“运行内存”。它支持的特性很标准:
- 容量与组织:支持1、2、4个Bank的SDRAM,列地址为8、9、10、11位。结合13位行地址,可以支持从32Mb到1Gb的各种容量芯片(参见文档中的Table 6-17)。
- 关键参数:CAS Latency(CL)支持2或3个时钟周期。这是SDRAM性能的关键参数,值越小,从发出读命令到数据输出的延迟越短。
- 低功耗模式:支持自刷新(Self-Refresh)和掉电(Powerdown)模式。在系统空闲时,将SDRAM置于自刷新模式可以大幅降低功耗,同时保持数据。掉电模式功耗更低,但需要DSP定期唤醒SDRAM进行刷新。
配置核心:三大寄存器配置SDRAM不像配置异步存储器那样直接设置时间参数,而是通过配置SDRAM芯片的“操作流程”来实现。
- SDRAM配置寄存器(
SDCR):设置核心参数,如数据总线宽度(此处固定为16位)、Bank数量(SDRAM_BANK位域)、CAS延迟(CL位域,例如0x2代表CL=2)、行列地址宽度等。 - SDRAM时序寄存器(
SDTIMR):设置SDRAM操作的各种时间要求,单位是EMIF时钟周期。这是最容易出错的地方。T_RFC:自动刷新周期时间。必须大于SDRAM芯片手册中的tRFC(例如,64ms/8192行 ≈ 7.8us)。T_RP:预充电命令周期时间。必须大于芯片的tRP。T_RCD:行选通到列选通延迟。必须大于芯片的tRCD。T_WR:写恢复时间。必须大于芯片的tWR。T_RAS:行有效时间。必须大于芯片的tRAS。
- SDRAM刷新控制寄存器(
SDRCR):设置刷新速率。最关键的是RR位域,它决定了每隔多少个EMIF时钟周期发起一次自动刷新命令。计算公式为:刷新间隔 = (RR + 1) / EMA_CLK频率。这个间隔必须小于SDRAM芯片要求的最大刷新间隔(通常是64ms内刷新8192次,即每7.8us需刷新一次)。
避坑指南:SDRAM初始化序列配置好寄存器不等于SDRAM就能用了。SDRAM上电后必须执行一个严格的初始化序列,这个序列通常由EMIF硬件状态机自动完成,但你需要确保配置正确并触发初始化。流程大致如下:
- 上电后等待至少200us(通常由软件延时实现)。
- 对所有Bank发送预充电命令(通过写
SDCR的SDC位域触发)。 - 发送至少2个(通常8个)自动刷新命令(通过写
SDRCR的SR位域触发)。 - 发送模式寄存器设置命令(MRS,通过写
SDTIMR的TMRS位域并结合特定地址线值来设置,例如设置CL、突发长度等)。 - 初始化完成,进入正常操作模式。 在C674x的EMIF中,上述步骤2-4通常是通过向特定的“SDRAM命令寄存器”(如果存在)写入命令码来执行的,或者由配置寄存器中的位触发。你需要仔细查阅《C674x DSP External Memory Interface (EMIF) User‘s Guide》来确认具体的软件操作流程。
3. EMIFB接口:专为高性能SDRAM设计
EMIFB是C6745/6747上的另一个外部存储器接口,它的定位非常清晰:专为高速、大容量SDRAM设计。与EMIFA的“混合型”不同,EMIFB是“专业型”选手。
3.1 架构与性能优势
从文档中的框图(Figure 6-20)可以看出,EMIFB通过一个交叉开关(Crossbar)连接到多个主设备(如CPU、EDMA、USB、uPP等)。这种架构支持分离事务,意味着读请求和写请求可以并发进行,大大提升了总线利用率和系统并发性能。这对于需要高带宽数据吞吐的应用(如视频处理、高速数据采集)至关重要。
关键特性对比:
- 数据总线:支持32位宽,是EMIFA(16位)的两倍,在相同时钟频率下,理论带宽翻倍。
- 时钟频率:文档指出EMIFB支持高达152MHz的SDRAM操作(EMIFA为100MHz)。更高的时钟意味着更高的数据吞吐率。
- 地址容量:支持最多13位行地址,列地址支持8/9/10/11位,Bank数支持1/2/4个。其支持的SDRAM密度更大(参见Table 6-23),最高可达2Gb(256MB)的单片容量。
- 接口:仅支持SDRAM,不支持异步存储器。引脚定义与EMIFA的SDRAM部分类似,但数据线更多(
EMB_D[31:0]),对应的数据掩码EMB_WE_DQM[3:0]也有4位。
3.2 硬件连接实战:从原理图到引脚分配
文档中的Figure 6-21到6-23以及Table 6-24给出了非常宝贵的硬件连接参考。我们以最常用的连接一片32位宽、256Mb(32MB)的SDRAM为例(假设型号为MT48LC16M16A2, 4M x 16 x 4banks, 共两片组成32位):
- 时钟与使能:
EMB_CLK连接两片SDRAM的CLK,EMB_SDCKE连接CKE,EMB_CS[0]连接两片SDRAM的CS#(并联)。 - 命令线:
EMB_RAS,EMB_CAS,EMB_WE分别连接到两片SDRAM的对应引脚(并联)。 - 地址与Bank选择:
EMB_A[12:0]连接到两片SDRAM的A[12:0]。EMB_BA[1:0]连接到两片SDRAM的BA[1:0]。这里有个关键点:对于32位总线,我们使用两片16位宽的SDRAM并联。这两片SDRAM的地址线和控制线完全并联,它们共同组成一个逻辑存储单元。 - 数据线与掩码:
EMB_D[15:0]连接到第一片SDRAM的DQ[15:0],EMB_WE_DQM[1:0]连接到其LDQM和UDQM。EMB_D[31:16]连接到第二片SDRAM的DQ[15:0],EMB_WE_DQM[3:2]连接到其LDQM和UDQM。这样,一次32位访问会同时读写两片芯片。 - 电源与端接:务必确保SDRAM的VDD/VDDQ电源干净稳定,并在时钟和数据线上根据布线长度和频率考虑是否需要串联匹配电阻(通常22Ω到33Ω),以减少信号反射。
Table 6-24的使用技巧:这张表解决了工程师最头疼的地址线映射问题。例如,对于一颗256Mb、32位宽、4Bank的SDRAM,其内部地址线是A[11:0]。那么,EMB_A[11:0]就应直接连接到SDRAM的A[11:0]。EMB_A[12]可能不用连接,或者在某些容量配置下用作A12。这张表帮你省去了根据容量计算行列地址位宽的繁琐过程。
3.3 寄存器配置精讲
EMIFB的寄存器组(Table 6-25)比EMIFA的SDRAM部分更丰富,体现了其更精细的控制能力。
SDCFG(SDRAM Configuration Register):类似EMIFA的SDCR,配置基本参数。SDRFC(SDRAM Refresh Control Register):刷新控制寄存器。SDTIM1和SDTIM2(SDRAM Timing Registers):将时序参数分成了两个寄存器,允许更灵活的配置。SDTIM1通常包含T_RFC,T_RP,T_RCD,T_WR等核心时序;SDTIM2可能包含T_RAS以及其他更高级的时序参数。务必根据你所用的具体SDRAM芯片数据手册来逐项核对和填写这些值。SDCFG2(SDRAM Configuration 2 Register):可能用于配置一些扩展功能,如部分阵列自刷新(PASR)、驱动强度等。- 性能计数器寄存器(
PC1,PC2,PCC等):这是EMIFB的一大亮点。你可以使能性能计数器,来统计一定时间内EMIFB的读写交易数量、带宽利用率、冲突等待周期等。这对于性能分析和瓶颈定位极其有用。
配置步骤总结:
- 根据硬件设计,确定SDRAM的型号、数据位宽(16/32位)、容量、Bank数、行列地址数。
- 查阅SDRAM芯片手册,找到所有关键时序参数(tRCD, tRP, tRAS, tRFC, CL等)的最小值(单位通常是ns)。
- 确定EMIFB的工作时钟频率(
EMB_CLK)。例如,如果CPU主频是456MHz,EMIFB时钟可能为其分频,假设为152MHz,则周期约为6.58ns。 - 将SDRAM的时序参数(ns)转换为EMIFB时钟周期数。转换公式:周期数 = ceil(时序参数 / EMB_CLK周期)。例如,tRCD=18ns, EMB_CLK周期=6.58ns, 则
T_RCD= ceil(18 / 6.58) = ceil(2.73) = 3个周期。记住,周期数必须是整数,且必须向上取整(ceil)以满足最坏情况。 - 将计算出的周期数,填入对应的寄存器位域(
SDTIM1,SDTIM2)。 - 计算刷新间隔:假设SDRAM要求64ms内刷新8192次,则刷新间隔 = 64ms / 8192 ≈ 7.81us。
RR= ceil(7.81us / 6.58ns) - 1 ≈ 1186 - 1 = 1185。将1185写入SDRFC的RR字段。 - 在代码中,按照数据手册要求的顺序,依次配置
SDCFG、SDTIM1、SDTIM2、SDRFC等寄存器,并执行SDRAM初始化命令序列。
4. 电气时序分析与PCB设计要点
文档中Table 6-19到6-22以及Table 6-26到6-28给出了详细的AC时序特性。这些参数决定了你的电路板(PCB)设计能否稳定工作。
4.1 时序参数解读与计算
以EMIFA SDRAM读时序(Table 6-19, No.19 & 20)为例:
tsu(DV-CLKH):读数据建立时间,最小值1.3ns。这意味着SDRAM芯片输出的数据,必须在EMIF的时钟EMA_CLK上升沿到来之前至少1.3ns就达到稳定有效的状态。th(CLKH-DIV):读数据保持时间,最小值1.5ns。这意味着在EMA_CLK上升沿到来之后,数据还必须保持稳定至少1.5ns。
对于EMIFB的SDRAM接口输出时序(Table 6-27, No.7 & 8):
td(CLKH-AV):时钟到地址有效的最大延迟为5.1ns(CVDD=1.2V时)。这意味着EMB_CLK上升沿后,最晚5.1ns地址线就会稳定。toh(CLKH-AIV):时钟到地址无效的保持时间为1.1ns。这意味着EMB_CLK上升沿后,地址线至少会保持上一个值1.1ns才可能变化。
如何利用这些参数?它们主要用于信号完整性(SI)分析和时序裕量计算。你需要结合SDRAM芯片手册的时序要求(如tAC,时钟到数据输出有效时间)和PCB的传输延迟,来验证系统是否满足建立时间和保持时间的要求。
4.2 PCB布局布线核心准则
- 等长布线:这是高速并行总线设计的黄金法则。同一组信号线(如数据线
D[15:0]、地址线A[12:0])之间的长度差要尽可能小。通常要求误差在几十mil(1mil=0.0254mm)以内。等长的目的是让信号同时到达,避免数据歪斜(skew)。 - 时钟线优先:
EMx_CLK是时序参考基准,必须给予最高优先级的处理。建议走线最短、最直,并包地处理以减少干扰。在源端(DSP端)可以串联一个小电阻(如22Ω)来改善信号质量。 - 控制/命令线与地址线组:
EMx_RAS,EMx_CAS,EMx_WE,EMx_CS,EMx_BA[1:0],EMx_A[12:0]最好作为一组进行等长布线。它们的时序关系紧密。 - 数据线组:
EMx_D[15:0](或EMB_D[31:0])及其对应的数据掩码EMx_WE_DQM[x:0]作为另一组进行等长布线。数据组与地址/控制组之间的等长要求可以相对宽松一些。 - 电源完整性:为SDRAM的VDD和VDDQ提供充足、干净的电源。每个电源引脚附近都必须放置去耦电容(通常为0.1uF和0.01uF并联),并且电容要尽量靠近引脚。整个存储器的电源入口处应放置一个容量更大的电容(如10uF)。
- 参考平面:信号线下方必须有完整、不间断的参考平面(地平面或电源平面),为信号提供清晰的返回路径,这是控制阻抗和减少辐射的关键。
一个实用的检查清单:
- [ ] 所有信号线是否做到了阻抗控制(通常单端50Ω,差分100Ω)?
- [ ] 时钟线是否最短,且与其他信号线保持了3W(线宽的三倍)以上的间距?
- [ ] 数据组、地址组的组内等长误差是否控制在目标范围内(如±50mil)?
- [ ] 去耦电容是否紧贴每个SDRAM电源引脚放置?
- [ ] 是否避免了在连接器或过孔密集区域走关键高速线?
5. 软件驱动开发与调试实战
理解了硬件和寄存器,最终要落地到代码。这里分享一个基于TI的CSL(Chip Support Library)或寄存器直接操作的EMIF初始化框架。
5.1 EMIFA初始化代码示例(以SDRAM为例)
/** * 配置EMIFA SDRAM (假设为一片64Mb, 4Mx16, 4 Banks, CL=2的芯片) * EMIF时钟假设为100MHz (周期10ns) */ void EMIFA_SDRAM_Init(void) { // 1. 确保PLL和时钟配置已经完成,SYSCLK3或PLL/4.5已输出给EMIFA作为EMA_CLK // 2. 配置SDRAM时序寄存器 (SDTIMR) // 假设SDRAM芯片参数:tRFC=70ns, tRP=20ns, tRCD=20ns, tWR=2clk(20ns), tRAS=45ns // 计算周期数(向上取整):tRFC/10ns = 7, tRP/10ns=2, tRCD/10ns=2, tWR=2, tRAS/10ns=5 volatile uint32_t *sdtimr = (volatile uint32_t *)0x68000020; uint32_t sdtimr_val = 0; sdtimr_val |= (7 << 24); // T_RFC = 7 cycles sdtimr_val |= (5 << 20); // T_RAS = 5 cycles sdtimr_val |= (2 << 16); // T_RP = 2 cycles sdtimr_val |= (2 << 12); // T_RCD = 2 cycles sdtimr_val |= (2 << 8); // T_WR = 2 cycles (注意:tWR通常以时钟周期计,此处假设为2) // T_MRD (模式寄存器设置周期),通常为2 sdtimr_val |= (2 << 4); *sdtimr = sdtimr_val; // 3. 配置SDRAM刷新控制寄存器 (SDRCR) // 刷新间隔 = 64ms / 8192 = 7.8125us // RR = (刷新间隔 / EMA_CLK周期) - 1 = (7812.5ns / 10ns) - 1 ≈ 781 - 1 = 780 volatile uint32_t *sdrcr = (volatile uint32_t *)0x6800000C; *sdrcr = 780; // 设置RR字段 // 4. 配置SDRAM配置寄存器 (SDCR) volatile uint32_t *sdcr = (volatile uint32_t *)0x68000008; uint32_t sdcr_val = 0; sdcr_val |= (0x1 << 31); // SDEN = 1, 使能SDRAM时钟 sdcr_val |= (0x0 << 27); // IBANK_POS = 0, Bank地址位位置(根据芯片) sdcr_val |= (0x2 << 24); // CL = 2, CAS Latency = 2 // 假设芯片是4Mx16, 行地址13位(A0-A12),列地址10位(A0-A9) // 对于EMIFA,寄存器位域可能需要设置行列地址宽度,具体请查用户指南 // 例如:sdcr_val |= (0x2 << 20); // 设置某种参数 sdcr_val |= (0x1 << 10); // NM = 0, 接口宽度为16位? (需要查证,可能是位域不同) sdcr_val |= (0x2 << 7); // SDRAM_BANK = 2, 表示4个banks (00=1, 01=2, 10=4) sdcr_val |= (0x1 << 6); // SDRAM_DRIVE = 1, 可能控制输出驱动强度 sdcr_val |= (0x0 << 4); // SDRAM_PAGESIZE = 0, 页大小? (需要查证) *sdcr = sdcr_val; // 5. 执行SDRAM初始化序列(伪代码,具体命令触发方式需查用户指南) // a. 等待上电稳定(>200us),通常用空循环实现 delay_us(500); // b. 发送预充电所有Bank命令(可能通过向特定地址写数据触发) // c. 发送至少2个(通常8个)自动刷新命令 // d. 发送模式寄存器设置(MRS)命令,设置CL、突发长度等 // 在C674x EMIF中,这些命令可能通过向SDCR或另一个命令寄存器写入特定值来触发。 // 例如:*sdcr |= (1 << XX); // 触发预充电命令 // 详细步骤必须参考《EMIF User‘s Guide》中的“SDRAM Initialization”章节。 // 6. 将SDRAM配置寄存器中的SDEN位置1(如果之前未置位),使能SDRAM控制器 // *sdcr |= (1 << 31); }注意:以上代码中的寄存器位域偏移量和命令触发方式是示意性的,绝对不可以直接复制使用。你必须根据《TMS320C674x DSP External Memory Interface (EMIF) User’s Guide (SPRUFL6)》中确切的寄存器定义来编写代码。TI的CSL库(如果提供)中通常有更易用的API,如
EMIFA_configSDRAM()。
5.2 异步存储器(NOR Flash)配置示例
/** * 配置EMIFA CE2空间连接NOR Flash (假设为16位宽,型号AM29LV160D) */ void EMIFA_Async_Init(void) { // 配置异步空间2配置寄存器 (CE2CFG) - 地址 0x68000010 volatile uint32_t *ce2cfg = (volatile uint32_t *)0x68000010; uint32_t ce2cfg_val = 0; // 假设EMA_CLK = 100MHz (10ns), NOR Flash参数如下: // 读周期时间 tRC = 70ns -> 选通时间需要 >=7 cycles // 地址建立时间 tAS = 0ns -> 但需留裕量,设置Setup=2 cycles (20ns) // 地址保持时间 tAH = 10ns -> 设置Hold=2 cycles (20ns) // 写脉冲宽度 tWP = 30ns -> 写选通时间需要 >=3 cycles // 字段位置需查用户指南,以下是假设: ce2cfg_val |= (0x0 << 31); // 异步模式使能? (假设) ce2cfg_val |= (0x1 << 30); // 选择Strobe模式? (SS=1, 使用EMA_WE/EMA_OE) ce2cfg_val |= (0x0 << 28); // 写使能极性? (假设低有效) ce2cfg_val |= (0x0 << 27); // 输出使能极性? (假设低有效) ce2cfg_val |= (0x0 << 26); // 扩展等待使能 EW = 0 (不使用外部WAIT) ce2cfg_val |= (0x2 << 20); // 写保持时间 WH = 2 cycles ce2cfg_val |= (0x3 << 16); // 写选通时间 WST = 3 cycles (30ns) ce2cfg_val |= (0x2 << 12); // 写建立时间 WS = 2 cycles ce2cfg_val |= (0x2 << 8); // 读保持时间 RH = 2 cycles ce2cfg_val |= (0x7 << 4); // 读选通时间 RST = 7 cycles (70ns) ce2cfg_val |= (0x2 << 0); // 读建立时间 RS = 2 cycles // 总线周转时间 TA 可能在另一个寄存器(AWCC)中配置 *ce2cfg = ce2cfg_val; // 配置异步等待周期配置寄存器 (AWCC) - 地址 0x68000004 volatile uint32_t *awcc = (volatile uint32_t *)0x68000004; *awcc = (0x1 << 0); // 设置TA (Turn Around) = 1 cycle, 可根据需要调整 }5.3 调试技巧与常见问题排查
系统无法启动,卡在Boot阶段:
- 检查:首先确认硬件连接,特别是
EMA_CS[2](NOR Boot)或EMA_CS[3](NAND Boot)上的Flash芯片型号、电路是否正确。用示波器测量Boot阶段相关片选和读信号是否有波形。 - 检查:确认EMIF时钟
EMA_CLK是否正常产生。时钟是心脏,没有时钟一切免谈。 - 检查:如果使用SDRAM,确认初始化代码是否在系统初始化早期被正确执行。SDRAM未初始化就访问会导致总线错误。
- 检查:首先确认硬件连接,特别是
可以启动,但运行中偶尔数据错误或死机:
- 检查:时序裕量不足。这是最常见的原因。尤其是在高温或低压条件下。尝试增加读写时序参数(Setup, Strobe, Hold)的时钟周期数,特别是
RST和WST。 - 检查:电源噪声。用示波器测量SDRAM或Flash的电源引脚,看是否有大幅度的毛刺或跌落。加强电源去耦。
- 检查:信号完整性。用示波器(最好带高级触发功能)观察数据线、地址线在读写时的波形。是否有过冲、振铃、边沿过于缓慢?这通常需要优化PCB布局布线或调整串联匹配电阻值。
- 检查:SDRAM刷新率。刷新间隔设置过长会导致数据丢失。重新计算
RR值,确保满足SDRAM芯片的刷新要求。
- 检查:时序裕量不足。这是最常见的原因。尤其是在高温或低压条件下。尝试增加读写时序参数(Setup, Strobe, Hold)的时钟周期数,特别是
读写速度远低于预期:
- 检查:是否启用了EMIF的优化功能?例如,对于SDRAM,可以配置突发长度(Burst Length)为4或8,以提升连续访问效率。在
SDCR或模式寄存器设置中配置。 - 检查:异步存储器的等待周期是否设置过长?在不违反芯片时序的前提下,可以尝试优化
RST/WST等参数。 - 检查:CPU访问EMIF时,是否被其他总线主设备(如EDMA)频繁打断?考虑优化仲裁优先级或使用缓存。
- 检查:是否启用了EMIF的优化功能?例如,对于SDRAM,可以配置突发长度(Burst Length)为4或8,以提升连续访问效率。在
使用性能计数器(EMIFB): 如果问题难以定位,可以启用EMIFB的性能计数器。通过监控读写交易数、冲突次数、空闲周期等,可以量化分析总线瓶颈所在。例如,如果读冲突计数很高,说明多个主设备争抢读总线,可能需要调整访问策略或使用缓存。
最后一点心得:EMIF的配置是硬件和软件的紧密结合。一份清晰的硬件原理图、一份准确的芯片数据手册、一份可靠的PCB设计,再加上耐心细致的软件调试,是成功的关键。每次修改时序参数后,最好能进行高低温测试和电压拉偏测试,以确保系统的鲁棒性。希望这篇结合了手册要点和实战经验的解析,能帮你更顺畅地驾驭TMS320C674x的EMIF接口。