将STM32F407片外SRAM作运行内存
本例演示用的软硬件:
- 片内外设驱动库:STM32CubeF41.24.1的HAL库1.7.6,2019年4月12日
- IDE:MDK-ARM 5.28.0.0,2019年5月
- 开发板:片外SRAM挂在FSMC_NORPSRAM3,16bit×219=1MiB
本例的目的是让编程人员使用片外SRAM就像使用片内SRAM一样,即不用把任何变量声明到指定的RAM地址、连接器也能自动地把片外SRAM作为变量的存储空间
如果把所有需要被放到片外SRAM的变量用__attribute__((at()))、指针等声明到片外SRAM,那么完全不用像本例这样
执行main()前执行片内Flash上初始化FSMC及其GPIO的指令:
- 有些指令由启动文件的汇编代码生成,例如对于本例的STM32F407ZG来说这个启动文件就是startup_stm32f407xx.s(默认版本位于STM32CubeF4\Drivers\CMSIS\Device\ST\STM32F4xx\Source\Templates\arm)
- 有些函数在system_stm32f4xx.c(位于STM32CubeF4\Drivers\CMSIS\Device\ST\STM32F4xx\Source\Templates\)
对于本例的STM32F407来说修改上述的2个源文件的方法是:
- 换用官方的使用片外SRAM作运行内存的例程的启动文件,例如STM32CubeF4\Projects\STM324xG_EVAL\Examples\FSMC\FSMC_SRAM_DataMemory\MDK-ARM\startup_stm32f407xx.s
可以看到适用于使用片外SRAM运存的启动文件相较于默认版本的启动文件变化的地方有
- 第52行:定义用于初始化片外SRAM的栈
- 第75行:让栈顶指针指向第52行定义的栈
- 第191行~第192行:在执行main()前、执行完启动文件定义的指令后将栈顶指针恢复为默认值
__initial_spTop EQU 0x20000400 ; stack used for SystemInit & SystemInit_ExtMemCtl
__Vectors DCD __initial_spTop ; Top of Stack
LDR R0, =__initial_sp ; restore original stack pointer
MSR MSP, R0
- 取消注释system_stm32f4xx.c的第96行
/************************* Miscellaneous Configuration ************************/
/*!< Uncomment the following line if you need to use external SRAM or SDRAM as data memory */
#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)\
|| defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
|| defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx)
/* #define DATA_IN_ExtSRAM */
#endif /* STM32F40xxx || STM32F41xxx || STM32F42xxx || STM32F43xxx || STM32F469xx || STM32F479xx ||\
STM32F412Zx || STM32F412Vx */
那么system_stm32f4xx.c的
- 第662行~第716行
- 开启FSMC模块用到的GPIO的时钟(第662行)
- 配置相应GPIO口的模式、速度等信息(第667行~第712行)
- 开启FSMC模块的时钟(第716行))
- 第737行~第741行
- 配置FSMC_NORPSRAM的控制、时序(第739行~第741行)
都会被执行
#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)\
|| defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
|| defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx)
#if defined(DATA_IN_ExtSRAM)
/*-- GPIOs Configuration -----------------------------------------------------*/
/* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */
RCC->AHB1ENR |= 0x00000078;
/* Delay after an RCC peripheral clock enabling */
tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIODEN);
/* Connect PDx pins to FMC Alternate function */
GPIOD->AFR[] = 0x00CCC0CC;
GPIOD->AFR[] = 0xCCCCCCCC;
/* Configure PDx pins in Alternate function mode */
GPIOD->MODER = 0xAAAA0A8A;
/* Configure PDx pins speed to 100 MHz */
GPIOD->OSPEEDR = 0xFFFF0FCF;
/* Configure PDx pins Output type to push-pull */
GPIOD->OTYPER = 0x00000000;
/* No pull-up, pull-down for PDx pins */
GPIOD->PUPDR = 0x00000000;
/* Connect PEx pins to FMC Alternate function */
GPIOE->AFR[] = 0xC00CC0CC;
GPIOE->AFR[] = 0xCCCCCCCC;
/* Configure PEx pins in Alternate function mode */
GPIOE->MODER = 0xAAAA828A;
/* Configure PEx pins speed to 100 MHz */
GPIOE->OSPEEDR = 0xFFFFC3CF;
/* Configure PEx pins Output type to push-pull */
GPIOE->OTYPER = 0x00000000;
/* No pull-up, pull-down for PEx pins */
GPIOE->PUPDR = 0x00000000;
/* Connect PFx pins to FMC Alternate function */
GPIOF->AFR[] = 0x00CCCCCC;
GPIOF->AFR[] = 0xCCCC0000;
/* Configure PFx pins in Alternate function mode */
GPIOF->MODER = 0xAA000AAA;
/* Configure PFx pins speed to 100 MHz */
GPIOF->OSPEEDR = 0xFF000FFF;
/* Configure PFx pins Output type to push-pull */
GPIOF->OTYPER = 0x00000000;
/* No pull-up, pull-down for PFx pins */
GPIOF->PUPDR = 0x00000000;
/* Connect PGx pins to FMC Alternate function */
GPIOG->AFR[] = 0x00CCCCCC;
GPIOG->AFR[] = 0x000000C0;
/* Configure PGx pins in Alternate function mode */
GPIOG->MODER = 0x00085AAA;
/* Configure PGx pins speed to 100 MHz */
GPIOG->OSPEEDR = 0x000CAFFF;
/* Configure PGx pins Output type to push-pull */
GPIOG->OTYPER = 0x00000000;
/* No pull-up, pull-down for PGx pins */
GPIOG->PUPDR = 0x00000000;
/*-- FMC/FSMC Configuration --------------------------------------------------*/
/* Enable the FMC/FSMC interface clock */
RCC->AHB3ENR |= 0x00000001;
#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx)\
|| defined(STM32F412Zx) || defined(STM32F412Vx)
/* Delay after an RCC peripheral clock enabling */
tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FSMCEN);
/* Configure and enable Bank1_SRAM2 */
FSMC_Bank1->BTCR[] = 0x00001011;
FSMC_Bank1->BTCR[] = 0x00000201;
FSMC_Bank1E->BWTR[] = 0x0FFFFFFF;
- 更正system_stm32f4xx.c的上述代码
(再次提醒没仔细读题的读者:下文的代码只被保证适用于( (STM32F407ZG) && (片外SRAM挂在FSMC_NORPSRAM3) && (片外SRAM是16bit×219=1MiB) )的情况,且应该根据你用的SRAM芯片、STM32的AHB总线时钟频率等信息修改第739行~第741行配置FSMC寄存器用的值。用上一段提到的方法获取适用于你的开发板的寄存器值,用本文初提到的方法获取适用于你的单片机的启动文件):
#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)\
|| defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
|| defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx)
#if defined(DATA_IN_ExtSRAM)
/*-- GPIOs Configuration -----------------------------------------------------*/
/* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */
RCC->AHB1ENR |= 0x00000078;
/* Delay after an RCC peripheral clock enabling */
tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIODEN);
/* Connect PDx pins to FMC Alternate function */
GPIOD->AFR[] = 0x00CC00CC;
GPIOD->AFR[] = 0xCCCCCCCC;
/* Configure PDx pins in Alternate function mode */
GPIOD->MODER = 0xAAAA0A0A;
/* Configure PDx pins speed to 100 MHz */
GPIOD->OSPEEDR = 0xFFFF0F0F;
/* Configure PDx pins Output type to push-pull */
GPIOD->OTYPER = 0x00000000;
/* No pull-up, pull-down for PDx pins */
GPIOD->PUPDR = 0x00000000;
/* Connect PEx pins to FMC Alternate function */
GPIOE->AFR[] = 0xC00000CC;
GPIOE->AFR[] = 0xCCCCCCCC;
/* Configure PEx pins in Alternate function mode */
GPIOE->MODER = 0xAAAA800A;
/* Configure PEx pins speed to 100 MHz */
GPIOE->OSPEEDR = 0xFFFFC00F;
/* Configure PEx pins Output type to push-pull */
GPIOE->OTYPER = 0x00000000;
/* No pull-up, pull-down for PEx pins */
GPIOE->PUPDR = 0x00000000;
/* Connect PFx pins to FMC Alternate function */
GPIOF->AFR[] = 0x00CCCCCC;
GPIOF->AFR[] = 0xCCCC0000;
/* Configure PFx pins in Alternate function mode */
GPIOF->MODER = 0xAA000AAA;
/* Configure PFx pins speed to 100 MHz */
GPIOF->OSPEEDR = 0xFF000FFF;
/* Configure PFx pins Output type to push-pull */
GPIOF->OTYPER = 0x00000000;
/* No pull-up, pull-down for PFx pins */
GPIOF->PUPDR = 0x00000000;
/* Connect PGx pins to FMC Alternate function */
GPIOG->AFR[] = 0x00CCCCCC;
GPIOG->AFR[] = 0x00000C00;
/* Configure PGx pins in Alternate function mode */
GPIOG->MODER = 0x00200AAA;
/* Configure PGx pins speed to 100 MHz */
GPIOG->OSPEEDR = 0x00300FFF;
/* Configure PGx pins Output type to push-pull */
GPIOG->OTYPER = 0x00000000;
/* No pull-up, pull-down for PGx pins */
GPIOG->PUPDR = 0x00000000;
/*-- FMC/FSMC Configuration --------------------------------------------------*/
/* Enable the FMC/FSMC interface clock */
RCC->AHB3ENR |= 0x00000001;
#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx)\
|| defined(STM32F412Zx) || defined(STM32F412Vx)
/* Delay after an RCC peripheral clock enabling */
tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FSMCEN);
/* Configure and enable Bank1_SRAM3 */
FSMC_Bank1->BTCR[] = 0x00001091;
FSMC_Bank1->BTCR[] = 0x0FFFFFFF;
- 在MDK把FSMC_NORPSRAM3映射的地址范围0x68000000~0x6BFFFFFF的首1M设为运行内存
把0x68000000、0x100000分别填入下图窗口右下角的"Read/Write Memory Areas"的”off-chip“的任一行:

修改完后Reuild(注意:MDK-ARM可能不知道用户修改了哪些文件,所以如果仅Build,那么IDE可能会拿编译旧版本的源文件得到的目标文件进行连接)
从MAP文件可以看到,变量被分配到了片外SRAM映射的地址范围0x68000000~0x68100000中,且单片机程序能正常运行
希望CubeMX以后的版本能自动将片外RAM设为运存
将STM32F407片外SRAM作运行内存的更多相关文章
- STM32片外SRAM作运行内存
本例演示用的软硬件: 片内外设驱动库:STM32CubeF41.24.1的HAL库1.7.6,2019年4月12日 IDE:MDK-ARM 5.28.0.0,2019年5月 开发板:片外SRAM挂在F ...
- JS画几何图形之六【过直线外一点作垂线】
样例:http://www.zhaojz.com.cn/demo/draw10.html 依赖:[点].[直线] //过直线外一点画垂线 function drawVerticalLine(point ...
- JS画几何图形之五【过圆外一点作切线】
样例:http://www.zhaojz.com.cn/demo/draw9.html 依赖:[点].[直线].[圆] //画切线 //point 圆外的一点 //dot 圆心 //r 半径 func ...
- MT【45】抛物线外一点作抛物线的切线(尺规作图题)
注1:S为抛物线焦点 注2:由切线的唯一性,以及切线时可以利用MT[42]评得到三角形全等从而得到切线平分$\angle MQS$得到
- STM32F103片外运行代码分析
STM32F103片外运行代码分析 STM32F103有三种启动方式: 1.从片内Flash启动: 2.从片内RAM启动: 3.从片内系统存储器启动,内嵌的自举程序,用于串口IAP. 无法直接在片外N ...
- DSP28335的XINTF操作SRAM实验
1. 本次使用三兄弟的XDS28335开发板,研究一下XINTF操作SRAM的代码.哈弗结构,奇怪,DSP28335是哈弗结构,那么数据和程序空间应该独立的,为啥书上说采用统一的寻址方式?估计只是读写 ...
- 第51章 设置FLASH的读写保护及解除—零死角玩转STM32-F429系列
第51章 设置FLASH的读写保护及解除 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.co ...
- EasyUI-panel 内嵌页面上的js无法被执行
声明: http://www.jeasyuicn.com/post-49.html 本文引用自GodSon的杰作 http://www.jeasyuicn.com/post-49.html,除修正了个 ...
- Chrome Apps將是Google送給微軟的特洛伊木馬?
今天,Google 發表了 Chrome Apps,不同於之前 web app,此舉是要把 Chrome 瀏覽器升級為真正的 app 平台,將 Chrome OS 發展成一個成熟的作業系統,可以視為 ...
随机推荐
- 迷你PS小程序-集成的开放式画报、油墨电子签名、图片拖拽可单独食用
米娜桑,哦哈哟~ 个人制作,该文章主要讲解最近基于uni-app框架编写的集图文拖拽等多方位编辑.油墨电子签名.开放式海报于一体的小程序的制作思路和实现代码. 目录 1.完整源码链接 2.实现思路 3 ...
- 通过例子学习C++(二)最小公倍数
本文是通过例子学习C++的第二篇,通过这个例子可以快速入门c++相关的语法. 题目要求:输入两个整数,求其最小公倍数. 解答方法一:两个数的最小公倍数,是这两个数中的大数,或者是这2个数的倍数中的最小 ...
- 【转】ArcGIS Server 站点架构-Web Adaptor
GIS 服务器内置了Web服务器,如果我想用我自己企业内部的服务器,该怎么做? 多个GIS服务器集群又如何做? …… 有问题,说明我们在思考,这也是我们希望看到的,因为只有不断的思考,不断的问自己为什 ...
- Git创建远程分支并提交代码到远程分支
1.可以在VS中新建分支 2.可以通过git branch -r 命令查看远端库的分支情况 这些红色都是远程的分支 3.从已有的分支创建新的分支(如从master分支),创建一个dev分支 (不用vs ...
- AVR单片机教程——PWM调光
本文隶属于AVR单片机教程系列. PWM 两位数码管的驱动方式是动态扫描,每一位都只有50%的时间是亮的,我们称这个数值为其占空比.让引脚输出高电平点亮LED,占空比就是100%. 在驱动数码管时 ...
- [bzoj2668] [洛谷P3159] [cqoi2012] 交换棋子
Description 有一个n行m列的黑白棋盘,你每次可以交换两个相邻格子(相邻是指有公共边或公共顶点)中的棋子,最终达到目标状态.要求第i行第j列的格子只能参与mi,j次交换. Input 第一行 ...
- 「 从0到1学习微服务SpringCloud 」02 Eureka服务注册与发现
系列文章(更新ing): 「 从0到1学习微服务SpringCloud 」01 一起来学呀! Spring Cloud Eureka 基于Netflix Eureka做了二次封装(Spring Clo ...
- mongoskin 是让 Node.js 支持 MongoDB 的内嵌访问层。
mongoskin 是让 Node.js 支持 MongoDB 的内嵌访问层.
- SpringBoot简单实现登录功能
登陆 开发期间模板引擎页面修改以后,要实时生效 1).禁用模板引擎的缓存 # 禁用缓存 spring.thymeleaf.cache=false 2).页面修改完成以后ctrl+f9:重新编译: 登陆 ...
- Qt下Eigen矩阵函数库的添加
第1步: 下载一个Eigen文件包,在官网下即可: http://eigen.tuxfamily.org/index.php?title=Main_Page 第2步: 用Qt随便建一个GUI工程,在. ...