STM32CubeMX系列 | 外部SRAM

发布者:幸福花开最新更新时间:2023-03-23 来源: zhihu关键字:STM32CubeMX系列  外部SRAM  内存 手机看文章 扫描二维码
随时随地手机看文章

1.外部SRAM简介

本例程使用的STM32F103ZET6本身有64K字节的SRAM,一般应用已经足够;不过在一些对内存要求高的场合,比如跑算法或者GUI等,就需要外扩SRAM来满足大内存使用的需求。这里我们使用了一颗256K字节容量的SRAM芯片:IS62WV12816,利用STM32F1的FSMC控制该SRAM芯片,实现对该SRAM芯片的访问控制

IS62WV12816是一种16位宽128K(128*2,即256K字节)容量的CMOS静态内存芯片,它有高速访问、低功耗、兼容TTL电平接口、全静态操作(不需要刷新和时钟电路)、三态输出和字节控制(支持高/低字节控制)等特点

IS62WV12816的引脚以及对应的引脚功能如下图示:

A0 ~ A16为地址线,总共17根地址线(可访问 217 = 128K字节空间);I/O0 ~ I/O15为数据线,总共16根数据线;CS1(低电平有效)和CS2(高电平有效)都是片选信号;WE为输入使能信号(写信号);OE为输出使能信号(读信号);UB和LB分别是高字节和低字节控制信号

FSMC的相关介绍可参考TFTLCD显示例程中的FSMC介绍部分

2. 硬件设计

D1指示灯用来提示系统运行状态,按键用来控制IS62WV12816数据读写,TFTLCD和串口1用来显示读写的内容

  • D1指示灯

  • K_UP/K_DOWN

  • USART1

  • TFTLCD模块

  • IS62WV12816

电路图中可以看到IS62WV12816和STM32F1的连接线路: A0 ~ A16连接在FSMC_A0 ~ FSMC_A16上(连接顺序可以打乱,因为地址是固定的) I/O0 ~ I/O15连接在FSMC_D0 ~ FSMC_D15上(连接顺序不能打乱,否则读写数据将出错) UB和LB连接在FSMC_NBL1 和 FSMC_NBL0上 OE和WE分别连接在FSMC_NOE 和 FSMC_NWE上 CE连接在FSMC_NE3上

由于TFTLCD核SRAM共用FSMC总线,因此他们通过不同片选分时复用,互不影响

3. 软件设计

3.1 STM32CubeMX设置

  • RCC设置外接HSE,时钟设置为72M

  • PC0设置为GPIO推挽输出模式、上拉、高速、默认输出电平为高电平

  • PA0设置为GPIO输入模式、下拉模式;PE3设置为GPIO输入模式、上拉模式

  • USART1选择为异步通讯方式,波特率设置为115200Bits/s,传输数据长度为8Bit,无奇偶校验,1位停止位

  • 激活FSMC,详细请参考TFTLCD显示章节的设置

  • 输入工程名,选择工程路径(不要有中文),选择MDK-ARM V5;勾选Generated periphera initialization as a pair of ‘.c/.h’ files per IP ;点击GENERATE CODE,生成工程代码

由于TFTLCD使用的Bank1_sector4和SRAM使用的Bank1_sector3无法同时在CubeMX里设置分时复用,因此需要单独创建SRAM的FSMC初始化函数(可自行创建,也可另外创建一个CubeMX工程,按下图设置后将生成的相关FSMC初始化代码拷贝到当前工程源码中并稍作修改)


3.2 MDK-ARM编程

  • 添加按键驱动文件key.c和key.h,参考按键输入例程

  • 添加TFTLCD驱动文件tftlcd.c 和tftlcd.h,参考TFTLCD显示例程

  • 添加IS62WV12816芯片驱动文件sram.c和sram.h

#define Bank1_SRAM3_ADDR    ((uint32_t)(0x68000000))    //Bank1区域3的起始地址 

SRAM_HandleTypeDef SRAM_Handler;    //定义SRAM句柄

//SRAM的FSMC初始化函数

void FSMC_SRAM_Init(void){  

    GPIO_InitTypeDef GPIO_InitStruct;

    FSMC_NORSRAM_TimingTypeDef FSMC_ReadWriteTim; 

    __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();               

    GPIO_InitStruct.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;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

    HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3 

                         |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_10;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

    HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

    GPIO_InitStruct.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;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

    HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11 

                          |GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1 

                          |GPIO_PIN_4|GPIO_PIN_5;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);  


    SRAM_Handler.Instance=FSMC_NORSRAM_DEVICE;                

    SRAM_Handler.Extended=FSMC_NORSRAM_EXTENDED_DEVICE;    


    SRAM_Handler.Init.NSBank=FSMC_NORSRAM_BANK3;                        //使用NE3

    SRAM_Handler.Init.DataAddressMux=FSMC_DATA_ADDRESS_MUX_DISABLE;     //地址/数据线不复用

    SRAM_Handler.Init.MemoryType=FSMC_MEMORY_TYPE_SRAM;                 //SRAM

    SRAM_Handler.Init.MemoryDataWidth=FSMC_NORSRAM_MEM_BUS_WIDTH_16;    //16位数据宽度

    SRAM_Handler.Init.BurstAccessMode=FSMC_BURST_ACCESS_MODE_DISABLE;   //不使能突发访问

    SRAM_Handler.Init.WaitSignalPolarity=FSMC_WAIT_SIGNAL_POLARITY_LOW; //等待信号的极性(突发模式)

    SRAM_Handler.Init.WaitSignalActive=FSMC_WAIT_TIMING_BEFORE_WS;      

    SRAM_Handler.Init.WriteOperation=FSMC_WRITE_OPERATION_ENABLE;       //写使能

    SRAM_Handler.Init.WaitSignal=FSMC_WAIT_SIGNAL_DISABLE;          

    SRAM_Handler.Init.ExtendedMode=FSMC_EXTENDED_MODE_DISABLE;          //读写使用相同的时序

    SRAM_Handler.Init.AsynchronousWait=FSMC_ASYNCHRONOUS_WAIT_DISABLE;

    SRAM_Handler.Init.WriteBurst=FSMC_WRITE_BURST_DISABLE;              //禁止突发写

    //FSMC读时序控制器

    FSMC_ReadWriteTim.AddressSetupTime=0x00;        //地址建立时间(ADDSET)为1个HCLK

    FSMC_ReadWriteTim.AddressHoldTime=0x00;         //地址保持时间(ADDHLD)模式A未用到

    FSMC_ReadWriteTim.DataSetupTime=0x08;           //数据保持时间(DATAST)为9个HCLK

    FSMC_ReadWriteTim.BusTurnAroundDuration=0X00;

    FSMC_ReadWriteTim.AccessMode=FSMC_ACCESS_MODE_A;    //模式A

    HAL_SRAM_Init(&SRAM_Handler,&FSMC_ReadWriteTim,&FSMC_ReadWriteTim); 

}

//n向指定地址写数据

void FSMC_SRAM_WriteBuffer(uint8_t *pBuffer,uint32_t WriteAddr,uint32_t n){

    for(;n!=0;n--){     // n表示要连续写入的字节个数

        *(vu8*)(Bank1_SRAM3_ADDR + WriteAddr) = *pBuffer;

        WriteAddr++;    //要写入的地址

        pBuffer++;      //要写入的数据的指针

    }

}

//从指定地址读数据

void FSMC_SRAM_ReadBuffer(uint8_t *pBuffer,uint32_t ReadAddr,uint32_t n){

    for(;n!=0;n--){     // n表示要连续读出的字节个数

        *pBuffer++=*(vu8*)(Bank1_SRAM3_ADDR+ReadAddr);  //存放读出的数据

        ReadAddr++;     //要读出的起始地址

    }

}

//      

void ExSRAM_Cap_Test(uint16_t x,uint16_t y){

    uint8_t writeData = 0xf0, readData;

    uint16_t cap=0;

    uint32_t addr;  

    addr = 1024;    //从1KB位置开始计算    

    LCD_ShowString(x,y,239,y+16,16,"ExSRAM Cap:   0KB"); 


    while(1){

        FSMC_SRAM_WriteBuffer(&writeData, addr, 1);

        FSMC_SRAM_ReadBuffer(&readData,addr,1);


        if(readData == writeData){  //检查读出的数据是否与写入的数据一样

            cap++;      //如果相同表示写入/读出成功,容量加1(单位KB)

            addr += 1024;   //地址加1024

            readData = 0;

            if(addr > 256 * 1024)   //IS62WV12816的容量为256KB

                break;   

        }

        else

            break;  

    }

    LCD_ShowxNum(x+11*8,y,cap,4,16,0);  //LCD上显示内存容量

    printf("SRAM Menmory Size:%dKBrn",cap);

}

在main.c文件下编写SRAM测试代码

int main(void){

    /* USER CODE BEGIN 1 */

    uint8_t key;

    uint8_t text_buf[] = "This is SRAM testing...";

    uint8_t textlen = sizeof(text_buf);

    uint8_t read_buf[textlen];

    /* USER CODE END 1 */

    HAL_Init();

    SystemClock_Config();

    MX_GPIO_Init();

    MX_FSMC_Init();

    MX_USART1_UART_Init();

    /* USER CODE BEGIN 2 */

    TFTLCD_Init();

    FSMC_SRAM_Init();


    FRONT_COLOR=BROWN;

    LCD_DrawRectangle(5,5,235,95);

    FRONT_COLOR=BLACK;

    LCD_ShowString(10,10,tftlcd_data.width,tftlcd_data.height,16,"ANDYXI STM32F1");

    LCD_ShowString(10,30,tftlcd_data.width,tftlcd_data.height,16,"STM32CubeMx SRAM");

    LCD_ShowString(10,50,tftlcd_data.width,tftlcd_data.height,16,"ExSRAM Test");

    LCD_ShowString(10,70,tftlcd_data.width,tftlcd_data.height,16,"K_UP:Write   K_DOWN:Read");


    FRONT_COLOR=RED;

    ExSRAM_Cap_Test(10,110); 

    FRONT_COLOR=MAGENTA;

    LCD_ShowString(10,130,tftlcd_data.width,tftlcd_data.height,16,"Write:");

    LCD_ShowString(10,150,tftlcd_data.width,tftlcd_data.height,16,"Read :");

  /* USER CODE END 2 */


  /* Infinite loop */

  /* USER CODE BEGIN WHILE */

    while(1){

        key = KEY_Scan(0);

        if(key == KEY_UP_PRES){     //KEY_UP按下写数据到SRAM

            FSMC_SRAM_WriteBuffer(text_buf,0,textlen);

            printf("SRAM_Write:%srn",text_buf);

[1] [2]
关键字:STM32CubeMX系列  外部SRAM  内存 引用地址:STM32CubeMX系列 | 外部SRAM

上一篇:STM32CubeMX系列 | ADXL345传感器
下一篇:STM32CubeMX系列 | SD卡

推荐阅读最新更新时间:2024-11-11 14:21

三星2020年推16nm DRAM内存,15nm恐成DRAM终点
三星不仅是智能手机市场的老大,更重要的是三星还掌握了产业链至关重要的DRAM内存、NAND闪存及OLED屏幕,这三大部件上三星遥遥领先其他对手,手机OLED面板上更是占据95%以上的份额。下面就随半导体小编一起来了解一下相关内容吧。 在DRAM内存市场上,三星不仅产能、份额最高,技术也是最领先的,去年率先量产18nm工艺,今年将完成17nm DRAM内存研发,2018年量产,2020年则会推出16nm工艺的DRAM内存芯片。     三星2020年推16nm DRAM内存,15nm恐成DRAM终点 在18nm工艺之后三星还将开发17nm、16nm DRAM芯片 与CPU等芯片相比,DRAM内存在20nm节点之后也放缓了速
[半导体设计/制造]
Android系统的内存管理研究
1 Android系统概述 Android是Google(谷歌)公司开发的一款专门为移动设备打造的操作系统。2005年谷歌公司收购Android Inc公司后,于2007年研发了基于Linux的操作系统Android。2008年,TMobile与HTC公司共同研发了第一款Android手机——HTC G1。Android的发展速度非常惊人,仅仅3年便超过了Symbian系统,并且有强大的OEM支持以及众多的开发者。 Android基于Linux平台,主要由操作系统、中间件、用户界面和应用软件组成。采用的是软件堆栈的结构,操作系统的底层仅提供最基本的系统功能。在Android系统中,基本上使用的是标准的Linux2.6内核,
[嵌入式]
2017款三星J3渲染图曝光:骁龙430+2G内存
据国外网站Sammobile报道,近日知名爆料大神在推特上放出2017年款Galxay J3的渲染图。这款手机与之前的Galaxy J3外形区别不大。值得一提的是,这款手机采用三星传统的设计方式,实体Home键的两边设有两个电容屏按钮。总体来看,这款安卓入门机还是有一定竞争力。 2017款三星J3渲染图曝光:骁龙430+2G内存(图片来自于推特)   三星在今年年中的时候就已经推出了Galaxy J3 Pro,从各种配置上来看,2017年款Galaxy J3都在其基础上进行了一定的升级。整体造型方面,2017款Galaxy J3更加的圆滑,并沿用了之前的金属质感设计。正面延续三星一贯的设计语言,配有实体Home键。   在配
[手机便携]
西部数据终于出手!174 亿美元收购东芝内存芯片业务
  据不愿透露姓名的消息人士表示,一个包括 西部数据 在内的财团向 东芝 出价 1.9 万亿日元( 174 亿美元)收购其内存芯片业务。其中, 西部数据 将通过可转换债券提供 1500 亿日元( 13.72 亿美元),并且不要求得到企业的投票权。下面就随网络通信小编一起来了解一下相关内容吧。   据悉,该财团还包括美国私募股权公司 KKR & Co 、具有政府背景的日本产业革新机构(INCJ)和日本政策投资银行,这几家机构各出资 3000 亿日元( 27.4 亿美元)。    西部数据 在本月初向 东芝 高层提出这项提案,若 东芝 接受,西部数据将撤销双方之间的诉讼,西部数据本周已派人抵达日本进一步交涉,东芝要求必须维持现有人员
[网络通信]
单片机C语言几种内存泄露总结
日常项目中碰到的内存泄露无非有以下几种: (1) 堆内存泄漏(Heap leak)。堆内存指的是程序运行中根据需要分配通过malloc,realloc new等从堆中分配的一块内存,再是完成后必须通过调用对应的 free或者delete 删掉。如果程序的设计的错误导致这部分内存没有被释放,那么此后这块内存将不会被使用,就会产生Heap Leak. 这是最常见的内存泄露。 (2)系统资源泄露(Resource Leak).主要指程序使用系统分配的资源比如 Bitmap,handle ,SOCKET等没有使用相应的函数释放掉,导致系统资源的浪费,严重可导致系统效能降低,系统运行不稳定 如果您创建一个可接合的POSIX线程,
[单片机]
家居监控:如何选择内存技术以适应新型系统架构
近年来,人工智能(AI)和机器学习(ML)技术产品需求激增。但研究发现,在自动驾驶等应用中,让机器学习人类与生俱来的技能和判断力,简直难若登天。尽管在部分领域,有关AI的炒作已经超越现实,仍有不少采用ML功能的真实产品开始逐渐吸引消费者的目光。例如采用智能视觉的安防和家居监控系统,就拥有巨大的潜力:分析公司Strategy Analytics预测,2019年至2023年间,家居安防摄像头市场的增长率将超过50%,市值将从80亿美元增至130亿美元。 由于影像和场景识别被认为是最适合发展ML技术的功能之一,智能摄像头得以蓬勃发展。家居监控系统中的智能功能可用于: 看护老年人或弱势群体 监测婴儿睡眠时呼吸是否正常 识别住
[嵌入式]
家居监控:如何选择<font color='red'>内存</font>技术以适应新型系统架构
三星电子宣布量产业界最薄LPDDR5X内存封装,较上代厚度减少约9%
8 月 6 日消息,三星电子今日宣布启动业界最薄的 LPDDR5X 内存封装量产。该新产品封装高度为 0.65mm,较上代产品的 0.71mm 降低约 9%,耐热性能提升了 21.2%。 三星电子本次推出的 LPDDR5X 内存封装基于 12nm 级 LPDDR DRAM,采用了 4 堆栈、每堆栈 2 层的结构设计,提供 12GB、16GB 两种容量版本。 在制造该内存封装的过程中,三星电子优化了 PCB 和环氧树脂模塑料(IT之家注:Epoxy Molding Compound,简称 EMC)技术,并结合了晶圆背面研磨工艺,使其成为最薄的 12GB 及以上容量 LPDDR DRAM 模组。 更低的封装高度,加上更优异的耐
[半导体设计/制造]
LG G Watch智能手表已可成功刷入第三方ROM
   搭载Android Wear的LG G Watch刚刚发布不久,目前首款第三方ROM就已经诞生,此款Gohma ROM由开发者jakeday制作。   据开发者介绍,此款ROM仅有细微修改,可以提高手表性能、流畅度,并可大幅提升续航能力。   据悉,LG G Watch的bootloader是可以解锁的,所以开发者表示在制作ROM时并没有遇到太多麻烦,很快就完成了修改 。
[手机便携]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved