屏幕上的程序因为内存不足再次卡死,老张盯着眼前闪烁的STM32开发板,终于下定决心要给这个“小脑瓜”配个“大内存”。
很多人以为STM32单片机的片上SRAM就是全部可用内存了,当项目涉及GUI界面、图像处理或大量数据缓存时,才发现那几百KB的SRAM真是捉襟见肘-3。这时候,给STM32扩展外部SDRAM就成了性价比最高的解决方案。

现在的嵌入式项目越来越复杂,一个稍微好看点的用户界面,几帧图像数据就能把STM32片内SRAM撑满-3。片内SRAM速度快但容量有限,而外部SDRAM容量能以百MB计,价格还更便宜-1。

选择SDRAM而不是SRAM扩展内存,主要是“容量/价格”比的优势-1。
STM32的内部存储结构很特别,像H7系列就分了多个域和多种RAM,但即使这样,当需要处理视频帧或大型缓存时,外接SDRAM几乎是必然选择-3。
SDRAM属于DRAM的一种,工作时需要与CPU时钟同步,数据读写按时钟节拍进行-3。它需要定期刷新才能保持数据,这是它与SRAM的主要区别之一-8。
要给STM32扩展外部存储器,得靠一个叫FMC的控制器。这个“可变静态存储控制器”能连接多种外部存储器-2。
对于SDRAM,STM32H7系列通过FMC接口进行控制-3。FMC的一端通过内部高速总线连接到ARM内核,另一端则面向扩展存储器-2。
它负责把内核的访问信号转换成符合外部存储器通信规约的信号-2。
FMC支持同时扩展多种存储器,当系统中使用多个外部存储器时,它会通过总线悬空延迟时间参数的设置,防止访问冲突-2。
有意思的是,FMC管理着1GB的映射地址空间,这个空间被划分为4个独立的存储块,每个块支持独立的时序配置-2。
SDRAM内部结构挺有意思,它不是简单的一堆存储单元。你可以把它想象成一个由多个表格组成的图书馆-1。
每个表格就是一个Bank,要找到特定数据,得先确定Bank号,再找行地址,最后找列地址-1。这就是为什么SDRAM有BA线选择Bank,A线则行列地址共用-1。
SDRAM的存储原理是利用电容存储电荷来表示数据,电容会漏电,所以需要定期“刷新”-3。通常每隔64ms就要对所有行进行一次刷新操作-1。
刷新期间所有Bank都停止工作,这会对性能造成影响,但这是DRAM特性决定的,也是它成本优势的代价-1。
控制SDRAM需要一整套命令:行有效、列读写、预充电、刷新等-1。预充电是关闭当前工作行,准备打开新行的操作-1。
连接STM32与SDRAM需要不少引脚,除了常规的地址线、数据线,还有一些专门的控制信号线。
CLK是同步时钟信号,所有输入信号都在CLK上升沿被采集-1。CKE是时钟使能信号,禁止时钟时SDRAM会启动自刷新操作-1。
CS是片选信号,低电平有效;CAS和RAS分别是列地址和行地址选通-1。WE是写入使能,低电平时才能写入数据-1。
DQM线特别重要,它用于数据输入/输出掩码,可以控制哪些数据线有效-1。比如传输8位数据时,可以用DQM线屏蔽掉高8位,防止误修改-1。
实际连接时,FMC的数据线FSMC_D[15:0]对应SDRAM的数据引脚,地址线也要对应连接-2。根据芯片规格不同,可能需要连接多达几十个引脚。
硬件连接好了,接下来得让STM32认识这片新内存。首先要配置FMC的寄存器,告诉控制器连接的是什么类型的存储器-2。
对于SDRAM,需要设置存储器类型、数据线宽度(通常是16位或32位)、时序参数等-2。时序配置特别关键,包括地址建立时间、数据建立时间等-2。
刷新定时也得仔细配置,SDRAM需要周期性刷新才能保持数据,刷新周期通常为64ms-1。刷新操作分为自动刷新和自我刷新,后者主要用于低功耗状态-1。
初始化SDRAM有一套标准流程:先是加载模式寄存器,然后进行预充电,再执行多个自动刷新周期,最后设置刷新计数器-1。
配置完成后,外部SDRAM就会被映射到STM32的地址空间中,可以像访问内部内存一样使用它-2。对于STM32H7,可以使用现成的库函数来简化初始化过程-4。
成功扩展SDRAM后,怎么在程序里用好它?首先要合理规划内存布局,确定哪些数据放片内SRAM,哪些放外部SDRAM。
片内SRAM速度更快,应该留给对速度要求高的任务,比如中断服务程序中的变量、经常访问的数据-3。外部SDRAM容量大,适合存放大块数据,如图像缓冲区、音频数据、文件系统缓存等。
使用外部SDRAM时要注意数据对齐和访问模式。尽量使用连续的大块数据传输,减少随机小数据访问,这样可以提高效率-3。
对于需要频繁访问的数据,可以考虑在片内SRAM中设置缓存,减少对外部SDRAM的访问次数-3。也可以通过DMA来搬运数据,减轻CPU负担-3。
在链接脚本中,可以指定不同段的位置,比如将大数组放在外部SDRAM区域。C语言中,可以使用特定修饰符或通过指针直接访问外部内存地址。
调试外部SDRAM时,经常会遇到各种问题。最常见的是初始化失败,这时候要仔细检查硬件连接和时序配置。
如果系统不稳定,可能是刷新配置不当。SDRAM必须定期刷新,刷新周期太大会导致数据丢失,太小则影响性能-1。
另一个常见问题是数据错误,可能是地址线或数据线连接问题,也可能是时序不匹配。可以尝试降低时钟频率,看看问题是否改善。
电源质量也很关键,SDRAM对电源噪声比较敏感,确保电源稳定并加上适当的去耦电容-1。还要注意信号完整性,特别是高速时钟信号。
调试时可以先用简单测试模式,如写入固定模式再读回验证。也可以使用STM32的存储器接口调试工具,检查实际波形和时序。
STM32外扩SDRAM后,老张的开发板轻松跑起了彩色触摸界面,实时显示传感器数据波形图,还能缓存长达半小时的日志数据。那片小小的SDRAM芯片静静站在电路板角落,里面却装着整个系统的活力源泉。