文章目录

  • SRAM的概念
    • XM8A51216介绍
      • 特点
      • 连接线原理框图
      • 硬件连接图
  • SRAM的配置
    • 使能 FSMC 时钟,并配置 FSMC 相关的 IO 及其时钟使能
    • 初始化FSMC,设置FSMC BANK1区域3
    • 使能 BANK1 区域 3
    • FSMC读写代码

SRAM的概念

SRAM的介绍
STM32F407ZGT6自带了 192K字节的 SRAM。内存要求高的场合, STM32F4自带的这些内存就不够用了。

XM8A51216介绍

XM8A51216 是深圳星忆存储科技有限公司生产的一颗(512*16,即 1M 字节)容量的 CMOS 静态内存芯片。
啥是CMOS?

特点

该芯片具有如下几个特点:
⚫ 高速。具有最高访问速度 10/12ns。
⚫ 低功耗。
⚫ TTL 电平兼容。
⚫ 全静态操作。不需要刷新和时钟电路。
⚫ 三态输出。
⚫ 字节控制功能。支持高/低字节控制。

连接线原理框图


A0~18 为地址线,总共 19 根地址线(即 2^19=512K,1K=1024);
DQ0~15 为数据线,总共 16 根数据线。
CEn 是芯片使能信号,低电平有效;
OEn 是输出使能信号,低电平有效;
WEn 是写使能信号,低电平有效;
BLEn 和 BHEn 分别是高字节控制和低字节控制信号;

硬件连接图

A[0:18]接 FMSC_A[0:18](不过顺序错乱了)
D[0:15]接 FSMC_D[0:15]
BHEn 接 FSMC_NBL1
BLEn 接 FSMC_NBL0
OEn 接 FSMC_OE
WEn 接 FSMC_WE
CEn 接 FSMC_NE3

  • XM8A51216 的 A[0:18]并不是按顺序连接 STM32F1 的 FMSC_A[0:18],不过这并不影响我们正常使用外部 SRAM,因为地址具有唯一性。

SRAM的配置

使用 FSMC的 BANK1 区域 3来控制 XM8A51216。
PB15 控制背光?
初始化 FSMC 主要是初始化三个寄存器 FSMC_BCRx,FSMC_BTRx,FSMC_BWTRx

使能 FSMC 时钟,并配置 FSMC 相关的 IO 及其时钟使能

要使用 FSMC,当然首先得开启其时钟。然后需要把FSMC_D015,FSMCA018 等相关IO 口,全部配置为复用输出,并使能各 IO 组的时钟。使能 FSMC 时钟的方法:
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC,ENABLE);

#include "sram.h"
#include "usart.h"
//使用 NOR/SRAM 的 Bank1.sector3,地址位 HADDR[27,26]=10
//对 IS61LV25616/IS62WV25616,地址线范围为 A0~A17
//对 IS61LV51216/IS62WV51216,地址线范围为 A0~A18
//对 XM8A51216,地址线范围为 A0~A18
#define Bank1_SRAM3_ADDR ((u32)(0x68000000))
//初始化外部 SRAM
void FSMC_SRAM_Init(void)
{FSMC_NORSRAMInitTypeDef FSMC_NSInitStructure;
FSMC_NORSRAMTimingInitTypeDef readWriteTiming;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOE|
RCC_APB2Periph_GPIOF|RCC_APB2Periph_GPIOG,ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC,ENABLE);
GPIO_InitStructure.GPIO_Pin = 0xFF33; //PORTD 复用推挽输出
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = 0xFF83; //PORTE 复用推挽输出
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = 0xF03F; //PORTD 复用推挽输出
GPIO_Init(GPIOF, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = 0x043F; //PORTD 复用推挽输出
GPIO_Init(GPIOG, &GPIO_InitStructure);

初始化FSMC,设置FSMC BANK1区域3

固件库提供了 3 个 FSMC 初始化函数分别为

FSMC_NORSRAMInit();
FSMC_NANDInit();
FSMC_PCCARDInit();

这三个函数分别用来初始化 4 种类型存储器。
用来初始化NOR 和 SRAM 使用同一个函数 FSMC_NORSRAMInit()。
此部分包括设置区域 3 的存储器的工作模式、位宽和读写时序等。
本章我们使用模式 A、16 位宽,读写共用一个时序寄存器。使用的函数是:

void FSMC_NORSRAMInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct)

结构体指针:

typedef struct
{uint32_t FSMC_Bank;
uint32_t FSMC_DataAddressMux;
uint32_t FSMC_MemoryType;
uint32_t FSMC_MemoryDataWidth;
uint32_t FSMC_BurstAccessMode;
uint32_t FSMC_AsynchronousWait;
uint32_t FSMC_WaitSignalPolarity;
uint32_t FSMC_WrapMode;
uint32_t FSMC_WaitSignalActive;
uint32_t FSMC_WriteOperation;
uint32_t FSMC_WaitSignal;
uint32_t FSMC_ExtendedMode;
uint32_t FSMC_WriteBurst;
FSMC_NORSRAMTimingInitTypeDef* FSMC_ReadWriteTimingStruct;
FSMC_NORSRAMTimingInitTypeDef* FSMC_WriteTimingStruct;
}FSMC_NORSRAMInitTypeDef;

前面13 个基本类型(unit32_t)的成员变量用来配置片选控制寄存器 FSMC_BCRx。
最后两个SMC_NORSRAMTimingInitTypeDef 指针类型的成员变量用来配置寄存器 FSMC_BTRx 和 FSMC_BWTRx
下面我们主要来看看模式 A下的相关配置参数:

  • FSMC_Bank
    ○ 用来设置使用到的存储块标号和区号,前面讲过
    ○ 存储块 1 区号 4,所以选择值为FSMC_Bank1_NORSRAM4。
  • FSMC_MemoryType
    用来设置存储器类型,我们这里是 SRAM,所以选择值为FSMC_MemoryType_SRAM。
  • FSMC_MemoryDataWidth
    用来设置数据宽度,可选 8 位还是 16 位,这里我们是 16 位数据宽度,所以选择值为 FSMC_MemoryDataWidth_16b。
  • FSMC_WriteOperation
    用来设置写使能,毫无疑问,我们前面讲解过我们要向 TFT 写数据,所以要写使能,这里我们选择 FSMC_WriteOperation_Enable。
  • FSMC_ExtendedMode
    是设置扩展模式使能位,也就是是否允许读写不同的时序,这里我们采取的读写不同时序,所以设置值为 FSMC_ExtendedMode_Enable。
    上面的这些参数是与模式 A 相关的
    下面我们也来稍微了解一下其他几个参数的意义吧:
  • FSMC_DataAddressMux
    用来设置地址/数据复用使能,若设置为使能,那么地址的低 16位和数据将共用数据总线,仅对 NOR 和 PSRAM 有效,所以我们设置为默认值不复用,值FSMC_DataAddressMux_Disable。

FSMC_BurstAccessMode , FSMC_AsynchronousWait , FSMC_WaitSignalPolarity ,FSMC_WaitSignalActive , FSMC_WrapMode , FSMC_WaitSignal FSMC_WriteBurst 和FSMC_WaitSignal 这些参数在成组模式同步模式才需要设置。

设 置 读 写 时 序 参 数 的 两 个 变 量 FSMC_ReadWriteTimingStruct 和FSMC_WriteTimingStruct,他们都是 FSMC_NORSRAMTimingInitTypeDef 结构体指针类型,这两个参数在初始化的时候分别用来初始化片选控制寄存器FSMC_BTRx和写操作时序控制寄存器 FSMC_BWTRx。
下面我们看看 FSMC_NORSRAMTimingInitTypeDef 类型的定义:

typedef struct
{uint32_t FSMC_AddressSetupTime;
uint32_t FSMC_AddressHoldTime;
uint32_t FSMC_DataSetupTime;
uint32_t FSMC_BusTurnAroundDuration;
uint32_t FSMC_CLKDivision;
uint32_t FSMC_DataLatency;
uint32_t FSMC_AccessMode;
}FSMC_NORSRAMTimingInitTypeDef;

这个结构体有 7 个参数用来设置 FSMC 读写时序。
设计地址建立保持时间,数据建立时间等等配置等。

具体的设置方法请参考我们的 sarm.c 文件中的 FSMC_SRAM_Init()函数。

SRAM/NOR 闪存片选时序寄存器:FSMC_BTRx

readWriteTiming.FSMC_AddressSetupTime = 0x00; //地址建立时间为 0 个 HCLK
readWriteTiming.FSMC_AddressHoldTime = 0x00; //地址保持时间模式 A 未用到
readWriteTiming.FSMC_DataSetupTime = 0x01; //数据保持时间为 1 个 HCLK
readWriteTiming.FSMC_BusTurnAroundDuration = 0x00;
readWriteTiming.FSMC_CLKDivision = 0x00;
readWriteTiming.FSMC_DataLatency = 0x00;
readWriteTiming.FSMC_AccessMode = FSMC_AccessMode_A; //模式 A
FSMC_NSInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM3;// BTCR[4],[5]。
FSMC_NSInitStructure.FSMC_DataAddressMux= FSMC_DataAddressMux_Disable;
FSMC_NSInitStructure.FSMC_MemoryType =FSMC_MemoryType_SRAM //SRAM
FSMC_NSInitStructure.FSMC_MemoryDataWidth= FSMC_MemoryDataWidth_16b;
//存储器数据宽度为 16bit
FSMC_NSInitStructure.FSMC_BurstAccessMode=FSMC_BurstAccessMode_Disable;
FSMC_NSInitStructure.FSMC_WaitSignalPolarity=FSMC_WaitSignalPolarity_Low;
FSMC_NSInitStructure.FSMC_AsynchronousWait=FSMC_AsynchronousWait_Disable;
FSMC_NSInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
FSMC_NSInitStructure.FSMC_WaitSignalActive=
FSMC_WaitSignalActive_BeforeWaitState;
FSMC_NSInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
//存储器写使能
FSMC_NSInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
FSMC_NSInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
// 读写使用相同的时序
FSMC_NSInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
FSMC_NSInitStructure.FSMC_ReadWriteTimingStruct = &readWriteTiming;
FSMC_NSInitStructure.FSMC_WriteTimingStruct = &readWriteTiming;
FSMC_NORSRAMInit(&FSMC_NSInitStructure); //初始化 FSMC 配置

使能 BANK1 区域 3

FSMC 对不同的存储器类型同样提供了不同的使能函数:

void FSMC_NORSRAMCmd(uint32_t FSMC_Bank, FunctionalState NewState);
void FSMC_NANDCmd(uint32_t FSMC_Bank, FunctionalState NewState);
void FSMC_PCCARDCmd(FunctionalState NewState);

NORSRAM函数是:
void FSMC_NORSRAMCmd(uint32_t FSMC_Bank, FunctionalState NewState);

FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3, ENABLE);

因为我们使用的是 BANK1 的区域 3,所以 HADDR[27:26]=10,故外部内存的首地址为0X68000000。
存储块1的地址

FSMC读写代码

//在指定地址开始,连续写入 n 个字节.
//pBuffer:字节指针
//WriteAddr:要写入的地址
//n:要写入的字节数
void FSMC_SRAM_WriteBuffer(u8* pBuffer,u32 WriteAddr,u32 n)
{for(;n!=0;n--)
{*(vu8*)(Bank1_SRAM3_ADDR+WriteAddr)=*pBuffer;
WriteAddr++;
pBuffer++;
}
}
//在指定地址开始,连续读出 n 个字节.
//pBuffer:字节指针
//ReadAddr:要读出的起始地址
//n:要写入的字节数
void FSMC_SRAM_ReadBuffer(u8* pBuffer,u32 ReadAddr,u32 n)
{for(;n!=0;n--)
{*pBuffer++=*(vu8*)(Bank1_SRAM3_ADDR+ReadAddr);
ReadAddr+=1;
//址右移一位对齐.加 2 相当于加 1.
}
}

STM32的SRAM相关推荐

  1. stm32 内部sram大小_STM32第三天

    13. 位操作就是可以单独的对一个比特位进行读和写,在STM32钟,一个是SRAM区的最低1MB空间,另一个外设区最低1MB的空间 外设位带区,SRAM位带区, 14.通过指针形式访问位带 通过指针形 ...

  2. stm32 内部sram大小_让STM32的外部SRAM操作跟内部SRAM一样

    让 STM32 的外部 SRAM 操作跟内部 SRAM 一样 前几天看到开源电子论坛 (openedv) 有人在问这个问题,我特意去做了这个 实验,这样用外部 SRAM 就跟用内部 SRAM 一样,不 ...

  3. stm32 内部sram大小_在SRAM、FLASH中调试代码的配置方法(附详细步骤)

    聊天界面发送嵌入式大杂烩获取1TB大杂烩资料包 STM32的FLASH擦写次数有限(大概为1万次),所以为了延长FLASH的使用时间,我们平时调试时可以选择在SRAM中进行硬件调试.除此之外,SRAM ...

  4. STM32使用SRAM扩展内存

    目录 一.SRAM介绍 二.STM32F103系列的FSMC模块 三.初始化配置及数据访问 四.使全局变量定义在外部SRAM中的方法 五.参考文章及资料 一.SRAM介绍 SRAM(Static Ra ...

  5. STM32 在SRAM中调试代码

    本文所有内容转自他人内容,非本人原创,仅做资料收集.原文地址 https://www.cnblogs.com/firege/p/5806141.html 全套200集视频教程和1000页PDF教程请到 ...

  6. STM32的SRAM调试

    据说Flash的擦写次数是有限的,所以在调试的时候擦来擦去不好,看到boot0.boot1可以配置从SRam启动,就查了相关资料,试了一下,ok了.记录一下,免得以后又忘了.跟flash调试部分相同的 ...

  7. STM32下载程序至SRAM——基于正点原子精英STM32F103ZET6开发板

    STM32下载程序至SRAM--基于正点原子精英STM32F103ZET6开发板 如题,由于STM32的FLASH烧写寿命在1万次左右,对于本人这样的改一行代码都想下载到开发板中测试的强迫症患者,真是 ...

  8. stm32外扩外部sram学习笔记

    在一般情况下stm32内部sram是足够使用的 MDK配置如下 但是有些时候内存是不够用的,比如用到ucgui的时候或者做大项目时就需要外扩sram,倘若你要把外部sram作为运行内存则可以做如下配置 ...

  9. dma接收双缓存 stm32_容易被大多数人忽视的STM32串口DMA问题

    讨论三个问题: 1.什么叫串口DMA 请求: 2.串口简要复习: 3.串口DMA发送流程. 第一 什么叫串口DMA 请求(战舰STM32开发板) 说这个问题之前先简单回顾DMA的基本特性.先导出原子哥 ...

最新文章

  1. R语言构建xgboost模型:控制训练信息输出级别verbose参数
  2. 是时候不把智能手机叫做电话了:移动AI时代来临!
  3. 上接[翻译]ASP.NET 2.0中的健康监测系统(Health Monitoring)(1) - 基本应用
  4. 宝塔部署项目报Warning: require(): open_basedir restriction in effect的解决方案
  5. SVN关于忽略xcuserdata目录
  6. 一颗强健的“心脏”,让海银的业务系统更高效、更安全!
  7. oracle用户名无法登陆,sysdba却可以登陆
  8. 每天一道LeetCode-----有序数组循环右移n位后,寻找最小值,数组中可能包含重复元素
  9. 备份文件命令SqlServer一键复制数据库脚本
  10. 如何成为阿里巴巴大数据开发工程师?你要学习很多东西
  11. 慢速HTTP拒绝服务攻击
  12. spi驱动 (2):应用与测试
  13. 斯特林发动机图纸尺寸_南昌教学模型订做,航空发动机模型_境海模型
  14. concat特征融合_MSFNet:多重空间融合网络进行实时语义分割(北航和旷视联合提出)...
  15. java redis tokenid_基于Spring及Redis的Token鉴权
  16. PHP用set_error_handler()拦截程序中的错误
  17. Luogu P3223 [HNOI2012]排队 组合
  18. iapp进度条倒计时_‎App Store 上的“纪念日提醒 - days matter · 倒数倒计时”
  19. 强大的支持多文件上传的jQuery文件上传插件Uploadify
  20. u盘怎样修复服务器系统,高手教你怎么修复U盘的MBR

热门文章

  1. 握手定理(握手数之和为偶数)和相关2个推论
  2. 期权希腊字母更多的含义和解释
  3. python爬虫精进参考答案_高校邦数据科学创新通识课【Python爬虫】课后习题答案...
  4. 软考_法律法规与标准化知识
  5. MySQL三种插入方式
  6. ❤️熬夜爆肝十万字❤️Java最简单最全入门基础知识(一)(小白必备--推荐小白收藏)❤️
  7. linux etc cron.deny,at.allow与at.deny及cron.allow与cron.deny优先级的比较
  8. remote: Repository not found. fatal: repository ‘xxxxxxx‘ not found
  9. 360度全景图像制作
  10. poi 启用保护后取消_关于POI锁定保护Excel表格后的操作