无法在 STM32F429I-Disco 板上使用 FMC 读取 from/write 到外部 SRAM
Cannot read from/write to external SRAM using FMC on STM32F429I-Disco board
我目前正在使用带有完整 FMC(F407 上的 FSMC)引脚的 STM32F429I Disco 板尝试连接 Waveshare 的 IS62WV51216BLL SRAM 模块,但没有成功。
下面给出了主要的 SRAM test/initialization 代码。
对 post 的长度表示歉意。我已经尝试检查并与互联网上所有可用的代码进行比较,但不知何故,它只是没有初始化[未返回测试值]
代码是在 IAR 工作台中构建和调试的
SRAM_ADR
#define SRAM_ADR ((uint32_t)0x60000000)
#define SRAM_END SRAM_ADR + ((uint32_t)0x7FFFF) // not required for test
SRAM初始化、读写代码
//--------------------------------------------------------------
// Includes
//--------------------------------------------------------------
#include "stm32_ub_sram.h"
//--------------------------------------------------------------
// Internal Function
//--------------------------------------------------------------
void P_SRAM_InitIO(void);
void P_SRAM_InitFMC(void);
//--------------------------------------------------------------
// Initialize External SRAM
// Return_value :
// -> ERROR , when SRAM does not configured properly
// -> SUCCESS , when SRAM configured successfully
//--------------------------------------------------------------
ErrorStatus UB_SRAM_Init(void)
{
ErrorStatus ret_value = ERROR;
uint16_t oldvalue, isvalue;
// IO-Lines initialization
P_SRAM_InitIO();
// FMC initialization
P_SRAM_InitFMC();
//-----------------------------------------
// Check the SRAM live or dead
// Depends on testing the Adress 0x00
//-----------------------------------------
oldvalue = UB_SRAM_Read(0x00);
UB_SRAM_Write(0x00, 0x5A3C);
isvalue = UB_SRAM_Read(0x00);
UB_SRAM_Write(0x00, oldvalue);
if(isvalue == 0x5A3C)
ret_value = SUCCESS; // RAM verification
return(ret_value);
}
//--------------------------------------------------------------
// Internal Function
// Initialize all IO-Pins for the SRAM
//--------------------------------------------------------------
void P_SRAM_InitIO(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable GPIOs clock */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE
| RCC_AHB1Periph_GPIOF | RCC_AHB1Periph_GPIOG, ENABLE);
/* Common GPIO configuration */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; // STM32F429I Only support speeds up to 90Mhz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
/*-- SRAM GPIOs Configuration --------------------------------------------------*/
/*
+-------------------+------------------+-------------------+
| PD14 <-> FMC_D0 | PF0 <-> FMC_A0 | PE0 <-> FMC_NBL0 |
| PD15 <-> FMC_D1 | PF1 <-> FMC_A1 | PE1 <-> FMC_NBL1 |
| PD0 <-> FMC_D2 | PF2 <-> FMC_A2 | PD4 <-> FMC_NOE |
| PD1 <-> FMC_D3 | PF3 <-> FMC_A3 | PD5 <-> FMC_NWE |
| PE7 <-> FMC_D4 | PF4 <-> FMC_A4 | PD7 <-> FMC_NE1 |
| PE8 <-> FMC_D5 | PF5 <-> FMC_A5 |-------------------+
| PE9 <-> FMC_D6 | PF12 <-> FMC_A6 |
| PE10 <-> FMC_D7 | PF13 <-> FMC_A7 |
| PE11 <-> FMC_D8 | PF14 <-> FMC_A8 |
| PE12 <-> FMC_D9 | PF15 <-> FMC_A9 |
| PE13 <-> FMC_D10 | PG0 <-> FMC_A10 |
| PE14 <-> FMC_D11 | PG1 <-> FMC_A11 |
| PE15 <-> FMC_D12 | PG2 <-> FMC_A12 |
| PD8 <-> FMC_D13 | PG3 <-> FMC_A13 |
| PD9 <-> FMC_D14 | PG4 <-> FMC_A14 |
| PD10 <-> FMC_D15 | PG5 <-> FMC_A15 |
+-------------------| PD11 <-> FMC_A16 |
| PD12 <-> FMC_A17 |
| PD13 <-> FMC_A18 |
| PE3 <-> FMC_A19 |
+------------------+
*/
//-----------------------------------------
// All pins for Port-D initialization
//-----------------------------------------
GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_FMC); // PD0 = FMC_D2
GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_FMC); // PD1 = FMC_D3
GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_FMC); // PD4 = FMC_NOE
GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_FMC); // PD5 = FMC_NWE
// GPIO_PinAFConfig(GPIOD, GPIO_PinSource7, GPIO_AF_FMC); // PD7 = FMC_NE1
GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_FMC); // PD8 = FMC_D13
GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_FMC); // PD9 = FMC_D14
GPIO_PinAFConfig(GPIOD, GPIO_PinSource10, GPIO_AF_FMC); // PD10 = FMC_D15
GPIO_PinAFConfig(GPIOD, GPIO_PinSource11, GPIO_AF_FMC); // PD11 = FMC_A16
GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_FMC); // PD12 = FMC_A17
GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_FMC); // PD13 = FMC_A18
GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_FMC); // PD14 = FMC_D0
GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_FMC); // PD15 = FMC_D1
// Structure for Port-D
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5
// | 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;
// Configure Port-D
GPIO_Init(GPIOD, &GPIO_InitStructure);
//-----------------------------------------
// All pins for Port-E initialization
//-----------------------------------------
GPIO_PinAFConfig(GPIOE, GPIO_PinSource0, GPIO_AF_FMC); // PE0 = FMC_NBL0
GPIO_PinAFConfig(GPIOE, GPIO_PinSource1, GPIO_AF_FMC); // PE1 = FMC_NBL1
// GPIO_PinAFConfig(GPIOE, GPIO_PinSource3, GPIO_AF_FMC); // PE3 = FMC_A19
GPIO_PinAFConfig(GPIOE, GPIO_PinSource7, GPIO_AF_FMC); // PE7 = FMC_D4
GPIO_PinAFConfig(GPIOE, GPIO_PinSource8, GPIO_AF_FMC); // PE8 = FMC_D5
GPIO_PinAFConfig(GPIOE, GPIO_PinSource9, GPIO_AF_FMC); // PE9 = FMC_D6
GPIO_PinAFConfig(GPIOE, GPIO_PinSource10, GPIO_AF_FMC); // PE10 = FMC_D7
GPIO_PinAFConfig(GPIOE, GPIO_PinSource11, GPIO_AF_FMC); // PE11 = FMC_D8
GPIO_PinAFConfig(GPIOE, GPIO_PinSource12, GPIO_AF_FMC); // PE12 = FMC_D9
GPIO_PinAFConfig(GPIOE, GPIO_PinSource13, GPIO_AF_FMC); // PE13 = FMC_D10
GPIO_PinAFConfig(GPIOE, GPIO_PinSource14, GPIO_AF_FMC); // PE14 = FMC_D11
GPIO_PinAFConfig(GPIOE, GPIO_PinSource15, GPIO_AF_FMC); // PE15 = FMC_D12
// Structure for Port-E
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 // | GPIO_Pin_3
| 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;
// Configure Port-E
GPIO_Init(GPIOE, &GPIO_InitStructure);
//-----------------------------------------
// All pins for Port-F initialization
//-----------------------------------------
GPIO_PinAFConfig(GPIOF, GPIO_PinSource0, GPIO_AF_FMC); // PF0 = FMC_A0
GPIO_PinAFConfig(GPIOF, GPIO_PinSource1, GPIO_AF_FMC); // PF1 = FMC_A1
GPIO_PinAFConfig(GPIOF, GPIO_PinSource2, GPIO_AF_FMC); // PF2 = FMC_A2
GPIO_PinAFConfig(GPIOF, GPIO_PinSource3, GPIO_AF_FMC); // PF3 = FMC_A3
GPIO_PinAFConfig(GPIOF, GPIO_PinSource4, GPIO_AF_FMC); // PF4 = FMC_A4
GPIO_PinAFConfig(GPIOF, GPIO_PinSource5, GPIO_AF_FMC); // PF5 = FMC_A5
GPIO_PinAFConfig(GPIOF, GPIO_PinSource12, GPIO_AF_FMC); // PF12 = FMC_A6
GPIO_PinAFConfig(GPIOF, GPIO_PinSource13, GPIO_AF_FMC); // PF13 = FMC_A7
GPIO_PinAFConfig(GPIOF, GPIO_PinSource14, GPIO_AF_FMC); // PF14 = FMC_A8
GPIO_PinAFConfig(GPIOF, GPIO_PinSource15, GPIO_AF_FMC); // PF15 = FMC_A9
// Structure for Port-F
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;
// Configure Port-F
GPIO_Init(GPIOF, &GPIO_InitStructure);
//-----------------------------------------
// All pins for Port-G initialization
//-----------------------------------------
GPIO_PinAFConfig(GPIOG, GPIO_PinSource0, GPIO_AF_FMC); // PG0 = FMC_A10
GPIO_PinAFConfig(GPIOG, GPIO_PinSource1, GPIO_AF_FMC); // PG1 = FMC_A11
GPIO_PinAFConfig(GPIOG, GPIO_PinSource2, GPIO_AF_FMC); // PG2 = FMC_A12
GPIO_PinAFConfig(GPIOG, GPIO_PinSource3, GPIO_AF_FMC); // PG3 = FMC_A13
GPIO_PinAFConfig(GPIOG, GPIO_PinSource4, GPIO_AF_FMC); // PG4 = FMC_A14
GPIO_PinAFConfig(GPIOG, GPIO_PinSource5, GPIO_AF_FMC); // PG5 = FMC_A15
GPIO_PinAFConfig(GPIOG, GPIO_PinSource10, GPIO_AF_FMC); // PG10 = FMC_NE3
GPIO_PinAFConfig(GPIOG, GPIO_PinSource12, GPIO_AF_FMC); // PG12 = FMC_NE4
// Structure for Port-G
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3
| GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_10 | GPIO_Pin_12;
// Configure Port-G
GPIO_Init(GPIOG, &GPIO_InitStructure);
}
//--------------------------------------------------------------
// Internal Function
// Initialize FSMC for the SRAM
//--------------------------------------------------------------
void P_SRAM_InitFMC(void)
{
FMC_NORSRAMInitTypeDef FMC_NORSRAMInitStructure;
FMC_NORSRAMTimingInitTypeDef FMC_NORSRAMTimingInitStructure;
#if 0
// De-initialize for re-initialize
FMC_NORSRAMDeInit(FMC_Bank1_NORSRAM3); // From FMC_Bank1_NORSRAM1 -> 3
#endif
/* Enable FMC clock */
RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FMC, ENABLE);
//-----------------------------------------
// Structure for Timing
//-----------------------------------------
FMC_NORSRAMTimingInitStructure.FMC_AddressSetupTime = SRAM_FMC_AST; // 3
FMC_NORSRAMTimingInitStructure.FMC_AddressHoldTime = SRAM_FMC_AHT; // 0
FMC_NORSRAMTimingInitStructure.FMC_DataSetupTime = SRAM_FMC_DST; // 3
FMC_NORSRAMTimingInitStructure.FMC_BusTurnAroundDuration = 0;
FMC_NORSRAMTimingInitStructure.FMC_CLKDivision = 0;
FMC_NORSRAMTimingInitStructure.FMC_DataLatency = 0;
FMC_NORSRAMTimingInitStructure.FMC_AccessMode = FMC_AccessMode_A;
//-----------------------------------------
// Structure for Bank-1 / PSRAM-1
//-----------------------------------------
FMC_NORSRAMInitStructure.FMC_Bank = FMC_Bank1_NORSRAM3; // From FMC_Bank1_NORSRAM1 -> 3
FMC_NORSRAMInitStructure.FMC_DataAddressMux = FMC_DataAddressMux_Disable;
FMC_NORSRAMInitStructure.FMC_MemoryType = FMC_MemoryType_SRAM; // Workaround for 'Free GPIO Pin' <- NOR
FMC_NORSRAMInitStructure.FMC_MemoryDataWidth = FMC_NORSRAM_MemoryDataWidth_16b;
FMC_NORSRAMInitStructure.FMC_BurstAccessMode = FMC_BurstAccessMode_Disable;
FMC_NORSRAMInitStructure.FMC_AsynchronousWait = FMC_AsynchronousWait_Disable;
FMC_NORSRAMInitStructure.FMC_WaitSignalPolarity = FMC_WaitSignalPolarity_Low;
FMC_NORSRAMInitStructure.FMC_WrapMode = FMC_WrapMode_Disable;
FMC_NORSRAMInitStructure.FMC_WaitSignalActive = FMC_WaitSignalActive_BeforeWaitState;
FMC_NORSRAMInitStructure.FMC_WriteOperation = FMC_WriteOperation_Enable;
FMC_NORSRAMInitStructure.FMC_WaitSignal = FMC_WaitSignal_Disable;
FMC_NORSRAMInitStructure.FMC_ExtendedMode = FMC_ExtendedMode_Disable;
FMC_NORSRAMInitStructure.FMC_WriteBurst = FMC_WriteBurst_Disable;
FMC_NORSRAMInitStructure.FMC_ReadWriteTimingStruct = &FMC_NORSRAMTimingInitStructure;
FMC_NORSRAMInitStructure.FMC_WriteTimingStruct = &FMC_NORSRAMTimingInitStructure;
// Configure FSMC
FMC_NORSRAMInit(&FMC_NORSRAMInitStructure);
// Enable Bank-1 / PSRAM-1
FMC_NORSRAMCmd(FMC_Bank1_NORSRAM3, ENABLE); // From FMC_Bank1_NORSRAM1 -> 3
}
//--------------------------------------------------------------
// Sends 16-bit value to the external SRAM
//--------------------------------------------------------------
void UB_SRAM_Write(uint32_t adr, uint16_t wert)
{
// Transfer 16-bits data to the memory
*(uint16_t *) (SRAM_ADR + adr) = wert;
}
//--------------------------------------------------------------
// Reads 16-bit value from the external SRAM
//--------------------------------------------------------------
uint16_t UB_SRAM_Read(uint32_t adr)
{
uint16_t ret_wert = 0;
// Read 16-bits data from the memory
ret_wert = *(__IO uint16_t*) (SRAM_ADR + adr);
return(ret_wert);
}
在执行此操作之前,我是否应该检查任何缺失的点?
从软件的角度来看,您的银行选择与基地址不匹配。 FMC 库排列为 4x64Mb(库 1、2、3、4),基地址如下:
bank 1: 0x60000000
bank 2: 0x64000000
bank 3: 0x68000000
bank 4: 0x6C000000
令人困惑的是,ST 将 64Mb 范围称为银行本身,而实际上它们是分配给 NOR/PSRAM 的较大银行 #1 的子银行。
您定义了这个:
#define SRAM_ADR ((uint32_t)0x60000000)
// [...]
FMC_NORSRAMCmd(FMC_Bank1_NORSRAM3, ENABLE);
如您所见,存储区选择 (#3) 和基地址选择 (#1) 不匹配。你需要让它们对齐。
如果您在解决此问题后仍然遇到问题,请查看您的时序计算,当然还有电气连接。
我目前正在使用带有完整 FMC(F407 上的 FSMC)引脚的 STM32F429I Disco 板尝试连接 Waveshare 的 IS62WV51216BLL SRAM 模块,但没有成功。
下面给出了主要的 SRAM test/initialization 代码。 对 post 的长度表示歉意。我已经尝试检查并与互联网上所有可用的代码进行比较,但不知何故,它只是没有初始化[未返回测试值]
代码是在 IAR 工作台中构建和调试的
SRAM_ADR
#define SRAM_ADR ((uint32_t)0x60000000)
#define SRAM_END SRAM_ADR + ((uint32_t)0x7FFFF) // not required for test
SRAM初始化、读写代码
//--------------------------------------------------------------
// Includes
//--------------------------------------------------------------
#include "stm32_ub_sram.h"
//--------------------------------------------------------------
// Internal Function
//--------------------------------------------------------------
void P_SRAM_InitIO(void);
void P_SRAM_InitFMC(void);
//--------------------------------------------------------------
// Initialize External SRAM
// Return_value :
// -> ERROR , when SRAM does not configured properly
// -> SUCCESS , when SRAM configured successfully
//--------------------------------------------------------------
ErrorStatus UB_SRAM_Init(void)
{
ErrorStatus ret_value = ERROR;
uint16_t oldvalue, isvalue;
// IO-Lines initialization
P_SRAM_InitIO();
// FMC initialization
P_SRAM_InitFMC();
//-----------------------------------------
// Check the SRAM live or dead
// Depends on testing the Adress 0x00
//-----------------------------------------
oldvalue = UB_SRAM_Read(0x00);
UB_SRAM_Write(0x00, 0x5A3C);
isvalue = UB_SRAM_Read(0x00);
UB_SRAM_Write(0x00, oldvalue);
if(isvalue == 0x5A3C)
ret_value = SUCCESS; // RAM verification
return(ret_value);
}
//--------------------------------------------------------------
// Internal Function
// Initialize all IO-Pins for the SRAM
//--------------------------------------------------------------
void P_SRAM_InitIO(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable GPIOs clock */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE
| RCC_AHB1Periph_GPIOF | RCC_AHB1Periph_GPIOG, ENABLE);
/* Common GPIO configuration */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; // STM32F429I Only support speeds up to 90Mhz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
/*-- SRAM GPIOs Configuration --------------------------------------------------*/
/*
+-------------------+------------------+-------------------+
| PD14 <-> FMC_D0 | PF0 <-> FMC_A0 | PE0 <-> FMC_NBL0 |
| PD15 <-> FMC_D1 | PF1 <-> FMC_A1 | PE1 <-> FMC_NBL1 |
| PD0 <-> FMC_D2 | PF2 <-> FMC_A2 | PD4 <-> FMC_NOE |
| PD1 <-> FMC_D3 | PF3 <-> FMC_A3 | PD5 <-> FMC_NWE |
| PE7 <-> FMC_D4 | PF4 <-> FMC_A4 | PD7 <-> FMC_NE1 |
| PE8 <-> FMC_D5 | PF5 <-> FMC_A5 |-------------------+
| PE9 <-> FMC_D6 | PF12 <-> FMC_A6 |
| PE10 <-> FMC_D7 | PF13 <-> FMC_A7 |
| PE11 <-> FMC_D8 | PF14 <-> FMC_A8 |
| PE12 <-> FMC_D9 | PF15 <-> FMC_A9 |
| PE13 <-> FMC_D10 | PG0 <-> FMC_A10 |
| PE14 <-> FMC_D11 | PG1 <-> FMC_A11 |
| PE15 <-> FMC_D12 | PG2 <-> FMC_A12 |
| PD8 <-> FMC_D13 | PG3 <-> FMC_A13 |
| PD9 <-> FMC_D14 | PG4 <-> FMC_A14 |
| PD10 <-> FMC_D15 | PG5 <-> FMC_A15 |
+-------------------| PD11 <-> FMC_A16 |
| PD12 <-> FMC_A17 |
| PD13 <-> FMC_A18 |
| PE3 <-> FMC_A19 |
+------------------+
*/
//-----------------------------------------
// All pins for Port-D initialization
//-----------------------------------------
GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_FMC); // PD0 = FMC_D2
GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_FMC); // PD1 = FMC_D3
GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_FMC); // PD4 = FMC_NOE
GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_FMC); // PD5 = FMC_NWE
// GPIO_PinAFConfig(GPIOD, GPIO_PinSource7, GPIO_AF_FMC); // PD7 = FMC_NE1
GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_FMC); // PD8 = FMC_D13
GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_FMC); // PD9 = FMC_D14
GPIO_PinAFConfig(GPIOD, GPIO_PinSource10, GPIO_AF_FMC); // PD10 = FMC_D15
GPIO_PinAFConfig(GPIOD, GPIO_PinSource11, GPIO_AF_FMC); // PD11 = FMC_A16
GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_FMC); // PD12 = FMC_A17
GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_FMC); // PD13 = FMC_A18
GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_FMC); // PD14 = FMC_D0
GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_FMC); // PD15 = FMC_D1
// Structure for Port-D
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5
// | 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;
// Configure Port-D
GPIO_Init(GPIOD, &GPIO_InitStructure);
//-----------------------------------------
// All pins for Port-E initialization
//-----------------------------------------
GPIO_PinAFConfig(GPIOE, GPIO_PinSource0, GPIO_AF_FMC); // PE0 = FMC_NBL0
GPIO_PinAFConfig(GPIOE, GPIO_PinSource1, GPIO_AF_FMC); // PE1 = FMC_NBL1
// GPIO_PinAFConfig(GPIOE, GPIO_PinSource3, GPIO_AF_FMC); // PE3 = FMC_A19
GPIO_PinAFConfig(GPIOE, GPIO_PinSource7, GPIO_AF_FMC); // PE7 = FMC_D4
GPIO_PinAFConfig(GPIOE, GPIO_PinSource8, GPIO_AF_FMC); // PE8 = FMC_D5
GPIO_PinAFConfig(GPIOE, GPIO_PinSource9, GPIO_AF_FMC); // PE9 = FMC_D6
GPIO_PinAFConfig(GPIOE, GPIO_PinSource10, GPIO_AF_FMC); // PE10 = FMC_D7
GPIO_PinAFConfig(GPIOE, GPIO_PinSource11, GPIO_AF_FMC); // PE11 = FMC_D8
GPIO_PinAFConfig(GPIOE, GPIO_PinSource12, GPIO_AF_FMC); // PE12 = FMC_D9
GPIO_PinAFConfig(GPIOE, GPIO_PinSource13, GPIO_AF_FMC); // PE13 = FMC_D10
GPIO_PinAFConfig(GPIOE, GPIO_PinSource14, GPIO_AF_FMC); // PE14 = FMC_D11
GPIO_PinAFConfig(GPIOE, GPIO_PinSource15, GPIO_AF_FMC); // PE15 = FMC_D12
// Structure for Port-E
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 // | GPIO_Pin_3
| 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;
// Configure Port-E
GPIO_Init(GPIOE, &GPIO_InitStructure);
//-----------------------------------------
// All pins for Port-F initialization
//-----------------------------------------
GPIO_PinAFConfig(GPIOF, GPIO_PinSource0, GPIO_AF_FMC); // PF0 = FMC_A0
GPIO_PinAFConfig(GPIOF, GPIO_PinSource1, GPIO_AF_FMC); // PF1 = FMC_A1
GPIO_PinAFConfig(GPIOF, GPIO_PinSource2, GPIO_AF_FMC); // PF2 = FMC_A2
GPIO_PinAFConfig(GPIOF, GPIO_PinSource3, GPIO_AF_FMC); // PF3 = FMC_A3
GPIO_PinAFConfig(GPIOF, GPIO_PinSource4, GPIO_AF_FMC); // PF4 = FMC_A4
GPIO_PinAFConfig(GPIOF, GPIO_PinSource5, GPIO_AF_FMC); // PF5 = FMC_A5
GPIO_PinAFConfig(GPIOF, GPIO_PinSource12, GPIO_AF_FMC); // PF12 = FMC_A6
GPIO_PinAFConfig(GPIOF, GPIO_PinSource13, GPIO_AF_FMC); // PF13 = FMC_A7
GPIO_PinAFConfig(GPIOF, GPIO_PinSource14, GPIO_AF_FMC); // PF14 = FMC_A8
GPIO_PinAFConfig(GPIOF, GPIO_PinSource15, GPIO_AF_FMC); // PF15 = FMC_A9
// Structure for Port-F
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;
// Configure Port-F
GPIO_Init(GPIOF, &GPIO_InitStructure);
//-----------------------------------------
// All pins for Port-G initialization
//-----------------------------------------
GPIO_PinAFConfig(GPIOG, GPIO_PinSource0, GPIO_AF_FMC); // PG0 = FMC_A10
GPIO_PinAFConfig(GPIOG, GPIO_PinSource1, GPIO_AF_FMC); // PG1 = FMC_A11
GPIO_PinAFConfig(GPIOG, GPIO_PinSource2, GPIO_AF_FMC); // PG2 = FMC_A12
GPIO_PinAFConfig(GPIOG, GPIO_PinSource3, GPIO_AF_FMC); // PG3 = FMC_A13
GPIO_PinAFConfig(GPIOG, GPIO_PinSource4, GPIO_AF_FMC); // PG4 = FMC_A14
GPIO_PinAFConfig(GPIOG, GPIO_PinSource5, GPIO_AF_FMC); // PG5 = FMC_A15
GPIO_PinAFConfig(GPIOG, GPIO_PinSource10, GPIO_AF_FMC); // PG10 = FMC_NE3
GPIO_PinAFConfig(GPIOG, GPIO_PinSource12, GPIO_AF_FMC); // PG12 = FMC_NE4
// Structure for Port-G
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3
| GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_10 | GPIO_Pin_12;
// Configure Port-G
GPIO_Init(GPIOG, &GPIO_InitStructure);
}
//--------------------------------------------------------------
// Internal Function
// Initialize FSMC for the SRAM
//--------------------------------------------------------------
void P_SRAM_InitFMC(void)
{
FMC_NORSRAMInitTypeDef FMC_NORSRAMInitStructure;
FMC_NORSRAMTimingInitTypeDef FMC_NORSRAMTimingInitStructure;
#if 0
// De-initialize for re-initialize
FMC_NORSRAMDeInit(FMC_Bank1_NORSRAM3); // From FMC_Bank1_NORSRAM1 -> 3
#endif
/* Enable FMC clock */
RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FMC, ENABLE);
//-----------------------------------------
// Structure for Timing
//-----------------------------------------
FMC_NORSRAMTimingInitStructure.FMC_AddressSetupTime = SRAM_FMC_AST; // 3
FMC_NORSRAMTimingInitStructure.FMC_AddressHoldTime = SRAM_FMC_AHT; // 0
FMC_NORSRAMTimingInitStructure.FMC_DataSetupTime = SRAM_FMC_DST; // 3
FMC_NORSRAMTimingInitStructure.FMC_BusTurnAroundDuration = 0;
FMC_NORSRAMTimingInitStructure.FMC_CLKDivision = 0;
FMC_NORSRAMTimingInitStructure.FMC_DataLatency = 0;
FMC_NORSRAMTimingInitStructure.FMC_AccessMode = FMC_AccessMode_A;
//-----------------------------------------
// Structure for Bank-1 / PSRAM-1
//-----------------------------------------
FMC_NORSRAMInitStructure.FMC_Bank = FMC_Bank1_NORSRAM3; // From FMC_Bank1_NORSRAM1 -> 3
FMC_NORSRAMInitStructure.FMC_DataAddressMux = FMC_DataAddressMux_Disable;
FMC_NORSRAMInitStructure.FMC_MemoryType = FMC_MemoryType_SRAM; // Workaround for 'Free GPIO Pin' <- NOR
FMC_NORSRAMInitStructure.FMC_MemoryDataWidth = FMC_NORSRAM_MemoryDataWidth_16b;
FMC_NORSRAMInitStructure.FMC_BurstAccessMode = FMC_BurstAccessMode_Disable;
FMC_NORSRAMInitStructure.FMC_AsynchronousWait = FMC_AsynchronousWait_Disable;
FMC_NORSRAMInitStructure.FMC_WaitSignalPolarity = FMC_WaitSignalPolarity_Low;
FMC_NORSRAMInitStructure.FMC_WrapMode = FMC_WrapMode_Disable;
FMC_NORSRAMInitStructure.FMC_WaitSignalActive = FMC_WaitSignalActive_BeforeWaitState;
FMC_NORSRAMInitStructure.FMC_WriteOperation = FMC_WriteOperation_Enable;
FMC_NORSRAMInitStructure.FMC_WaitSignal = FMC_WaitSignal_Disable;
FMC_NORSRAMInitStructure.FMC_ExtendedMode = FMC_ExtendedMode_Disable;
FMC_NORSRAMInitStructure.FMC_WriteBurst = FMC_WriteBurst_Disable;
FMC_NORSRAMInitStructure.FMC_ReadWriteTimingStruct = &FMC_NORSRAMTimingInitStructure;
FMC_NORSRAMInitStructure.FMC_WriteTimingStruct = &FMC_NORSRAMTimingInitStructure;
// Configure FSMC
FMC_NORSRAMInit(&FMC_NORSRAMInitStructure);
// Enable Bank-1 / PSRAM-1
FMC_NORSRAMCmd(FMC_Bank1_NORSRAM3, ENABLE); // From FMC_Bank1_NORSRAM1 -> 3
}
//--------------------------------------------------------------
// Sends 16-bit value to the external SRAM
//--------------------------------------------------------------
void UB_SRAM_Write(uint32_t adr, uint16_t wert)
{
// Transfer 16-bits data to the memory
*(uint16_t *) (SRAM_ADR + adr) = wert;
}
//--------------------------------------------------------------
// Reads 16-bit value from the external SRAM
//--------------------------------------------------------------
uint16_t UB_SRAM_Read(uint32_t adr)
{
uint16_t ret_wert = 0;
// Read 16-bits data from the memory
ret_wert = *(__IO uint16_t*) (SRAM_ADR + adr);
return(ret_wert);
}
在执行此操作之前,我是否应该检查任何缺失的点?
从软件的角度来看,您的银行选择与基地址不匹配。 FMC 库排列为 4x64Mb(库 1、2、3、4),基地址如下:
bank 1: 0x60000000
bank 2: 0x64000000
bank 3: 0x68000000
bank 4: 0x6C000000
令人困惑的是,ST 将 64Mb 范围称为银行本身,而实际上它们是分配给 NOR/PSRAM 的较大银行 #1 的子银行。
您定义了这个:
#define SRAM_ADR ((uint32_t)0x60000000)
// [...]
FMC_NORSRAMCmd(FMC_Bank1_NORSRAM3, ENABLE);
如您所见,存储区选择 (#3) 和基地址选择 (#1) 不匹配。你需要让它们对齐。
如果您在解决此问题后仍然遇到问题,请查看您的时序计算,当然还有电气连接。