当前位置: 首页 > news >正文

STM32F4 外扩SRAM介绍及应用

第十七章 外扩SRAM介绍及应用

1. IS62WV51216 芯片介绍

存储特性:

  • 存储容量与组织: 8Mbit (兆比特) 静态RAM,组织形式为 512K 字 × 16 位。
  • 高速存取时间: 提供 45ns 和 55ns 两种高速存取时间。
  • 全静态操作: 无需时钟或刷新操作,简化了设计。

功耗特性:

  • CMOS 低功耗操作: 具有低功耗特性,典型工作电流为 36mW,典型 CMOS 待机电流为 12µW。 新版本的IS62/65WV51216HALL/BLL型号,其典型CMOS待机电流可低至 3.2 µA (25°C)。
  • 待机模式: 当芯片未被选中时(例如,CS1 为高或 CS2 为低,或 CS1 为低、CS2 为高且 LB 和 UB 都为高),器件进入待机模式,此时功耗显著降低。

电压和接口:

  • 单电源供电:
    • IS62WV51216ALL 版本:1.65V 至 2.2V VDD。
    • IS62WV51216BLL 版本:2.5V 至 3.6V VDD。
    • 新版本的 IS62/65WV51216HALL 支持 1.65V-2.2V VDD,IS62/65WV51216HBLL 支持 2.2V-3.6V VDD。
  • TTL 兼容接口电平: 输入/输出接口与 TTL 标准兼容。

控制和封装:

  • 三态输出: 具有三态输出功能。
  • 字节控制: 支持上下字节 (UB 和 LB) 的数据控制,允许对单个字节进行读写操作。
  • 易于存储器扩展: 通过使用片选 (Chip Enable) 和输出使能 (Output Enable) 输入实现存储器扩展。
  • 封装类型: 通常采用 JEDEC 标准 48 引脚 mini BGA (7.2mm x 8.7mm) 和 44 引脚 TSOP (TYPE II) 封装。

2. 外扩SRAM应用示例

2.1 相关宏定义

#ifndef __SRAM_H
#define __SRAM_H#include "sys.h"extern SRAM_HandleTypeDef sram_hanle;/* FSMC相关参数 定义 * 注意: 我们默认是通过FSMC块3来连接SRAM, 块1有4个片选: FSMC_NE1~4** 修改SRAM_FSMC_NEX, 对应的SRAM_CS_GPIO相关设置也得改*/
#define SRAM_FSMC_NEX           3         /* 使用FSMC_NE3接SRAM_CS,取值范围只能是: 1~4 */
#define SRAM_FSMC_BCRX          FSMC_Bank1->BTCR[(SRAM_FSMC_NEX - 1) * 2]       /* BCR寄存器,根据SRAM_FSMC_NEX自动计算 */
#define SRAM_FSMC_BTRX          FSMC_Bank1->BTCR[(SRAM_FSMC_NEX - 1) * 2 + 1]   /* BTR寄存器,根据SRAM_FSMC_NEX自动计算 */
#define SRAM_FSMC_BWTRX         FSMC_Bank1E->BWTR[(SRAM_FSMC_NEX - 1) * 2]      /* BWTR寄存器,根据SRAM_FSMC_NEX自动计算 *//* SRAM基地址, 根据 SRAM_FSMC_NEX 的设置来决定基址地址* 我们一般使用FSMC的块1(BANK1)来驱动SRAM, 块1地址范围总大小为256MB,均分成4块:* 存储块1(FSMC_NE1)地址范围: 0X6000 0000 ~ 0X63FF FFFF* 存储块2(FSMC_NE2)地址范围: 0X6400 0000 ~ 0X67FF FFFF* 存储块3(FSMC_NE3)地址范围: 0X6800 0000 ~ 0X6BFF FFFF* 存储块4(FSMC_NE4)地址范围: 0X6C00 0000 ~ 0X6FFF FFFF*/
#define SRAM_BASE_ADDR         (0X60000000 + (0X4000000 * (SRAM_FSMC_NEX - 1)))void sram_init(void);
void sram_write(uint8_t *pbuf, uint32_t addr, uint32_t datalen);
void sram_read(uint8_t *pbuf, uint32_t addr, uint32_t datalen);
void sram_test_write(uint32_t addr, uint8_t data);
uint8_t sram_test_read(uint32_t addr);#endif /* __SRAM_H__ */

2.2 FSMC-SRAM初始化

void sram_init(void)
{GPIO_InitTypeDef GPIO_InitStructure;FSMC_NORSRAM_TimingTypeDef fsmc_handle;__HAL_RCC_FSMC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); __HAL_RCC_GPIOF_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE();// WR-PD5 RD-PD4 CS-PG10GPIO_InitStructure.Pin = GPIO_PIN_10;GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;GPIO_InitStructure.Pull = GPIO_PULLUP;GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;GPIO_InitStructure.Alternate = GPIO_AF12_FSMC;HAL_GPIO_Init(GPIOG, &GPIO_InitStructure);GPIO_InitStructure.Pin = GPIO_PIN_5|GPIO_PIN_4;HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);// PD0,1,4,5,8~15GPIO_InitStructure.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;GPIO_InitStructure.Pull = GPIO_PULLUP;GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);// PE0,1,7~15GPIO_InitStructure.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;HAL_GPIO_Init(GPIOE, &GPIO_InitStructure);// PF0~5,12~15GPIO_InitStructure.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;HAL_GPIO_Init(GPIOF, &GPIO_InitStructure);// PG0~5,10GPIO_InitStructure.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_10;HAL_GPIO_Init(GPIOG, &GPIO_InitStructure);// FSMC Configurationsram_handle.Instance = FSMC_NORSRAM_DEVICE;sram_handle.Extended = FSMC_NORSRAM_EXTENDED_DEVICE;sram_handle.Init.NSBank = (SRAM_FSMC_NEX == 1) ? FSMC_NORSRAM_BANK1 : \(SRAM_FSMC_NEX == 2) ? FSMC_NORSRAM_BANK2 : \(SRAM_FSMC_NEX == 3) ? FSMC_NORSRAM_BANK3 : FSMC_NORSRAM_BANK4; /* 根据配置选择FSMC_NE1~4 */sram_handle.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE; // 地址/数据线不复用sram_handle.Init.MemoryType = FSMC_MEMORY_TYPE_SRAM; // SRAMsram_handle.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16; // 16位数据宽度sram_handle.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE; // 突发访问模式关闭sram_handle.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW; // 等待信号极性低sram_handle.Init.WaitSignalActive = FSMC_WAIT_TIMING_BEFORE_WS; // 等待信号在前sram_handle.Init.WriteOperation = FSMC_WRITE_OPERATION_ENABLE; // 写使能sram_handle.Init.WaitSignal = FSMC_WAIT_SIGNAL_DISABLE; // 等待信号关闭sram_handle.Init.ExtendedMode = FSMC_EXTENDED_MODE_DISABLE; // 扩展模式关闭sram_handle.Init.AsynchronousWait = FSMC_ASYNCHRONOUS_WAIT_DISABLE; // 异步等待关闭sram_handle.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE; // 写突发关闭/* FSMC读时序控制寄存器 */fsmc_handle.AddressSetupTime = 0x02; // 地址设置时间fsmc_handle.AddressHoldTime = 0x00; // 地址保持时间fsmc_handle.DataSetupTime = 0x08; // 数据设置时间fsmc_handle.BusTurnAroundDuration = 0x00; // 总线转向持续时间fsmc_handle.AccessMode = FSMC_ACCESS_MODE_A; // 访问模式AHAL_SRAM_Init(&sram_handle, &fsmc_handle, &fsmc_handle); // 初始化SRAM
}

2.3 SRAM读写

/*** @brief       往SRAM指定地址写入指定长度数据* @param       pbuf    : 数据存储区* @param       addr    : 开始写入的地址(最大32bit)* @param       datalen : 要写入的字节数(最大32bit)* @retval      无*/
void sram_write(uint8_t *pbuf, uint32_t addr, uint32_t datalen)
{for (; datalen != 0; datalen--){*(volatile uint8_t *)(SRAM_BASE_ADDR + addr) = *pbuf;addr++;pbuf++;}
}/*** @brief       从SRAM指定地址读取指定长度数据* @param       pbuf    : 数据存储区* @param       addr    : 开始读取的地址(最大32bit)* @param       datalen : 要读取的字节数(最大32bit)* @retval      无*/
void sram_read(uint8_t *pbuf, uint32_t addr, uint32_t datalen)
{for (; datalen != 0; datalen--){*pbuf++ = *(volatile uint8_t *)(SRAM_BASE_ADDR + addr);addr++;}
}

2.4 主函数测试

#include "bsp_init.h"
#include "stdio.h"
#include "SerialInvoker.h"
#include "sram.h"// 测试数据
// uint32_t test_data[250000] __attribute__((at(SRAM_BASE_ADDR))); // AC5写法
uint32_t test_data[250000] __attribute__((section(".ARM.__at_0x68000000"))); // AC6写法// 外扩SRAM测试
void sram_test(uint16_t x, uint16_t y)
{uint32_t i = 0;uint8_t temp = 0;uint16_t addr = 0; // 在地址0读到的数据LCD_ShowString(x,y,230,y+16,16,"Ex Memory Test:   0KB");// 每隔4k字节写入一个数据,总共写入256次,即写入1MB数据for(i=0;i<1024*1024;i+=4096){sram_write(&temp,i,1);temp++;}// 读取数据进行校验for(i=0;i<1024*1024;i+=4096){sram_read(&temp,i,1);if(i == 0){addr = temp; // 记录地址0读到的数据}else if(temp <= addr){break; // 校验失败,退出循环}LCD_ShowxNum(x+15*8,y,(uint16_t)(temp-addr+1)*4,4,16,0);}
}int main(void)
{uint8_t key_value = 0;uint8_t i = 0;uint32_t data = 0;bsp_init();sram_init();serial_invoker_init(84);LCD_ShowString(30,110,200,16,16,"KEY0:Test Sram");LCD_ShowString(30,130,200,16,16,"KEY1:TEST Data");for(data=0;data<250000;data++){test_data[data] = data; // 初始化测试数据}while(1){key_value = key_scan(0);if(key_value == KEY0_Press){sram_test(30,150); // 测试外扩SRAM}else if(key_value == KEY1_Press){for(data=0;data<250000;data++){LCD_ShowxNum(30,170,test_data[data],6,16,0); // 显示测试数据}}else{delay_ms(10);}i++;if(i == 10){i = 0;LED_TOGGLE(LED0_GPIO_Pin);}}
}

3. FSMC外扩SRAM相关函数(HAL库)

3.1 FSMC 初始化与配置

3.1.1 SRAM 句柄与初始化结构体
SRAM_HandleTypeDef hsram;
FSMC_NORSRAM_TimingTypeDef Timing;
3.1.2 配置时序参数
/* 地址建立时间、数据建立时间等 (单位: HCLK周期) */
Timing.AddressSetupTime = 2; // 地址建立时间
Timing.AddressHoldTime = 1; // 地址保持时间 (模式A/D)
Timing.DataSetupTime = 2; // 数据建立时间 (关键参数)
Timing.BusTurnAroundDuration = 0; // 总线周转时间
Timing.CLKDivision = 0; // 时钟分频
Timing.DataLatency = 0; // 数据延迟
Timing.AccessMode = FSMC_ACCESS_MODE_A; // 访问模式
3.1.3 配置 SRAM 初始化结构体
hsram.Instance = FSMC_NORSRAM_DEVICE;
hsram.Extended = FSMC_NORSRAM_EXTENDED_DEVICE;
hsram.Init.NSBank = FSMC_NORSRAM_BANK1; // 使用BANK1
hsram.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE;
hsram.Init.MemoryType = FSMC_MEMORY_TYPE_SRAM;
hsram.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16; // 16位总线
hsram.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE;
hsram.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW;
hsram.Init.WaitSignalActive = FSMC_WAIT_TIMING_BEFORE_WS;
hsram.Init.WriteOperation = FSMC_WRITE_OPERATION_ENABLE;
hsram.Init.WaitSignal = FSMC_WAIT_SIGNAL_DISABLE;
hsram.Init.ExtendedMode = FSMC_EXTENDED_MODE_DISABLE;
hsram.Init.AsynchronousWait = FSMC_ASYNCHRONOUS_WAIT_DISABLE;
hsram.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE;
3.1.4 初始化 FSMC
// 初始化FSMC并关联时序
HAL_SRAM_Init(&hsram, &Timing, &Timing);// 启用FSMC时钟
__HAL_RCC_FSMC_CLK_ENABLE();

3.2 SRAM 读写操作函数

3.2.1 阻塞式读写
// 16位写操作
HAL_StatusTypeDef HAL_SRAM_Write_16b(SRAM_HandleTypeDef *hsram,uint32_t *pAddress, // SRAM地址 (0x6xxxxxxx)uint16_t *pSrcBuffer, // 数据缓冲区uint32_t BufferSize // 数据大小 (单位: 16位字)
);// 16位读操作
HAL_StatusTypeDef HAL_SRAM_Read_16b(SRAM_HandleTypeDef *hsram,uint32_t *pAddress,uint16_t *pDstBuffer,uint32_t BufferSize
);
3.2.2 其他数据宽度
// 8位读写
HAL_SRAM_Write_8b();
HAL_SRAM_Read_8b();// 32位读写
HAL_SRAM_Write_32b();
HAL_SRAM_Read_32b();
3.2.3 中断模式读写
// 中断写
HAL_StatusTypeDef HAL_SRAM_Write_16b_IT(SRAM_HandleTypeDef *hsram,uint32_t *pAddress,uint16_t *pSrcBuffer,uint32_t BufferSize
);// 中断读
HAL_StatusTypeDef HAL_SRAM_Read_16b_IT(...);
3.2.4 DMA 模式读写
// DMA写
HAL_StatusTypeDef HAL_SRAM_Write_16b_DMA(SRAM_HandleTypeDef *hsram,uint32_t *pAddress,uint16_t *pSrcBuffer,uint32_t BufferSize
);// DMA读
HAL_StatusTypeDef HAL_SRAM_Read_16b_DMA(...);

3.3 回调函数 (中断/DMA模式)

// 写完成回调
void HAL_SRAM_TxCpltCallback(SRAM_HandleTypeDef *hsram);// 读完成回调
void HAL_SRAM_RxCpltCallback(SRAM_HandleTypeDef *hsram);// DMA错误回调
void HAL_SRAM_DMAError(DMA_HandleTypeDef *hdma);

3.4 SRAM 控制函数

// 启用/禁用写操作
void HAL_SRAM_WriteOperation_Enable(SRAM_HandleTypeDef *hsram);
void HAL_SRAM_WriteOperation_Disable(SRAM_HandleTypeDef *hsram);

文中完整工程下载:https://github.com/hazy1k/STM32F4-Quick-Start-Guide-HAL/tree/main/2.code

http://www.dtcms.com/a/340337.html

相关文章:

  • word——如何给封面、目录、摘要、正文设置不同的页码
  • Web网站的运行原理1
  • 使用 mongosh 设置 MongoDB 账号密码
  • word——快速删除页眉横线
  • 微软宣布开源大模型gpt-oss在Azure平台实现性能突破
  • Azure 使用记录
  • Claude Code NPM 包发布命令
  • 【Linux系统】匿名管道以及进程池的简单实现
  • 测试环境搭建和部署(在Linux环境下搭建jdk+Tomcat+mysql环境和项目包的部署)
  • 暖哇科技AI调查智能体上线,引领保险调查风控智能化升级
  • cv2.bitwise_and是 OpenCV 中用于执行按位与运算的核心函数,主要用于图像处理中的像素级操作
  • 【密码学实战】X86、ARM、RISC-V 全量指令集与密码加速技术全景解析
  • 【考研408数据结构-09】 图论进阶:最短路径与最小生成树
  • 【考研408数据结构-05】 串与KMP算法:模式匹配的艺术
  • [论文阅读] 人工智能 + 软件工程 | 从用户需求到产品迭代:特征请求研究的全景解析
  • 【软考架构】软件工程:软件项目管理
  • 用倒计时软件为考研备考精准导航 复习 模拟考试 日期倒计时都可以用
  • SBOM风险预警 | NPM前端框架 javaxscript 遭受投毒窃取浏览器cookie
  • vue3 el-select 默认选中第一个
  • 使用Redis 分布式锁防止短信验证码重复下发问题
  • 《防雷电路设计》---TVS介绍
  • Linux系统之部署nullboard任务管理工具
  • C++/Qt开发:TCP通信连接软件测试方法:ECHO指令
  • C++中的原子操作,自旋锁
  • Vibe Coding:轻松的幻觉,沉重的未来
  • HTML <meta name=“color-scheme“>:自动适配系统深色 / 浅色模式
  • AutoGLM2.0背后的云手机和虚拟机分析(非使用案例)
  • Mac 4步 安装 Jenv 管理多版本JDK
  • 基于YOLO11的手机违规使用检测模型训练实战
  • MySQL诊断系列(3/6):索引分析——5个SQL揪出“僵尸索引”