MCU-SDRAM-W9825G6KH的存储单元

ARM-M7的Memory架构:

在Cortex-M7中,存储器一共有4GB的地址空间,4GB的地址空间又被划分为8个区域块,每个块有512M的内存。

Note:4GB的地址空间为 0x0000 0000 - 0xFFFF FFFF,可寻址的512M的地址空间为 0x0000 0000 - 0x1FFF FFFF,可寻址的地址是指处理器可以直接访问和寻址的存储区域,如flash,SRAM,寄存器。

外部External RAM 通常映射到0x6000_0000到0x9FFF_FFFF的外部存储区域。

为何Cortex-M7外部Memory Region仅1GB,却能扩展更大SDRAM(8GB)?

通过址复用与Bank切换:复用地址线和切换存储体(Banks),1GB逻辑地址空间可管理更大的物理内存,但需软件参与地址管理。(可以理解为通过MMU实现物理地址与逻辑地址的切换)Cortex-M7的外部RAM的1GB地址空间是​逻辑地址空间,SDRAM是物理地址,软件通过控制BA0/BA1和RAS/CAS信号,动态切换不同的物理存储区域。

从 FMC 的角度,外部存储器被划分为固定大小的存储区域,每个存储区域的大小为 256 MB, Cortex-M7支持4个FMC,实际连接的SDRAM芯片容量可以小于或等于 256MB,只要不超过该区域的大小。

举例W9825G6KH:

根据数据手册,SDRAM一共有4个Bank,每个Bank有4M world的内存,每个world有16bit的数据宽度,相等于数据线的数量。SDRAM的实际内存是32M(4 bank * 4M world * 2 byte)

W9825G6KH 的一个bank存储结构为:行地址:8192 个;列地址: 512 个(8192*512*16bit=8M)

在 SDRAM 内部寻址的时候,先指定 BANK 号和行地址,然后再指定列地址,就可以查找到目标地址。

硬件连接:

地址空间映射:W9825G6KH 的 32MB 映射到 FMC 的 Bank1(0xC0000000 ~ 0xC1FFFFFF),剩余地址未使用。也就是逻辑地址直接mapping物理地址,不需要软件实现复杂管理(不超过256MB)

代码实现:

​
#include "stm32h7xx_hal.h"
#include "main.h"

#define SDRAM_BASE_ADDR    0xC0000000
#define SDRAM_SIZE         (32 * 1024 * 1024) // 32MB

SDRAM_HandleTypeDef hsdram;

// FMC GPIO配置(根据实际硬件调整)
void FMC_GPIO_Init() {
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    __HAL_RCC_GPIOD_CLK_ENABLE();
    __HAL_RCC_GPIOE_CLK_ENABLE();
    __HAL_RCC_GPIOF_CLK_ENABLE();
    __HAL_RCC_GPIOG_CLK_ENABLE();

    // 配置数据线 D0-D15(示例引脚)
    // PD0-D1, PE7-PE15, PF0-PF1, PG0-PG1 等
    GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
    // ... 其他数据线、地址线、控制信号引脚配置
}

// SDRAM初始化(严格遵循时序)
void SDRAM_Init() {
    FMC_SDRAM_TimingTypeDef timing = {
        .LoadToActiveDelay    = 2,   // tMRD=2周期
        .ExitSelfRefreshDelay = 7,   // tXSR=7周期
        .SelfRefreshTime      = 4,   // tRAS=4周期
        .RowCycleDelay        = 7,   // tRC=7周期
        .WriteRecoveryTime    = 2,   // tWR=2周期
        .RPDelay              = 2,   // tRP=2周期
        .RCDDelay             = 2    // tRCD=2周期
    };

    hsdram.Instance = FMC_SDRAM_DEVICE;
    hsdram.Init.SDBank             = FMC_SDRAM_BANK1;
    hsdram.Init.ColumnBitsNumber   = FMC_SDRAM_COLUMN_BITS_NUM_9; // 9位列地址
    hsdram.Init.RowBitsNumber      = FMC_SDRAM_ROW_BITS_NUM_12;  // 12位行地址
    hsdram.Init.MemoryDataWidth    = FMC_SDRAM_MEM_BUS_WIDTH_16;
    hsdram.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
    hsdram.Init.CASLatency         = FMC_SDRAM_CAS_LATENCY_3;
    hsdram.Init.SDClockPeriod      = FMC_SDRAM_CLOCK_PERIOD_2;   // 100MHz

    HAL_SDRAM_Init(&hsdram, &timing);

    // 发送初始化命令序列
    HAL_SDRAM_SendCommand(&hsdram, FMC_SDRAM_CMD_CLK_ENABLE, 0, 0xFFFF);
    HAL_Delay(1); // 等待100μs
    HAL_SDRAM_SendCommand(&hsdram, FMC_SDRAM_CMD_PALL, 0, 0xFFFF);
    HAL_SDRAM_SendCommand(&hsdram, FMC_SDRAM_CMD_AUTOREFRESH_MODE, 0, 0xFFFF);
    HAL_SDRAM_SendCommand(&hsdram, FMC_SDRAM_CMD_AUTOREFRESH_MODE, 0, 0xFFFF);

    // 配置模式寄存器(突发长度=1,顺序访问)
    FMC_SDRAM_CommandTypeDef cmd = {
        .CommandMode = FMC_SDRAM_CMD_LOAD_MODE,
        .CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1,
        .AutoRefreshNumber = 1,
        .ModeRegisterDefinition = (3 << 9) | (0 << 0) // CAS=3,BL=1
    };
    HAL_SDRAM_SendCommand(&hsdram, &cmd, 0xFFFF);
    HAL_SDRAM_ProgramRefreshRate(&hsdram, 8192); // 64ms刷新
}

// 单点写入(16位数据)
void SDRAM_Write16(uint32_t addr_offset, uint16_t data) {
    volatile uint16_t *ptr = (volatile uint16_t*)(SDRAM_BASE_ADDR + addr_offset);
    *ptr = data;
}

// 单点读取(16位数据)
uint16_t SDRAM_Read16(uint32_t addr_offset) {
    volatile uint16_t *ptr = (volatile uint16_t*)(SDRAM_BASE_ADDR + addr_offset);
    return *ptr;
}

// 块写入(16位数据,长度单位为字)
void SDRAM_WriteBlock16(uint32_t addr_offset, uint16_t *data, uint32_t len) {
    volatile uint16_t *ptr = (volatile uint16_t*)(SDRAM_BASE_ADDR + addr_offset);
    for (uint32_t i = 0; i < len; i++) {
        ptr[i] = data[i];
    }
}

// 块读取(16位数据,长度单位为字)
void SDRAM_ReadBlock16(uint32_t addr_offset, uint16_t *buffer, uint32_t len) {
    volatile uint16_t *ptr = (volatile uint16_t*)(SDRAM_BASE_ADDR + addr_offset);
    for (uint32_t i = 0; i < len; i++) {
        buffer[i] = ptr[i];
    }
}

​

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/982599.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

DeepSeek-R1国产化系统gpu驱动+cuda+ollama+webui可视化离线私有化部署

1.概述 网上大部分教程都是在线部署&#xff0c;完全离线私有化部署的文章不多&#xff0c;本文介绍从GPU驱动、cuda、ollama、deepseek模型和open webui等完全离线安装几个方面&#xff0c;让小白0基础也可以私有化部署大模型deepseek-R1。 我使用的设备是银河麒麟V10操作系统…

【蓝桥杯】每天一题,理解逻辑(3/90)【Leetcode 快乐数】

闲话系列&#xff1a;每日一题&#xff0c;秃头有我&#xff0c;Hello&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;,我是IF‘Maxue&#xff0c;欢迎大佬们来参观我写的蓝桥杯系列&#xff0c;我好久没有更新博客了&#xff0c;因为up猪我寒假用自己的劳动换了…

飞机大战lua迷你世界脚本

-- 迷你世界飞机大战 v1.2 -- 星空露珠工作室制作 -- 最后更新&#xff1a;2024年1月 ----------------------------- -- 迷你世界API适配配置 ----------------------------- local UI { BASE_ID 7477478487091949474-22856, -- UI界面ID ELEMENTS { BG 1, -- 背景 BTN_LE…

AI绘画软件Stable Diffusion详解教程(6):文生图、提示词细说与绘图案例

文生图即以文字描述来生成图像&#xff0c;这是目前所有AI绘画软件的基本功能之一。要想画一副好的图片&#xff0c;除了选择好的模型&#xff0c;在文生图中&#xff0c;提示词特别关键。 一、什么是提示词&#xff08;Prompt&#xff09; 提示词又称创意、关键词、咒语、ca…

C++编程:进阶阶段—4.1封装

C面向对象的三大特性&#xff1a;封装、继承、多态 具有相同性质的对象&#xff0c;抽象为类 4.1 封装 封装的意义&#xff1a;将属性和行为作为一个整体&#xff0c;表现生活中的事物&#xff0c;并将属性和行为加以权限控制。 4.1.1 类的定义及实例化对象 语法&#xff…

信奥赛CSP-J复赛集训(模拟算法专题)(1):P8813 [CSP-J 2022] 乘方

信奥赛CSP-J复赛集训&#xff08;模拟算法专题&#xff09;&#xff08;1&#xff09;&#xff1a;P8813 [CSP-J 2022] 乘方 题目描述 小文同学刚刚接触了信息学竞赛&#xff0c;有一天她遇到了这样一个题&#xff1a;给定正整数 a a a 和 b b b&#xff0c;求 a b a^b ab …

Flink深入浅出之02

深入浅出Flink-第二天 目标 掌握常见的DataStream常见的source掌握常见的DataStream的transformation操作掌握常见的DataStream的sink操作了解入门的DataSet API算子 &#x1f4d6; 1. DataStream 的编程模型 DataStream 的编程模型包括四个部分&#xff1a;Environment、D…

[C语言日寄] 字符串操作函数的使用及其拓展

【作者主页】siy2333 【专栏介绍】⌈c语言日寄⌋&#xff1a;这是一个专注于C语言刷题的专栏&#xff0c;精选题目&#xff0c;搭配详细题解、拓展算法。从基础语法到复杂算法&#xff0c;题目涉及的知识点全面覆盖&#xff0c;助力你系统提升。无论你是初学者&#xff0c;还是…

基于websocket的多用户网页五子棋 --- 测试报告

目录 功能测试自动化测试性能测试 功能测试 1.登录注册页面 2.游戏大厅页面 3.游戏房间页面 自动化测试 1.使用脑图编写web自动化测试用例 2.创建自动化项目&#xff0c;根据用例通过selenium来实现脚本 根据脑图进行测试用例的编写&#xff1a; 每个页面一个测试类&am…

【Linux】信号处理以及补充知识

目录 一、信号被处理的时机&#xff1a; 1、理解&#xff1a; 2、内核态与用户态&#xff1a; 1、概念&#xff1a; 2、重谈地址空间&#xff1a; 3、处理时机&#xff1a; 补充知识&#xff1a; 1、sigaction&#xff1a; 2、函数重入&#xff1a; 3、volatile&…

(三) 征服MySQL面试:30+高频核心问题深度剖析与实战指南

一、为什么MySQL是面试的"必答题"&#xff1f; 数据库领域占比&#xff1a;MySQL占据全球关系型数据库市场份额Top 3&#xff0c;阿里、腾讯、美团等大厂核心系统深度依赖技术栈深度检验&#xff1a;通过MySQL问题可考察候选人的数据结构理解、系统设计能力、性能优…

TensorFlow深度学习实战(10)——迁移学习详解

TensorFlow深度学习实战(10)——迁移学习详解 0. 前言1. 迁移学习1.1 迁移学习基本概念1.2 迁移学习的重要性1.3 ImageNet1.4 迁移学习流程2. Inception V3 架构3. 构建迁移学习模型小结系列链接0. 前言 迁移学习( Transfer Learning )是一种利用从一项任务中获得的知识来解…

Docker基础篇——什么是Docker与Docker的仓库、镜像、容器三大概念

大家好我是木木&#xff0c;在当今快速发展的云计算与云原生时代&#xff0c;容器化技术蓬勃兴起&#xff0c;Docker 作为实现容器化的主流工具之一&#xff0c;为开发者和运维人员带来了极大的便捷 。下面我们一起了解下什么是Docker与与Docker的仓库、镜像、容器三大概念。 …

蓝桥杯题型

蓝桥杯题型分类 二分 123 传送门 1. 小区间的构成 假设数列的构成是如下形式&#xff1a; 第 1 个区间包含 1 个元素&#xff08;1&#xff09;。第 2 个区间包含 2 个元素&#xff08;1 2&#xff09;。第 3 个区间包含 3 个元素&#xff08;1 2 3&#xff09;。第 4 个区…

大模型AI平台DeepSeek 眼中的SQL2API平台:QuickAPI、dbapi 和 Magic API 介绍与对比

目录 1 QuickAPI 介绍 2 dbapi 介绍 3 Magic API 介绍 4 简单对比 5 总结 统一数据服务平台是一种低代码的方式&#xff0c;实现一般是通过SQL能直接生成数据API&#xff0c;同时能对产生的数据API进行全生命周期的管理&#xff0c;典型的SQL2API的实现模式。 以下是针对…

本地部署pangolin获取谱系,从而达到预测新冠的流行趋势

步骤 1&#xff1a;安装Docker 注&#xff1a;此步骤忽略&#xff0c;可通过Docker官网对于文档进行安装,地址如下 Docker: Accelerated Container Application Developmenthttps://www.docker.com/ 步骤 2&#xff1a;拉取Pangolin镜像 docker pull staphb/pangolin:latest 步…

HarmonyOS Next 属性动画和转场动画

HarmonyOS Next 属性动画和转场动画 在鸿蒙应用开发中&#xff0c;动画是提升用户体验的关键要素。通过巧妙运用动画&#xff0c;我们能让应用界面更加生动、交互更加流畅&#xff0c;从而吸引用户的注意力并增强其使用粘性。鸿蒙系统为开发者提供了丰富且强大的动画开发能力&…

K8S学习之基础十:k8s中初始化容器和主容器

init容器和主容器 init容器和主容器的区别 初始化容器不支持 Readinessprobe&#xff0c;因为他们必须在pod就绪之前运行完成每个init容器必须运行成功&#xff0c;下一个才能够运行 # 定义两个初始化容器&#xff0c;完成后再运行主容器 vi pod-init.yaml apiVersion: v1 …

PostgreSQL 安装与使用

下载地址: EDB: Open-Source, Enterprise Postgres Database Management 安装图形化安装界面安装。安装完后将bin目录配置到系统环境变量 执行psql -h localhost -p 5432 -U postgres 密码在安装过程中设置的 ​ 0、修改密码 ALTER USER sonar WITH PASSWORD 123456; 1、新…

WPF高级 | WPF 应用程序部署与发布:确保顺利交付到用户手中

WPF高级 | WPF 应用程序部署与发布&#xff1a;确保顺利交付到用户手中 一、前言二、部署与发布基础概念2.1 部署的定义与目的2.2 发布的方式与渠道2.3 部署与发布的关键要素 三、WPF 应用程序打包3.1 使用 Visual Studio 自带的打包工具3.2 使用第三方打包工具 四、发布到不同…