DSP EMIF外扩存储器设计实战笔记:从硬件连接到调试排错
简介一套面向DSP初学者的实习资料包围绕TMS320VC55xx的EMIF外扩存储器设计展开涵盖EMIF引脚配置、时序参数设定、存储器初始化及读写访问等关键环节适合电子工程相关专业学生或嵌入式开发入门者用于课程实习和项目参考。包内共95个文件压缩包仅2.1MB主要包含C语言程序文件、原理图与PCB设计文件、工程配置文件等例如.c/.h源码、.schlib与.pcblib元件库、.prjpcb工程等可配合文档完整还原设计流程。已有274人学习。资料既包含硬件原理图设计与PCB版图也提供软件初始化与读写示例代码还有项目工作区与日志文件便于读者对照学习快速掌握DSP外部存储器扩展的完整实现方法提升嵌入式系统设计与调试能力。 DSP技术及应用实习我抽到的课题是“EMIF外扩存储器设计”。刚开始我以为就是照着原理图接线、开几个寄存器等真正开始做才发现这里面从器件选型、地址映射、时序配置到调试排错环环相扣哪一环没想明白都会卡壳。这篇笔记就把我从拿到题目到最终跑通读写、解决启动问题的完整过程写下来适合正在做DSP实习、课程设计或者第一次用TMS320C6748这类芯片外挂Flash/SRAM的同学参考。1. 实习任务拿到手上先想明白三个问题EMIF全称是External Memory Interface外部存储器接口。DSP芯片内部虽然集成了一部分RAM但程序、数据、日志这些一放大根本不够用所以必须通过EMIF把NOR Flash、SRAM、NAND Flash甚至SDRAM挂到DSP外面去。实习题目的核心就是怎么把一颗外部存储器通过EMIF正确接进系统并且保证读写可靠。动工之前我建议先想清楚三个问题。第一个问题外扩存储器到底用来装什么这个决定了选型方向。如果只是存程序代码选NOR Flash掉电不丢、支持片上XIP直接执行如果要大容量放文件系统或者做启动介质用NAND Flash更划算如果是为了扩展运行时的数据空间那就得上SRAM或者更高性能的SDRAM。TMS320C6748这颗芯片里EMIFA接口主要接NOR Flash、NAND Flash和SRAM这一类异步存储器而DDR2 SDRAM走的是芯片上独立的DDR2/MDDR控制器不能混为一谈。这个区别很重要很多同学一开始就把SDRAM想当然地往EMIF上接对着数据手册找半天也没找到对应片选。第二个问题DSP的EMIF接口能力边界在哪里。C6748的EMIFA支持16位数据总线地址线有23根也就是EA[22:0]片选信号有CS2、CS3、CS4、CS5四个空间每个片选对应一片独立的存储区域。在做硬件连接之前必须把数据手册里EMIFA的性能参数、电气特性、地址映射表都翻一遍尤其是确认你选的存储器时序能不能被EMIF的时序约束满足。举个例子有些老款NOR Flash读周期要90ns而你把EMIFA的异步时钟配得很快会造成采样不稳定这时候就必须降速或者调整周期参数。第三个问题软件侧的访问地址到底是多少。这个问题看起来简单实际上最容易被坑。EMIF不是一个独立外设它挂在DSP的地址总线上所以CPU访问外部存储器就是往一段固定地址空间里读写数据。以C6748为例CS2空间映射在0x60000000起始后续每个片选的映射区间滚动增加。写代码前一定要把映射关系确认好否则程序写进Flash还是读到Flash用CCS的Memory Browser一眼就能看出来。2. TMS320C6748的EMIF接口引脚、片选和地址映射对着最小系统板看C6748的引脚EMIFA相关的引脚主要包括数据线ED[15:0]、地址线EA[22:0]、四个片选线、读写控制线、字节使能等。设计电路之前最好把这些引脚按功能分组列个表格方便检查。信号类别信号名作用说明数据总线ED[15:0]16位并行数据线接存储器对应IO地址总线EA[22:0]用于寻址异步存储器的存储单元片选CS2、CS3、CS4、CS5选择当前访问哪个外部存储器写使能WE低有效表示当前是写操作输出使能OE低有效表示允许存储器输出数据字节使能BA[1:0]16位访问时控制高/低字节C6748的EMIFA映射地址在数据手册的存储器映射表里有明确说明几个片选从低到高依次排列。这里给出我当时参考的简化映射表格具体以你手头芯片型号的数据手册为准。片选地址范围典型用途CS20x60000000 - 0x61FFFFFFNOR Flash / SRAMCS30x62000000 - 0x63FFFFFFSRAM / NOR FlashCS40x64000000 - 0x65FFFFFFSRAM / 其他异步器件CS50x66000000 - 0x67FFFFFFNAND Flash / 扩展外设地址映射清楚之后硬件设计上才不会犯低级错误。比如你打算把NOR Flash挂在CS2上那么片选信号就必须接到DSP的CS2端访问基地址就是0x60000000。如果顺手接到了CS3程序里又按0x60000000去读那不管怎么调都不会有数据。还有一点值得注意EMIFA的地址线是按字还是按字节编址直接决定外部地址线的连接方式。C6748的EMIFA数据总线是16位外部存储器端如果也是16位总线那么DSP的EA[0]不会直接对应到存储器的A[0]具体的偏移接法必须查EMIFA接口章节里的地址映射说明。我当时就是在这里大意了16位模式下把地址线全部一一对应接上结果读出来的数据总像是错位了一个字节后来翻手册才意识到问题所在。这个坑在后面的调试部分还会细说。3. 硬件连接NOR Flash和SRAM到底怎么接硬件连接是EMIF设计里最容易出问题也最容易被忽视的一环。很多实习同学拿到原理图直接照抄连为什么这样接都不知道。我建议至少把NOR Flash和SRAM两种典型接法吃透因为这两种存储器对应的控制逻辑在工作原理上有本质区别。先看NOR Flash。NOR Flash的接口非常接近SRAM有独立的地址线、数据线、片选、写使能、输出使能。典型接法是把DSP的片选接到Flash的CE端读控制接OE写控制接WE地址线和数据线直接并联。由于C6748的EMIFA数据线是16位如果选一颗16位的NOR Flash那么总线宽度匹配连接起来相对简单如果选8位NOR Flash就要把数据线的高8位空着或者通过字节使能信号分两次访问代码里也要按字节操作效率会低不少。NOR Flash的具体接线还有几个细节地址线是否需要偏移、片选和复位引脚的时序关系、写保护引脚是否要上拉。写保护引脚常常被忽略如果接法错误或者悬空Flash会有概率无法写入。我的经验是把Flash的WP引脚通过10k电阻上拉到高电平保证正常工作状态下写保护不使能。另外去耦电容不是随便放的每个电源引脚旁放一个0.1uF陶瓷电容靠近引脚放置电源进来再加一个10uF的钽电容做储能这些在EMIF高速读写时能明显减少噪声引起的偶发错误。再看SRAM。SRAM的接法和NOR Flash很像但多了一个需要注意的点地址建立时间、读/写脉冲宽度这些参数SRAM一般比NOR Flash更严格。由于EMIF的异步接口本身就支持可配置的建立时间、选通时间和保持时间硬件上基本能直接连真正要调节的是软件端的时序寄存器。SRAM的地址线、数据线、控制线接好后用示波器看一次读操作波形把地址有效到数据稳定的时间量出来再回头对照寄存器配置值这样能非常直观地验证时序是否满足要求。如果是接NAND Flash那就完全是另一回事了。NAND Flash把命令、地址、数据全部复用在一组IO上通过CLE、ALE等控制信号来区分当前IO上传的是什么内容。这类存储器的接法不推荐实习阶段自己原创最好直接参考芯片厂商的评估板原理图C6748的EMIFA对NAND的支持一般会通过地址线的某些位来模拟CLE和ALE每个平台的接法都有讲究照抄官方方案是最省事的。4. 寄存器配置和时序计算datasheet里的ns怎么变成寄存器硬件接完之后真正拉开差距的是软件侧的时序配置。时序配置的本质很简单DSP的EMIF模块用寄存器告诉你“访问外部器件时地址建立几个时钟周期、选通几个时钟周期、保持几个时钟周期”。外部存储器数据手册里给的都是纳秒级参数所以关键就是把纳秒换算成时钟周期个数。我当时用的C6748平台EMIFA的异步接口配置主要靠异步配置寄存器英文缩写是A1CRn其中n对应不同的片选。寄存器里主要字段包括setup、strobe、hold和turnaround。Setup对应地址建立时间也就是地址有效到片选/读使能拉低之间的时间Strobe对应片选选通时间也就是读或写脉冲的宽度Hold是地址保持时间Turnaround用于防止读转写、写转读时总线冲突给出一段缓冲周期。换算的方法可以这样理解。假设EMIFA的异步时钟是100MHz一个时钟周期就是10ns。你选了一颗NOR Flash数据手册上写的最大读周期时间是70ns那么访问该Flash的单个读周期就必须大于70ns。如果配置setup1、strobe6、hold1那么总周期就是(161)×10ns80ns大于要求的70ns理论上是满足的。实际工程中还要留余量我一般会在此基础上让总周期再富余20%左右毕竟温度、电压波动都会让存储器实际参数变化。写配置时要注意寄存器字段对应的数值不一定等于实际周期数有些芯片编码需要加1有些字段是直接数值这个必须看寄存器描述。我当时犯过一个典型的错误把strobe字段配成6以为就是6个周期实际上有的平台字段含义是“额外周期数”实际选通周期是7个甚至8个周期。这种误差不会让系统完全不能跑但会导致时序比预期更慢如果之后还要优化读写速度就会被这里的误解卡住。异步接口还有一个容易被忽略的寄存器A1CRn里的turnaround字段。如果你只挂一颗存储器turnaround配成0问题不大但如果在同一组总线上挂了Flash和SRAM两个器件的读转写、写转读交错非常频繁不配置turnaround就可能出现总线竞争最典型的现象是数据总线上出现毛刺偶尔能读到错误数据。这个参数宁可多配一点也不要为了性能省掉。5. 读写验证与实测踩坑从0x55到0xAA的排查寄存器配置完之后就要进入调试验证阶段。第一次验证我建议写一段最笨的测试代码往外部存储器固定地址写一个16位数据再立刻读回来比较是否一致。先写0x55AA再写0xAA55能覆盖每一位的翻转情况。如果这一步都不通过后面都是白搭。用CCS的Memory Browser也能直接查看地址内容但我在调试时发现一个现象明明写的是0x55AAMemory Browser里显示的却是0xAA55或者是顺序错乱的数据。这种问题九成是数据总线高低字节接反了或者地址线偏移导致字节排列错位。还有一次我用了一段循环测试程序让DSP先连续写满2KB数据再读回来校验结果每次都在同一个偏移位置错几个字节后来用示波器抓OE和WE波形才发现是strobe配置太短导致数据还没稳定就被采样了。把strobe从4个周期调到7个周期之后连续跑100遍校验全部通过。我建议每个做EMIF调试的同学都准备一个这样的排查清单遇到问题先按顺序排除片选有没有拉低用示波器看CS引脚确认访问地址是否落在对应片选的映射区间。数据线有没有接反写0x55AA读回0xAA55大概率是高低位反了。地址线有没有偏位读回数据看起来像“隔一个地址”的内容多半是地址偏移接法有问题。写入数据读回来是0xFFFFNOR Flash之前没擦除或者擦除操作没生效。偶发错误优先怀疑时序余量不够把strobe稍微调大再观察。NOR Flash写入还有一个很多人不知道的规则NOR Flash的编程操作只能把位从1变成0不能从0变成1所以往一个已经写过数据的扇区再次写入之前必须先执行擦除操作把扇区擦回0xFF。我第一次调试时反复写同一个地址第二次起数据怎么都写不进去还以为Flash坏了后来才反应过来是没擦除。这个小坑在实习答辩时可以重点讲出来能体现你真的做过。慢速读写的稳定性验证通过之后可以试着把读写速度提上来用DMA批量搬运一定大小的数据块校验CRC。这一步能顺便检验EMIF接口是否适合实际产品场景因为很多DSP应用都需要独立于CPU的DMA通道来搬运外部数据。DMA搬运时DSP的CPU可以同时干别的活这才是外扩存储器的价值真正体现出来的时刻。6. 拔掉JTAG程序就不跑问题多半出在初始化顺序调试阶段通过后我把程序固化到外扩的NOR Flash里准备上电独立运行。结果遇到了一个很经典的问题插着仿真器、连上CCS的时候程序一切正常拔掉JTAG重新上电板子就是跑不起来。很多同学遇到这个情况第一反应是启动模式不对或者Flash烧写有问题但我在排查时发现往往问题出在初始化顺序。用CCS在线调试时仿真器在连接阶段就会帮你初始化DSP、配置一部分外设寄存器还会把代码加载到RAM里。所以调试模式下程序跑得好不代表你的初始化代码完整。拔掉JTAG以后DSP上电执行的是片内ROM里的引导程序它根据启动模式引脚决定从哪个外部存储器引导。如果你想从NOR Flash启动那么引导阶段就需要EMIF已经处于可用状态能够正确读取NOR Flash里的程序。我遇到的具体情况是我的启动代码里有一步是在主函数里才初始化EMIF而引导程序在搬移代码时需要EMIF已经从Flash读取前几KB数据这就形成了一个矛盾EMIF还没来得及配置Flash数据已经取不出来了。解决办法是把EMIF的初始化放到启动阶段最开始的位置用一组最保守的时序参数先让Flash可读等系统跑起来后再重新配置成更快的时序。整个过程如果还涉及DDR2还要注意DDR2控制器的初始化顺序必须放在外部RAM被引用之前。这个问题排查起来并不难用CCS的JTAG连接后在上电复位的断点处停下单步看引导程序卡在哪一步再检查那一步访问外部存储器的寄存器配置基本就能定位。但这个例子很好地说明了EMIF外扩存储器不是接完线配完寄存器就结束的它和整个系统的启动流程、存储器管理、总线仲裁都深度耦合。实习时能把这一条想明白比单纯调通读写测试要加分很多。最后分享一个个人体会做EMIF设计最大的坑往往不在某一步而在“想当然”。你觉得地址线应该这么接觉得时序配一次就够了觉得上电和在线调试没什么区别这些想当然会在后续某个时刻集中爆发。实习生做这个题目最重要的是把从选型到调试的整条链路走通一遍哪怕中途多踩几个坑都比直接抄一份能跑的工程收获大。本文还有配套的精品资源点击获取
上一篇/下一篇内容由系统自动关联
返回资讯列表 →