打印
[APM32F4]

APM32F407 局部和全局变量全部都放在外部SDRAM方法

[复制链接]
377|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Peixu|  楼主 | 2024-12-4 12:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 Peixu 于 2024-12-4 12:14 编辑

在使用APM32F407微控制器时,内存管理是一个重要的问题。特别是在需要大量数据存储的应用中,当内部SRAM不够用的时候,可以使用外部SDRAM来存放。本文将详细介绍如何在APM32F407中将局部和全局所有变量存储在外部SDRAM,包括使用内部SRAM作为栈的初始化、SDRAM的配置、以及在跳转到main函数之前重新设置堆栈指针(SP)的步骤。
1. 使用内部SRAM初始化栈
在微控制器启动时,堆栈指针(SP)默认指向内部SRAM的某个地址。一般来说,我们可以将其设置为内部SRAM的最高地址,以便为后续的栈操作留出充足的空间。
; Reset handler
Reset_Handler PROC
    EXPORT  Reset_Handler             [WEAK]
    ; 设置堆栈指针的初始值
    LDR     SP, =0x20001000          ; 将堆栈指针设置为内部SRAM中的一个地址
    ; 继续调用系统初始化
    IMPORT  SystemInit
    LDR     R0, =SystemInit
    BLX     R0                       ; 调用系统初始化函数
    ENDP

2. SDRAM的初始化
在执行任何应用逻辑之前,我们需要确保SDRAM能够正常工作。这涉及到SDRAM控制器的初始化。通常,这个过程包括配置SDRAM的时序参数、刷新率等,以确保SDRAM可以稳定运行。
#include "apm32f4xx_sdram.h"
// SDRAM初始化函数
void SDRAM_Init(void) {
    // 配置SDRAM控制器的参数
    // 具体配置请参考数据手册
}


3. 修改分散链接文件
为了将变量存储在外部SDRAM中,我们需要修改分散文件,将RW_IRAM1的地址指向SDRAM的起始地址。以下是修改后的分散文件示例:
LR_IROM1 0x08000000 0x00100000  {
    ER_IROM1 0x08000000 0x00100000  {
        *.o (RESET, +First)         ; 加载重置向量
        *(InRoot$Sections)         ; 加载根节
        .ANY (+RO)                  ; 只读区域
        .ANY (+XO)                  ; 扩展区域
    }
    RW_IRAM1 0x60000000 0x00200000  {  ; 外部SDRAM的起始地址
        .ANY (+RW +ZI)              ; 可读可写区域
    }
}


4. 在.S文件中初始化SDRAM
在汇编文件中,我们需要在__main函数调用之前初始化SDRAM。这样可以确保在分散加载代码执行之前,SDRAM已经处于可用状态,从而允许正确地初始化位于SDRAM中的变量。
; SDRAM初始化
    IMPORT SDRAM_Init
    LDR     R0, =SDRAM_Init
    BLX     R0                       ; 调用SDRAM初始化函数
5. 设置堆栈指针指向SDRAM
在SDRAM初始化完成后,我们需要将堆栈指针(SP)重新设置为指向SDRAM的地址。这是为了确保后续的堆栈操作能够使用SDRAM作为栈空间。
    LDR     SP, =0x60000000         ; 将堆栈指针设定为SDRAM的起始地址

6. 确保数据能够初始化
在使用SDRAM之前,分散加载代码会从FLASH中将RW-data复制到RAM中,并为ZI-data开辟空间并初始化为0。为了确保SDRAM中的变量能够正常初始化,我们可以将初始化代码放在Reset_Handler的最后部分,以确保SDRAM可用。
7. 完整的Reset_Handler示例
以下是一个完整的Reset_Handler示例,结合了以上的步骤:
; Reset handler
Reset_Handler PROC
    EXPORT  Reset_Handler             [WEAK]
    IMPORT  SystemInit
    IMPORT  __main
    IMPORT  SDRAM_Init
    ; 初始化堆栈指针
    LDR     SP, =0x20001000          ; 设置堆栈指针
    ; 调用系统初始化
    LDR     R0, =SystemInit
    BLX     R0
    ; 初始化SDRAM
    LDR     R0, =SDRAM_Init
    BLX     R0                       ; 初始化SDRAM
    ; 设置堆栈指针指向SDRAM
    LDR     SP, =0x60000000         ; 将堆栈指针指向SDRAM的起始地址
    ; 跳转到主函数
    LDR     R0, =__main
    BX      R0                       ; 跳转到主函数
ENDP

8. 总结
通过上述步骤,您可以成功地在APM32F407微控制器上实现将变量存储在外部SDRAM中。首先,在启动时使用内部SRAM进行堆栈初始化;然后,初始化SDRAM,并确保在执行分散加载代码之前SDRAM已经处于可用状态;最后,将堆栈指针设置为SDRAM的起始地址。这样,您的应用程序就能够高效地使用外部SDRAM的内存资源。
这种方法特别适用于需要处理大量数据的场景,如图像处理、通信协议等。希望这篇文章能够帮助您更好地理解。

使用特权

评论回复
沙发
guijial511| | 2024-12-4 19:19 | 只看该作者
直接把RAM存储空间地址映射到外部SDRAM

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

28

主题

54

帖子

0

粉丝