STM32F407通过FSMC扩展外部SRAM和NAND FLASH

news/2025/2/19 1:30:57/

1 扩展外部SRAM

1.1 地址情况

 FSMC控制器的存储区分为4个区(Bank),每个区256MB。其中,Bank1可以用于连接SRAM、NOR FLASH、PSRAM,还可以连接TFT LCD。Bank1的地址范围是0x60000000~0x6FFFFFFF。Bank1又分为4个子区,每个子区寻址空间是64MB,占用26位地址线。4个子区的地址范围分别如下。

Bank 1子区1:0x60000000~0x63FFFFFF。
Bank 1子区2:0x64000000~0x67FFFFFF。
Bank 1子区3:0x68000000~0x6BFFFFFF(开发板上用于外扩SRAM)。
Bank 1子区4:0x6C000000~0x6FFFFFFF(开发板上用于连接TFTLCD)。

 每个子区有一个专用的片选信号。下面将使用Bank 1子区3连接一个1MB的SRAM芯片,为系统扩展内存。

下述引脚都可以直接通过STM32CubeMX配置:

A0至A18是19根地址线,连接FSMC的19根地址线,即FSMC_A0至FSMC_A18。
I/O0至I/O15是16位数据线,连接FSMC的FSMC_D0至FSMC_D15数据线。
CE是芯片的片选信号,连接MCU的FSMC_NE3(PG10引脚),也就是Bank 1子区3的片选信号。
OE是输出使能信号,连接MCU的FSMC_NOE(PD4引脚),是读数据时的使能信号。
WE是写使能信号,连接MCU的FSMC_NWE(PD5引脚),是写数据使能信号。
UB是高字节使能信号,连接MCU的FSMC_NBL1(PE1引脚)。
LB是低字节使能信号,连接MCU的FSMC_NBL0(PE0引脚)。

这里19根地址线,但是有UB和LB两个脚,可以分别使能高低字节,所以这样总存储量就可以达到2的20次方等于1MB

考虑到FSMC Bank 1-NOR/PSRAM3起始地址为0x6800 0000,因此如果要访问IS62WV51216芯片全部的1024KB数据的地址范围应该为0x6800 0000~0x680F FFFF

1.2 实验材料

本实验使用STM32F407ZGT6开发板,我买的开发板引脚顺序如下,注意顺序

SRAM芯片型号为IS62WV51216,其为16位宽512K容量的静态随机存取存储器,原理图如下

我这个开发板背面有带预留SRAM焊点,如果没有,可以自己画个板子做一下

1.3 STM32CubeMX配置过程

这里选择1 2 3 4配置无所谓,主要是下面

片选信号选NE3,存储器种类选SRAM,地址位数选19位(注意虽然存储容量为1MB,但是有19根地址线,数据位数16位,勾选Byte enable

不用修改引脚,自动配置都没问题

参数如下:

1.4 测试代码

打开Keil工程,代码如下:

/*定义SRAM地址*/
#define SRAM_ADDR_BEGIN		0x68000000UL //Bank1 子区3的 SRAM起始地址
#define SRAM_ADDR_HALF		0x68080000UL //SRAM 中间地址 512K字节
#define SRAM_ADDR_END	    0x680FFFFFUL //SRAM 结束地址 1024K字节
int fputc(int ch, FILE *f)
{HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);return ch;
}
/*用HAL函数写入数据*/
void SRAM_WriteByFunc(void)
{//1.写入字符串uint32_t *pAddr = (uint32_t *)(SRAM_ADDR_BEGIN);	//给指针赋值uint8_t strIn[] = "Moment in UPC";uint16_t dataLen = sizeof(strIn); //数据长度,字节数,包括最后的结束符'\0’if(HAL_SRAM_Write_8b(&hsram3, pAddr, strIn, dataLen) == HAL_OK){printf("Write string at 0x6800 0000:");printf("%s\r\n",strIn);flg=1;}//2.写入一个随机数uint32_t num=0;pAddr=(uint32_t *)(SRAM_ADDR_BEGIN+256);	//指针重新赋值HAL_RNG_GenerateRandomNumber(&hrng, &num);	//产生32位随机数if(HAL_SRAM_Write_32b(&hsram3, pAddr, &num, 1) == HAL_OK){printf("Write 32b number at 0x6800 0100");printf("0x%x\r\n", num);	flg=2;}printf("-----------------------------------------\r\n");
}/*用HAL函数读取数据*/
void SRAM_ReadByFunc(void)
{//1.读取字符串uint32_t *pAddr = (uint32_t *)(SRAM_ADDR_BEGIN);	//给指针赋值uint8_t strOut[30];uint16_t dataLen = 30;if(HAL_SRAM_Read_8b(&hsram3, pAddr, strOut, dataLen) == HAL_OK){printf("Read string at 0x6800 0000:");printf("%s\r\n", strOut); }//2.读取一个uint32_t数uint32_t num=0;pAddr=(uint32_t *)(SRAM_ADDR_BEGIN+256);	//指针重新赋值,指向一个新的地址if(HAL_SRAM_Read_32b(&hsram3, pAddr, &num, 1) == HAL_OK){printf("Read 32b number at 0x6800 0100:");printf("0x%x\r\n", num);}printf("-----------------------------------------\r\n");
}
while (1)
{SRAM_WriteByFunc();HAL_Delay(1000);SRAM_ReadByFunc();HAL_Delay(1000);
}

2 扩展外部NAND FLASH

2.1 实验材料

SRAM芯片型号为MT29F4G08,原理图如下:

2.2 STM32CubeMX配置过程

片选信号选择NCE3,数据位数为8位,参数配置如下:

2.3 测试代码

static NAND_IDTypeDef NAND_ID;
static HAL_StatusTypeDef res;
res = HAL_NAND_Read_ID(&hnand1, &NAND_ID);
static NAND_AddressTypeDef pAddress;
pAddress.Block = 1;
pAddress.Page = 2;
pAddress.Plane = 0;
static uint8_t pBuffer[2048];
for(uint16_t i = 0; i < 2048; i++)
{pBuffer[i] = 2+i;
}
HAL_NAND_Erase_Block(&hnand1, &pAddress);
res = HAL_NAND_Read_Page_8b(&hnand1, &pAddress, pBuffer, 1);
if(HAL_OK == res)
{HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
}
else
{HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);
}
for(uint16_t i = 0; i < 2048; i++)
{pBuffer[i] = 2+i;
}
res = HAL_NAND_Write_Page_8b(&hnand1, &pAddress, pBuffer, 1);
if(HAL_OK == res)
{HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
}
else
{HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);
}
for(uint16_t i = 0; i < 2048; i++)
{pBuffer[i] = 4+i;
}	
res = HAL_NAND_Read_Page_8b(&hnand1, &pAddress, pBuffer, 1);
if(HAL_OK == res)
{HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
}
else
{HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);
}


http://www.ppmy.cn/news/1572396.html

相关文章

本地事务简介

本地事务简介 1 事务基本性质 数据库事务的几个特性&#xff1a;原子性(Automicity)、一致性(Consistency)、隔离性或独立性(islation)和持久性(Durability)&#xff0c;简称ACID。 原子性&#xff1a;一系列的操作&#xff0c;其整体不可拆分&#xff0c;要么同时成功&#…

【一文读懂】HTTP与Websocket协议

HTTP协议 概述 HTTP (Hypertext Transfer Protocol)&#xff0c;即超文本传输协议&#xff0c;是一种用于在客户端和服务器之间传输超文本&#xff08;例如网页、图片、音频、视频等&#xff09;的通信协议。它是万维网&#xff08;WWW&#xff09;的基础&#xff0c;负责在浏…

DeepSeek官方发布R1模型推荐设置

今年以来&#xff0c;DeepSeek便在AI领域独占鳌头&#xff0c;热度一骑绝尘。其官方App更是创造了惊人纪录&#xff0c;成为史上最快突破3000万日活的应用&#xff0c;这一成绩无疑彰显了它在大众中的超高人气与强大吸引力。一时间&#xff0c;各大AI及云服务厂商纷纷投身其中&…

Node.js 中的 Event 模块详解

Node.js 中的 Event 模块是实现事件驱动编程的核心模块。它基于观察者模式&#xff0c;允许对象&#xff08;称为“事件发射器”&#xff09;发布事件&#xff0c;而其他对象&#xff08;称为“事件监听器”&#xff09;可以订阅并响应这些事件。这种模式非常适合处理异步操作和…

Day 38 卡玛笔记

这是基于代码随想录的每日打卡 62. 不同路径 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。…

【愚公系列】《Python网络爬虫从入门到精通》008-正则表达式基础

标题详情作者简介愚公搬代码头衔华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,亚马逊技领云博主,51CTO博客专家等。近期荣誉2022年度…

2025年如何选择合适的微服务工具

选择合适的工具是成功实施微服务架构的关键&#xff0c;而2025年市场上可供选择的工具种类更加丰富&#xff0c;这也让开发者需要更为谨慎地做出决策。首先&#xff0c;需要根据团队的技术栈选择合适的开发框架。例如&#xff0c;Java开发者可以选择Spring Boot&#xff0c;而N…

Maven 中的 `<dependencyManagement>` 标签及其高级用法

在 Maven 构建工具中&#xff0c;<dependencyManagement> 标签是用于集中管理项目依赖版本的一个非常重要的功能。它通常应用于父项目&#xff0c;允许子项目继承和管理依赖版本&#xff0c;避免在每个子项目中重复配置版本号&#xff0c;简化依赖管理并保持项目的一致性…