STM32操作外部SRAM
转载自:
外部SRAM实验,让STM32的外部SRAM操作跟内部SRAM一样
http://www.openedv.com/thread-47895-1-1.html
(出处: OpenEdv-开源电子网)
前几天看到论坛有人在问这个问题,我特意去做了这个实验,这样用外部SRAM就跟用内部SRAM一样,不用自己去申请内存,也不用考虑什么内存地址,一切让编译器自己去解决。
废话不多说,我直接拿原子哥的战舰开发板库函数版的外部SRAM实验来修改。在库函数的system_stm32f10x.c这个初始化文件当中其实就已经有外部SRAM的初始化,我们只要增加“#define DATA_IN_ExtSRAM 1”这句宏定义
1
2
3
4
|
#if defined (<a href="http://openedv.taobao.com" target="_blank" class="relatedlink">STM32F1</a>0X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL) /* #define DATA_IN_ExtSRAM */ #define DATA_IN_ExtSRAM 1 #endif |
再编译的时候就会把外部SRAM的初始化编译进去,初始化的代码大家可以去看文件中的void SystemInit_ExtMemCtl(void) 这个函数。然后我们在工程设置那里把外部SRAM地址增加进去,如下图
<ignore_js_op>
修改启动文件中的中的第39行,把__initial_sp 修改成 __initial_sp EQU 0x20000000 + Stack_Size
<ignore_js_op>
然后我们把Main中的testsram中的地址去掉,让编译器自己去指定地址 <ignore_js_op>
再把原子哥的外部SRAM的初始化注释掉,因为前面已经在System_init已经初始化了。其实这里我们可以把原子的SRAM.c文件去掉不用它了,我这里没去掉,其实只是为了能正常调用fsmc_sram_test()来测试实验结果
<ignore_js_op>
到这里我们可以编译了,下载到开发板,我们就可以看到实验结果
<ignore_js_op>
我们继续深入点,看看testsram[]这个大数组到处编译在到哪里去了,用IDA64来反汇编下编译出来的AXF文件
<ignore_js_op>
可以看到testsram这个大数组自动编译到外部sram的0x68000000这个地址上。我们再试试再定义几个大数组看看
<ignore_js_op>
再来看看编译后的结果
<ignore_js_op>
可以看到每个大数组都由编译器自己分配了内存的地址,压根不用我们自己去定义。
到这里相信大家会有一个疑问,那编译是怎么来决定把哪些变量定义在内部SRAM,那些定义在外部SRAM。这一点我也研究清楚,我只知道编译会优先把变量都定义外部SRAM,当外部SRAM不够用情况才会定义在内部SRAM上,至于怎么让编译优先使用内部SRAM,我也没有搞明白。目前我能做到的是把已经初始化的全局变量都放在SRAM,做法是修改散列文件,让RW只在内存SRAM上编译。
<ignore_js_op>
去掉小红框的勾,然后点击Edit我们来修改SRAM.sct文件,也就是编译散列文件
<ignore_js_op>
把RW_RAM1中(也就是外部SRAM)的+RW去掉,这样已经初始化的全局变量就只会编译在内部SRAM中
<ignore_js_op>
重新编译下工程,再来反汇编下看看编译结果
<ignore_js_op>
可以看到usmart_nametab[]这个已经初始化的数组编译在内部SRAM上,adc2[]这个未初始化的数组,数组的大小比较而且能在内部Sram编译得下的,却还是编译在外部SRAM上。
最后散列相关的知识,大家可以看看这里http://blog.csdn.net/lindabell/article/details/8957968#0-qzone-1-11984-d020d2d2a4e8d1a374a433f596ad1440
前面没有修改启动文件,其它变量全部在内部SRAM的时候,程序运行是没有问题,减小数组的时候程序运行不起来,修改前面的红字部分后,程序就可以运行起来,但是LCD偶尔正常,偶尔不正常,调试下感觉是延时的问题,没有再继续调试了