无法使用 STM32F429I-Disco 板上的 FMC 读取/写入外部 SRAM

Posted

技术标签:

【中文标题】无法使用 STM32F429I-Disco 板上的 FMC 读取/写入外部 SRAM【英文标题】:Cannot read from/write to external SRAM using FMC on STM32F429I-Disco board 【发布时间】:2015-03-07 06:55:37 【问题描述】:

我目前正在使用带有完整 FMC(F407 上的 FSMC)引脚的 STM32F429I Disco 板尝试从 Waveshare 连接到 IS62WV51216BLL SRAM 模块,但没有取得多大成功。

下面给出了主要的 SRAM 测试/初始化代码。 为帖子的长度道歉。我已经尝试检查和比较互联网上所有可用的代码,但不知何故,它只是没有初始化[未返回测试值]

代码在 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);

在执行此操作之前我应该​​检查任何遗漏点吗?

【问题讨论】:

嗯,嗯..硬件? @MartinJames James 你好!这意味着我应该检查从/到迪斯科板的引脚连接?但是,这种联系对我来说似乎是正确的。还有什么我应该非常小心的地方吗? __no_init unsigned char ExternalMemory[512] @0x6C000000; //这适用于 IAR...不需要 UB_SRAM_read/write。 【参考方案1】:

从软件的角度来看,您的银行选择与您的基本地址不匹配。 FMC bank 排列为 4x64Mb(banks 1,2,3,4),基地址如下:

bank 1: 0x60000000
bank 2: 0x64000000
bank 3: 0x68000000
bank 4: 0x6C000000

令人困惑的是,ST 将 64Mb 范围称为 bank 本身,而实际上它们是分配给 NOR/PSRAM 的较大 bank #1 的子库。

你已经定义了这个:

#define SRAM_ADR   ((uint32_t)0x60000000)

// [...]

FMC_NORSRAMCmd(FMC_Bank1_NORSRAM3, ENABLE);

如您所见,银行选择 (#3) 和基地址选择 (#1) 不匹配。你需要让它们对齐。

如果您在修复此问题后仍然遇到问题,请查看您的时序计算,尤其是电气连接。

【讨论】:

非常感谢您的回复。我刚刚尝试了您评论的代码,但是在从外部 SRAM 读取数据时它没有响应。因此,我现在想检查时序和电气连接。如果这对您来说不会太麻烦,请分享几个有助于检查这些事情的网站。 另一种可能性是 429-disco 板与外部 RAM 不兼容,因为您需要的管脚可能被该板上的板载功能占用。请参考UM1670 并检查您使用的引脚在引脚分配表中是否标有“空闲 I/O”。如果它们被其他外围设备占用,那么您可能会遇到问题。 感谢您的即时回复。现在,我完成了这项工作。这可能是由 EWARM 工具引起的。我刚刚清理了整个项目的输出文件并再次编译,它工作了。

以上是关于无法使用 STM32F429I-Disco 板上的 FMC 读取/写入外部 SRAM的主要内容,如果未能解决你的问题,请参考以下文章

STM32-F429ZIT6-开发流程

stm32f429isp下载无法收到回应

无法使用 HAL 驱动程序在 STM32F429 上写入双字

STM32F429 没有收到 CAN 报文

STM32F429-DISC1 LCD打印双像素

会stm32f429好学stm32f103吗