七、STM32入门学习 之 FSMC与SRAM
FSMC连接的外部存储器可以是:静态存储器、NAND闪存、PC卡。其中静态存储区包括:SRAM、NOR闪存和PSARM。从FSMC的角度看,可以把外部存储器划分为固定大小为256M字节的四个存储块,见下图。本节只学习FSMC的存储块1关于SRAM的部分内容。
·
一、FSMC
FSMC为灵活的静态内存控制,FSMC模块能够与同步或异步存储器和16位PC存储器卡接口,它的主要作用是:
- 将AHB传输信号转换到适当的外部设备协议
- 满足访问外部设备的时序要求
FSMC连接的外部存储器可以是:静态存储器、NAND闪存、PC卡。其中静态存储区包括:SRAM、NOR闪存和PSARM。
1、FSMC框图:

2、外部设备地址映像
从FSMC的角度看,可以把外部存储器划分为固定大小为256M字节的四个存储块,见下图。
- 存储块1用于访问最多4个NOR闪存或PSRAM存储设备。这个存储区被划分为4个NOR/PSRAM区并有4个专用的片选。
- 存储块2和3用于访问NAND闪存设备,每个存储块连接一个NAND闪存。
- 存储块4用于访问PC卡设备

3、NOR和PSRAM地址映像
- HADDR[27:26]位用于选择四个存储块之一:

- HADDR是需要转换盗版外部存储器的内部AHB地址线。
- HADDR[27:0]包含内部存储块区分HADDR[27:26] 和 外部存储器地址HADDR[25:0]。其中HADDR是字节地址,而存储器访问不一定都是字节访问,这个还受到连接到外部存储器的数据宽度决定,如下表所示:

**注意:**对于16位宽度的外部存储器,在内部的HADDR[25:1]将产生外部存储器的地址FSMC_A[24:0]。且不论外部存储器的宽度是16位还是8位,FSMC_A[0]始终应该连到外部存储器的地址线A[0]。
本节只学习FSMC的存储块1关于SRAM的部分内容。
二、FSMC与SRAM传输
#include "stm32f10x.h"
#include <stdio.h>
// 定义SRAM的起始地址,使用FSMC Bank1
#define SRAM_BANK_ADDR ((uint32_t)0x68000000)
// FSMC初始化函数
void FSMC_SRAM_Init(void)
{
FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
FSMC_NORSRAMTimingInitTypeDef p;
GPIO_InitTypeDef GPIO_InitStructure;
// 使能FSMC和GPIO时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG, ENABLE);
// 配置FSMC相关的GPIO引脚 - 数据线(D0 - D15)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = 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_Init(GPIOE, &GPIO_InitStructure);
// 配置FSMC相关的GPIO引脚 - 地址线(A0 - A18)
GPIO_InitStructure.GPIO_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_Init(GPIOF, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
GPIO_Init(GPIOG, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 ;
GPIO_Init(GPIOD, &GPIO_InitStructure);
// 配置FSMC相关的GPIO引脚 - 控制信号
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 ;// OE,WE
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;// NE3 片选
GPIO_Init(GPIOG, &GPIO_InitStructure);
// 配置FSMC时序,根据IS62WV51216BLL-55TLI数据手册调整
p.FSMC_AddressSetupTime = 0x01; //地址建立时间(ADDSET)为2个HCLK 1/72M=27.6ns
p.FSMC_DataSetupTime = 0x02; //数据保持时间(DATAST)为3个HCLK 3/72M=41.4ns
p.FSMC_AccessMode = FSMC_AccessMode_A; //模式A
//不需要配置的成员变量
p.FSMC_BusTurnAroundDuration = 0x00;
p.FSMC_AddressHoldTime = 0x00; //地址保持时间(ADDHLD)模式A未用到
p.FSMC_CLKDivision = 0x00;
p.FSMC_DataLatency = 0x00;
// 配置FSMC NOR/SRAM初始化结构体
FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM3;// 这里我们使用NE3 ,也就对应BTCR[4],[5]。
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
FSMC_NORSRAMInitStructure.FSMC_MemoryType =FSMC_MemoryType_SRAM;// FSMC_MemoryType_SRAM; //SRAM
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;//存储器数据宽度为16bit
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode =FSMC_BurstAccessMode_Disable;// FSMC_BurstAccessMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait=FSMC_AsynchronousWait_Disable;
FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; //存储器写使能
FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; // 读写使用相同的时序
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
// 初始化FSMC Bank3
FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
// 使能FSMC Bank3
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3, ENABLE);
}
// 向SRAM写入一个半字(16位)数据
void SRAM_WriteHalfWord(uint32_t WriteAddr, uint16_t Data)
{
*(uint16_t *)(SRAM_BANK_ADDR + WriteAddr) = Data;
}
// 从SRAM读取一个半字(16位)数据
uint16_t SRAM_ReadHalfWord(uint32_t ReadAddr)
{
uint32_t p =(SRAM_BANK_ADDR + ReadAddr);
uint16_t data=*(uint16_t *)p;
printf("address=%x,data=%x \n",p,data );
return data;
}
// 向SRAM写入数组数据
void SRAM_WriteBuffer(uint32_t WriteAddr, uint16_t *pBuffer, uint32_t NumHalfwordToWrite)
{
for (uint32_t i = 0; i < NumHalfwordToWrite; i++)
{
SRAM_WriteHalfWord(WriteAddr, pBuffer[i]);
WriteAddr += 2;
}
}
// 从SRAM读取数组数据
void SRAM_ReadBuffer(uint32_t ReadAddr, uint16_t *pBuffer, uint32_t NumHalfwordToRead)
{
for (uint32_t i = 0; i < NumHalfwordToRead; i++)
{
pBuffer[i] = SRAM_ReadHalfWord(ReadAddr);
// printf("%x ", pBuffer[i] );
ReadAddr += 2;
}
}
void USART_Configure(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init( GPIOA, &GPIO_InitStruct);
//USART配置
USART_InitTypeDef USART_InitStruct;
USART_InitStruct.USART_BaudRate=115200;
USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
USART_InitStruct.USART_Mode = USART_Mode_Tx;
USART_InitStruct.USART_Parity = USART_Parity_No;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_Init(USART1,&USART_InitStruct);
USART_Cmd(USART1,ENABLE);
}
void USART_SendChar(uint16_t ch){
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET){
}
USART_SendData(USART1,ch);
}
int fputc(int ch, FILE* file)
{
USART_SendChar((uint16_t)ch);
return ch;
}
int main(void)
{
uint16_t writeData = 0x0010;
uint16_t readData;
uint16_t bufferWrite[5] = {0x1111, 0x2222, 0x3333, 0x4444, 0x5555};
uint16_t bufferRead[5];
USART_Configure();
printf("USART_Init succeed!\n");
// 初始化FSMC和SRAM
FSMC_SRAM_Init();
printf("FSMC_SRAM_Init succeed!\n");
// 写入一个 半字 数据并读取验证
SRAM_WriteHalfWord(0, writeData);
printf("Wrote data: 0x%04x to address 0x%08x\n", writeData, SRAM_BANK_ADDR);
readData = SRAM_ReadHalfWord(0);
printf("Read data: 0x%04x from address 0x%08x\n", readData, SRAM_BANK_ADDR);
// 写入数组数据并读取验证
SRAM_WriteBuffer(0, bufferWrite, 5);
SRAM_ReadBuffer(0, bufferRead, 5);
for (int i = 0; i < 5; i++)
{
if (bufferRead[i] != bufferWrite[i])
{
// printf("write and read buffer failed at index %d\n", i);
}
printf("%x ", bufferRead[i] );
}
while (1)
{
// 主循环可添加其他任务
}
}

更多推荐



所有评论(0)