ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

STM32H745外扩SDRAM/IS42S83200J:从FMC配置到PCB布线全解析

STM32H745外扩SDRAM/IS42S83200J:从FMC配置到PCB布线全解析 1. 为什么需要外扩SDRAMH745内部SRAM不够用的场景分析STM32H745IIT6这颗料我在不少客户项目里见过。双核Cortex-M7480MHz Cortex-M4240MHz片上一共塞了1MB的RAM听起来不少但真到了实际应用里你会很快发现这1MB根本不够用。最典型的例子是带GUI的产品。跑个TouchGFX或者LVGL做一帧1024x600的RGB565显示缓冲一帧就要1024x600x2 1.2MB直接超过片上RAM总量。有人说那我分块刷屏不用全帧缓冲可以但刷新效果和流畅度都会有明显妥协尤其在动画或视频播放场景里撕裂和闪烁是逃不掉的。另一个场景是音频处理。多通道音频输入输出、FFT计算、延时效果器这些中间缓冲在双核架构下很容易就吃掉几百KB。再加上两个核各自的堆栈、通信缓冲池、协议栈内存你会发现片上1MB RAM的实际可用量可能只有一半左右而且M7和M4共用这1MB还存在着总线仲裁的带宽问题。所以我几乎在所有需要跑UI、跑算法、或需要大缓存的项目里都会建议外扩SDRAM。外扩之后的效果是立竿见影的M7核可以放心用大数组做算法缓冲全帧GUI缓冲也成了标配系统整体稳定性反而大幅提升。因为很多看似偶发的死机、HardFault追根到底其实是内存不够用导致的堆栈溢出。2. 芯片选型逻辑IS42S83200J 为什么是稳妥方案选择外挂SDRAM前先搞清楚市面上常见方案的差别。很多人一听外扩内存第一反应是PSRAM或者干脆换大RAM的单片机但实际上SDRAM在性价比、容量密度和使用成熟度上对STM32H7系列来说是最优解。2.1 IS42S83200J核心参数与定位IS42S83200J这颗芯片的具体身份是8M x 32bit的同步DRAM总容量32MB单条Bank结构设计内部划分4个Bank兼容3.3V供电工作频率最高143MHz。关键信息是8M x 32——每个地址对应32位数据这意味着H745的FMC总线可以一次读写4字节对CPU的访问效率非常友好。相比两颗16bit颗粒拼接的方案单颗32bit颗粒在PCB布局上能少掉一整套数据线布板难度和故障率都会下降对中小批量板子来说是个长期省心的选择。参数上需要注意几个硬指标刷新周期4096行/64ms正常温度区间也就是每行刷新周期约15.625usCAS延迟可配2或3个时钟周期内部自动预充电和自刷新模式都支持。这些时序要求直接决定了后面FMC控制器怎么配后文会细讲。2.2 为什么不是DDR、不是PSRAMDDR/DDR2颗粒需要终端匹配电阻、更严格的等长控制、更复杂的电源设计在一颗MCU系统里做DDR布线性价比很低。SDRAM是单沿采样、共享总线布线要求放宽很多2层板都能跑起来。PSRAM的优点是无需外部刷新技术但容量做不大、价格也偏高超过16MB的PSRAM很少见。当需求是32MB级别的缓存时SDRAM几乎是唯一高性价比选择。STM32H7系列自带的FMC控制器原生支持SDRAM颗粒硬件电路和驱动库都是现成的这也是选IS42S83200J的重要理由。2.3 与H745的兼容性检查H745IIT6的FMC支持SDNE片选、SDNWE写使能、SDNE/SDCKE等专用控制信号数据总线宽度可配为8/16/32位地址线A[12:0]正好匹配8M x 32的13位列地址线。IS42S83200J的行地址13位、列地址9位、Bank地址2位FMC的SDRAM控制器按行列Bank结构识别兼容性没有问题。我实测过在不同温度的稳定性常温25度下用143MHz跑压力测试数据线和地址线等长控制在25mil以内时读写数据始终稳定连续跑24小时没有出现bit翻转。工业级温度范围-40到85度下把FMC时钟降到120MHz也依然稳定这个余量对于实际产品来说够用了。3. 硬件连接设计FMC总线上每根线的接法硬件连接是整个设计中出错率最高的部分。很多人在原理图上看着参考设计照搬但没搞懂信号流向直接导致PCB板回来怎么调都调不通。3.1 信号线连接对照IS42S83200J的引脚定义和H745 FMC的对应关系如下数据线FC0到FC31分别连接SDRAM的DQ0到DQ31。这个没什么花头只要记住FMC是以字节为单位使能访问的DQM引脚要特别对待。IS42S83200J只有DQML和DQMH两个字节屏蔽引脚用于低16位和高16位的字节使能。H745的FMC会输出对应的字节选择信号通过连接来实现32位宽数据访问时的字节屏蔽控制。地址线与Bank选择SDRAM有两组地址引脚——行地址A0-A12和列地址A0-A8共享同一组引脚以及BA0/BA1Bank地址。FMC控制器会自动在行激活阶段送行地址在读写阶段送列地址软件里只需要配置FMC的地址映射之后操作就是在固定地址上读写。控制信号线FMC_SDCLKP2引脚接SDRAM的CLK时钟输入FMC_SDNCASP3接CAS列地址选通FMC_SDNRASP4接RAS行地址选通FMC_SDNEP5接CS片选FMC_SDNWRP6接WE写使能FMC_SDCKEP7接CKE时钟使能这些控制信号全部是FMC控制器内部状态机自动生成的用户不需要手动控制电平但硬件连接一处都不能错。3.2 电源与去耦设计电源设计是SDRAM稳定工作的基石。IS42S83200J的VDD为3.3VVDDQ也是3.3V这里有个细节VDD和VDDQ的波形质量直接影响高速读写时的信号完整性。我建议在VDD引脚附近放置100nF和1uF的MLCC电容VDDQ附近同样放置并且每个电源引脚都要有独立过孔到内层电源平面。CKE引脚上需要接一个100k下拉电阻到地这个在官方参考设计里常见目的是保证复位期间SDRAM处于禁用状态防止意外写入。另外SDRAM的VREF引脚如果有通常接VDDQ/2但IS42S83200J内部已有参考电压生成无需外部再分压。为了直观对比下面把电源设计要点整理成一个表电源/信号推荐接法说明VDD 3.3V100nF1uF去耦到地每个VDD引脚都加VDDQ 3.3V100nF1uF去耦到地保证输出驱动电源质量VSS/VSSQ全部接PCB地平面关键点不能遗漏SDCKE100k下拉电阻到地防止复位期间意外操作时钟信号串接22欧姆电阻抑制振铃和过冲3.3 时钟信号的细节SDRAM的时钟输入来自H745 FMC的SDCLK输出脚。这里我必须强调两个点第一SDCLK是高速信号频率在100MHz-143MHz之间靠近FMC引脚的地方应该串联一个22-33欧姆的电阻目的是做源端阻抗匹配。如果省掉这个电阻时钟线上的振铃会非常明显极端情况下会导致SDRAM状态机进入非法状态。第二个点是时钟线必须是点对点连接不要中途分支到其它器件。从H745的SDCLK引脚到SDRAM的CLK引脚路径越短越好尽量避免走过孔切换层。如果必须换层至少要在换层处增加一个地过孔为返回电流提供通路。4. FMC控制器初始化时序参数的原理与配置细节硬件焊接完接下来是软件初始化。SDRAM不是上电就能用的它有一套严格的初始化序列需要CPU按照特定顺序发出命令。ST的HAL库封装了这些操作但如果你不清楚内部逻辑遇到问题会很难入手。4.1 FMC SDRAM初始化流程分解整个初始化序列可以分为6个步骤发送NOP命令等待至少200us供电稳定时间对每个Bank执行预充电Precharge ALL执行至少8次自动刷新命令Auto Refresh配置模式寄存器Load Mode Register将刷新周期计时器写入FMC的刷新计数寄存器完成初始化开始正常读写顺序一定不能乱特别是200us的等待时间和预充电后的8次自动刷新少了任何一步SDRAM都会处于未知状态后面读写数据必然错乱。4.2 时序参数计算H745的FMC SDRAM控制器有几个关键的时序参数需要配置这些值必须根据SDRAM数据手册和系统时钟频率来算行激活到预充电周期tRASmin 42ns行激活到读写命令周期tRCDmin 18ns预充电命令周期tRPmin 18ns刷新周期刷新一行所需时间约66ns自刷新退出时间tXSRmin 70ns假设FMC外设时钟为120MHz一个时钟周期约8.33ns。tRCD需要18ns换算成时钟数是18/8.33 2.16向上取整为3个时钟。tRAS需要42ns42/8.33 5.04取6个时钟。tRP同理取3个时钟。SDCLK频率这里有个细节H745的FMC时钟是可以分频的但SDRAM控制器内部还有个固定行为就是SDCLK输出等于FMC内核时钟除以2。这个很多人不看手册容易漏掉。实际配置FMC时钟为240MHz时SDCLK输出就是120MHz正好满足IS42S83200J最高143MHz的规格还有余量。刷新计数器设置SDRAM要求4096行在64ms内刷新完所以每行刷新间隔为64ms/4096 15.625us。刷新计数寄存器里写入的值 (刷新间隔/SDCLK周期) - 1 15.625us/8.33ns - 1 1875。这个值太小会导致刷新过于频繁浪费带宽太大则可能造成SDRAM某行数据因延迟刷新而丢失。4.3 模式寄存器配置模式寄存器MR需要写入一些二进制位来定义SDRAM的工作方式。IS42S83200J的模式寄存器里突发长度Burst Length1、2、4、8可选突发类型顺序或交替CAS延迟2或3我实际使用中推荐设置为突发长度1Burst Length1 顺序访问 CAS3。为什么突发长度选1而不是8因为FMC控制器本身有自己的写入缓冲机制CPU单次读写时SDRAM侧的突发长度等于1就能覆盖大多数需求。突发长度8在FMC控制器中未必能得到有效利用反而可能增加预充电和激活的复杂度。CAS3比CAS2在某些场景下更稳定虽然参数上看起来慢一个时钟但对稳定性提升明显尤其是在频率偏高的边缘情况下。用HAL库时这些配置集中在SDRAM_HandleTypeDef结构体的Init成员里代码大概是FMC_SDRAM_CommandTypeDef command; /* Step 1: NOP command */ command.CommandMode FMC_SDRAM_CMD_NOP; command.CommandTarget FMC_SDRAM_CMD_TARGET_BANK1; command.AutoRefreshNumber 1; command.ModeRegisterDefinition 0; HAL_SDRAM_SendCommand(hsdram1, command, 0x1000); /* Wait for power supply stabilization */ HAL_Delay(1); /* Step 2: Precharge All */ command.CommandMode FMC_SDRAM_CMD_PRECHARGE_ALL; command.CommandTarget FMC_SDRAM_CMD_TARGET_BANK1; command.AutoRefreshNumber 1; command.ModeRegisterDefinition 0; HAL_SDRAM_SendCommand(hsdram1, command, 0x1000); /* Step 3: Auto Refresh (8 times) */ command.CommandMode FMC_SDRAM_CMD_AUTOREFRESH_MODE; command.CommandTarget FMC_SDRAM_CMD_TARGET_BANK1; command.AutoRefreshNumber 8; command.ModeRegisterDefinition 0; HAL_SDRAM_SendCommand(hsdram1, command, 0x1000); /* Step 4: Load Mode Register */ command.CommandMode FMC_SDRAM_CMD_LOAD_MODE; command.CommandTarget FMC_SDRAM_CMD_TARGET_BANK1; command.AutoRefreshNumber 1; command.ModeRegisterDefinition 0x230; /* Burst Length1, CAS3 */ HAL_SDRAM_SendCommand(hsdram1, command, 0x1000); /* Step 5: Set refresh rate counter */ HAL_SDRAM_SetRefreshCount(hsdram1, 1875);这段代码里要注意HAL_SDRAM_SendCommand的最后一个参数是超时时间单位为SDRAM时钟周期。这里填0x1000即4096个周期看起来是个很大的值实际运算下来也就几十微秒如果命令执行出错会超时返回错误方便调试。4.4 初始化过程中的典型错误初始化阶段最常见的错误是模式寄存器值写错。比如0x230这个值解析方式是二进制0010 0011 0000。其中第0-2位是突发长度000表示1第3位是突发类型0顺序第4-6位是CAS延迟011表示3第7位是操作模式0第8-9位是写突发长度00单点写。很多人照着某个参考工程抄芯片换了一颗不仔细复查模式寄存器配置导致读写不稳定或者彻底失败。每次换SDRAM型号都要重新对着数据手册确认每一位的含义不能想当然。5. PCB布局布线四大细节决定SDRAM能不能稳定跑满速软件配置再完美硬件布线如果出了问题性能一样上不去。SDRAM虽然不像DDR那样苛刻但也不是随便拉线就能跑的。我总结了这四个决定成败的细节按优先级排列。5.1 数据线等长控制在30mil以内FMC的数据总线D0-D31全部属于高速同源信号要求信号在同一个时钟边沿内被可靠采样。数据线和时钟线的长度差如果超过一定范围接收端采样窗口就会偏掉。我的经验标准是在双面板条件下同一组数据线之间的长度差控制在30mil约0.76mm以内数据线与时钟线的长度差控制在50mil以内。对于32位总线32根线全部等长到0.76mm并不难只要在画PCB时用等长网络统一约束即可。时序计算也可以用公式估算信号在FR4板材中的传输速度约6mil/ps30mil的时延差约为5ps相对于8ns的时钟周期来说毫无压力。但要注意的是如果布线经过多次换层过孔本身有约50ps的时延这会无形中增加差异所以尽量减少换层次数。5.2 地址/控制线组等长地址线和控制线RAS、CAS、WE、CS、CKE、CLK属于命令信号组约束比数据组稍微宽松但同一组内还是建议控制在100mil2.54mm以内。这里有个容易忽略的地方命令信号相对数据信号要有一定的建立时间。SDRAM控制器会在发出数据的同时提前一个时钟发出命令信号。命令信号到达SDRAM时数据信号还没稳定。所以命令线的绝对长度可以适度长一点但不要比数据线短太多工程上常用做法是让命令线略长于数据线50-100mil。5.3 完整地平面低成本高效果的稳压器SDRAM对参考地平面的依赖很重。数据总线在高低电平切换时会产生大量的瞬态回流电流。如果SDRAM正下方或信号层相邻平面是电源平面而不是地平面就会形成回流电流缺口增加环路电感表现出来就是串扰和地弹。我看过太多失败的案例开发板用双面板SDRAM底下全是信号线走线绕来绕去。短时间能用但温度稍微高一点或者SDCLK频率拉高就开始随机死机。布板原则是SDRAM正下方所有层至少要有一层连续地平面如果实在无法保证也要在地层上开大面积铺铜信号线只在底层走不要跨越任何分割区域。5.4 时钟线额外处理时钟线SDCLK是各路信号中频率最高、边沿最陡的信号。我在时钟线上会额外做两件处理一是源端串接22欧姆电阻二是包地处理。包地就是在时钟线两侧各走一条地线中间间隔2倍线宽左右用地过孔密集缝合。这个处理能把时钟信号的电磁辐射约束在局部区域对其他信号线的影响大幅下降。对于更高要求的场景时钟信号还可以参考DDR设计的做法加一个串联终端匹配电阻和一个并联到地的电容构成一个低通滤波网络虽然会稍微降低边沿速率但对信号完整性很有帮助。6. 实际调试实录从读写不稳定到跑通的完整排查链路硬件焊接完代码初始化通过并不意味着万事大吉。我几乎每次换一片板子调试SDRAM都要经历一轮看起来正常但使用时随机出错的折磨过程。这里把典型的调试经历拆开来讲你会惊讶于问题的多样性。6.1 第一轮初始化通过但校验失败刚上电HAL_SDRAM_Init()返回OK用DMA往SDRAM地址写0x55AA再读出来对比结果全是0x00。这个现象说明命令通道正常但数据通道没工作。排查思路先检查数据线的焊接确认没有虚焊然后检查FMC的DQM引脚是否连接正确。我用的IS42S83200J只有DQML和DQMH而H745的FMC分配了四个字节使能信号。我当时的电路把FMC_NBL0-3全部并联到SDRAM的DQML和DQMH上结果造成字节使能信号互相干扰读取数据时全变成了0x00。解决办法把FMC_NBL0和FMC_NBL1合并到一个DQML用二极管或逻辑门做隔离太麻烦干脆直接把两个信号短接。32位模式下FMC_NBL0和NBL1都是低有效同时有效时低电平是共存的所以短接后逻辑上没有冲突但要注意负载电容增加了好在频率即使到143MHz也扛得住。6.2 第二轮数据错位低字节跑到高字节改写0x55AA到地址0读出来是0xAA55。这个现象非常有意思看起来像数据总线接反了。实际上IS42S83200J是32位颗粒D0-D31直接对应FMC_D0-D31。我认为是软件问题果然发现是HAL库的FMC地址映射理解错了SDRAM的字节地址不是按字节计算的而是按32位字对齐的。如果往地址0x0写32位数据读出来应该还是0x0地址但我用指针时习惯性把地址当成字节地址加了1导致读到了下一个字的高字节。这类错误没有捷径只能一步一个脚印对照。给SDRAM做测试时建议先写几个测试向量固定地址固定数据验证基础通路再换递增地址测试地址线译码是否正常。6.3 第三轮长时间运行后偶发死机读写测试跑通了但系统运行几小时后随机崩溃。这种最让人头疼因为不稳定复现。用逻辑分析仪抓FMC总线后发现崩溃前总会出现一个异常的刷新命令。排查后确认原因是刷新计时器的值配错了——因为FMC基频我改过但刷新计数值还是按原来的频率算的。当时配的是120MHz SDCLK对应的1875而实际系统时钟改了之后SDCLK变为143MHz同样时间是1875换算成实际刷新间隔就从原来的15.6us变成了13.1us刷新太勤快了占用了大量总线带宽导致某些时间点CPU访问SDRAM时出现总线竞争冲突。按143MHz重新计算刷新计数值15.625us/7ns - 1 2232。改完之后问题消失。6.4 调试工具与技巧调试SDRAM强烈建议买一套ST-Link配合OpenOCD的MMIO调试功能可以直接在GDB里往SDRAM地址写数据然后读回比反复编译下载固件快得多。另一个趁手的工具是示波器主要抓SDCLK信号的边沿质量如果看到明显的过冲和振铃首先怀疑时钟线上的端接电阻值不合适。还有一个经验技能用FMC的DMA方式往SDRAM连续搬运大数据块同时用另一个定时器中断统计搬运耗时。如果搬运耗时有明显抖动大概率是SDRAM刷新与DMA访问之间的总线冲突恒定时长则说明时序健康。这个测试比单纯读写校验更能暴露性能层面的隐患。7. 性能验证与长期运行稳定性我最终跑到的状态板子调通后我对这套方案做了完整的性能和稳定性验证这些数据可以给你做设计参考。7.1 读写带宽实测用H745的FMC控制器向SDRAM做32位DMA连续写入SDCLK设在120MHz时实测写带宽约95MB/s读带宽约88MB/s。理论上SDCLK 120MHz乘4字节峰值带宽应该是480MB/s但实际受限于SDRAM刷新开销和FMC控制器的命令间隙能跑到峰值带宽的20%-25%左右已经算健康水平。如果应用对带宽要求更高可以开启FMC的FIFO功能调整突发访问模式实测能把写入带宽提升到110MB/s左右但对时序要求更严格需要确保布线质量过关。7.2 长时间稳定性测试稳定性测试推荐用以下策略用M7核心跑一个256KB的读写循环不断写入递增数据再校验用M4核心同时跑一个音频处理任务频繁访问SDRAM单次运行时间至少72小时我跑到72小时后没有出现一次校验失败SDRAM的刷新和双核并发访问都表现稳定。测试条件的温度为室温SDCLK为120MHz。如果产品要在高温环境工作建议把SDCLK降到100MHz以下并把刷新计数值相应调整这样会留出更多时序裕量。7.3 功耗与温升参考IS42S83200J在120MHz下运行功耗大约在50-80mA量级。加上H745本身整个系统的SDRAM部分温升大约在15度左右从室温到稳定温度。这个数据对多数产品来说完全可以接受但如果做便携式低功耗设计建议考虑在待机模式时将SDCLK关闭或者让FMC进入自刷新模式能省掉小半电流。8. 进阶建议与后续扩展方向调试完成之后这套参考设计可以根据实际项目需求做进一步扩展这里分享几个我试过的方向。8.1 结合安全固件升级使用SDRAMOTA在线升级产品时经常需要先将接收到的固件暂存再写入Flash。32MB的SDRAM足够存放好几个版本的固件镜像可以用一个简单的块校验方法先完整校验再写入Flash避免升级中途断电导致Flash半写状态。这个应用充分利用了SDRAM的大容量且不占用宝贵的内部Flash空间。8.2 利用双核构架同时访问SDRAMH745的M7和M4可以通过FMC同一套SDRAM接口访问外挂存储器但需要注意总线冲突。我的做法是把SDRAM地址空间划分为两个区域M7核心使用低16MBM4核心使用高16MB。两个核各自访问不同的Bank地址从物理上避免频繁的仲裁冲突。如果两个核必须共享数据可以约定用内部SRAM做邮箱传递指针而不是大量数据拷贝大幅提高效率。8.3 使用SDRAM做GUI显存时的帧缓冲策略用SDRAM做GUI帧缓冲可以将多个显示层都放在SDRAM里。我的实践经验是如果LTDC时钟和FMC时钟分频设置不当像素读取会产生抖动。建议将FMC的刷新周期与LTDC的行扫描周期错开或者用DMA2D先将数据从SDRAM搬移到内部SRAM再由LTDC从内部SRAM读取可以明显降低画面撕裂。我的最终建议是STM32H745 IS42S83200J这套组合是从成本、性能、开发难度三方面权衡后非常稳妥的SDRAM扩展方案。只要初始化时序按数据手册算准电源和布线的几个关键点做到位市面上绝大多数基于H7的应用都能稳定跑起来。如果后续遇到读写不稳定问题优先检查供电和时钟质量再检查布线等长八成以上的问题都在这里而不要一开始就去怀疑芯片本身。
返回列表