STM32HAL库使用外部SRAM程序

Posted 浇筑菜鸟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32HAL库使用外部SRAM程序相关的知识,希望对你有一定的参考价值。



#include <board.h>

#ifdef BSP_USING_SRAM
#include <drv_common.h>
#include <rtthread.h>
#include <rtdevice.h>

#define DBG_TAG "drv_exsram"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

#define RAM_HEAP_EX_START           (0x68000000)
#define RAM_HEAP_EX_SIZE            (1024 * 1024)
#define RAM_HEAP_EX_END             (RAM_HEAP_EX_START + RAM_HEAP_EX_SIZE)

/* 注意:SRAM 句柄不能为局部变量 */
SRAM_HandleTypeDef SRAM_Handler;    // SRAM句柄

#ifdef RT_USING_MEMHEAP_AS_HEAP
static struct rt_memheap system_heap;
#endif


/**
  * @brief SRAM 初始化
  * @retval None
  */
static int system_sram_init(void)

	int result = RT_EOK;
	
    FSMC_NORSRAM_TimingTypeDef FSMC_ReadWriteTim;

    /*----------------------------------------- 使能时钟 -----------------------------------------*/
    __HAL_RCC_GPIOD_CLK_ENABLE();           // 使能GPIOD时钟
    __HAL_RCC_GPIOE_CLK_ENABLE();           // 使能GPIOE时钟
    __HAL_RCC_GPIOF_CLK_ENABLE();           // 使能GPIOF时钟
    __HAL_RCC_GPIOG_CLK_ENABLE();           // 使能GPIOG时钟

    /*----------------------------------------- 配置 SRAM -----------------------------------------*/
    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;        // 存储器是在等待周期之前的一个时钟周期还是等待周期期间使能NWAIT
    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 1/72M = 13.8ns
    FSMC_ReadWriteTim.AddressHoldTime = 0x00;           // 地址保持时间(ADDHLD)模式A未用到
    FSMC_ReadWriteTim.DataSetupTime = 0x03;             // 数据保存时间为3个HCLK = 4*13.8 = 55ns
    FSMC_ReadWriteTim.BusTurnAroundDuration = 0X00;
    FSMC_ReadWriteTim.CLKDivision = 0X00;
    FSMC_ReadWriteTim.DataLatency = 0X00;
    FSMC_ReadWriteTim.AccessMode = FSMC_ACCESS_MODE_A;  // 模式A

    if (HAL_SRAM_Init(&SRAM_Handler, &FSMC_ReadWriteTim, &FSMC_ReadWriteTim) != HAL_OK)
	
		LOG_E("SDRAM init failed!");
        result = -RT_ERROR;
	
	else
    
#ifdef RT_USING_MEMHEAP_AS_HEAP
        /* If RT_USING_MEMHEAP_AS_HEAP is enabled, SDRAM is initialized to the heap */
		rt_memheap_init(&system_heap, "sdram", (void *)RAM_HEAP_EX_START, RAM_HEAP_EX_SIZE);
#else
        rt_system_heap_init((void *)RAM_HEAP_EX_START, (void *)RAM_HEAP_EX_END);
#endif
    
	
	return result;


INIT_BOARD_EXPORT(system_sram_init);

#endif /* BSP_USING_SRAM */

调用时 HAL_SRAM_Init 需要使用 stm32f1xx_hal_sram.c 文件和 stm32f1xx_ll_fsmc.c 文件,并且需要在 stm32f1xx_hal_msp.c 文件中完成相应的引脚使能,代码如下所示:

static uint32_t FSMC_Initialized = 0;

static void HAL_FSMC_MspInit(void)
  /* USER CODE BEGIN FSMC_MspInit 0 */

  /* USER CODE END FSMC_MspInit 0 */
  GPIO_InitTypeDef GPIO_InitStruct =0;
  if (FSMC_Initialized) 
    return;
  
  FSMC_Initialized = 1;

  /* Peripheral clock enable */
  __HAL_RCC_FSMC_CLK_ENABLE();

  /** FSMC GPIO Configuration
  PF0   ------> FSMC_A0
  PF1   ------> FSMC_A1
  PF2   ------> FSMC_A2
  PF3   ------> FSMC_A3
  PF4   ------> FSMC_A4
  PF5   ------> FSMC_A5
  PF12   ------> FSMC_A6
  PF13   ------> FSMC_A7
  PF14   ------> FSMC_A8
  PF15   ------> FSMC_A9
  PG0   ------> FSMC_A10
  PG1   ------> FSMC_A11
  PE7   ------> FSMC_D4
  PE8   ------> FSMC_D5
  PE9   ------> FSMC_D6
  PE10   ------> FSMC_D7
  PE11   ------> FSMC_D8
  PE12   ------> FSMC_D9
  PE13   ------> FSMC_D10
  PE14   ------> FSMC_D11
  PE15   ------> FSMC_D12
  PD8   ------> FSMC_D13
  PD9   ------> FSMC_D14
  PD10   ------> FSMC_D15
  PD11   ------> FSMC_A16
  PD12   ------> FSMC_A17
  PD13   ------> FSMC_A18
  PD14   ------> FSMC_D0
  PD15   ------> FSMC_D1
  PG2   ------> FSMC_A12
  PG3   ------> FSMC_A13
  PG4   ------> FSMC_A14
  PG5   ------> FSMC_A15
  PD0   ------> FSMC_D2
  PD1   ------> FSMC_D3
  PD4   ------> FSMC_NOE
  PD5   ------> FSMC_NWE
  PG10   ------> FSMC_NE3
  PE0   ------> FSMC_NBL0
  PE1   ------> FSMC_NBL1
  */
  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_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_PIN_0|GPIO_PIN_1;
  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_12|GPIO_PIN_13|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);

  /* USER CODE BEGIN FSMC_MspInit 1 */

  /* USER CODE END FSMC_MspInit 1 */


void HAL_SRAM_MspInit(SRAM_HandleTypeDef* hsram)
  /* USER CODE BEGIN SRAM_MspInit 0 */

  /* USER CODE END SRAM_MspInit 0 */
  HAL_FSMC_MspInit();
  /* USER CODE BEGIN SRAM_MspInit 1 */

  /* USER CODE END SRAM_MspInit 1 */


static uint32_t FSMC_DeInitialized = 0;

static void HAL_FSMC_MspDeInit(void)
  /* USER CODE BEGIN FSMC_MspDeInit 0 */

  /* USER CODE END FSMC_MspDeInit 0 */
  if (FSMC_DeInitialized) 
    return;
  
  FSMC_DeInitialized = 1;
  /* Peripheral clock enable */
  __HAL_RCC_FSMC_CLK_DISABLE();

  /** FSMC GPIO Configuration
  PF0   ------> FSMC_A0
  PF1   ------> FSMC_A1
  PF2   ------> FSMC_A2
  PF3   ------> FSMC_A3
  PF4   ------> FSMC_A4
  PF5   ------> FSMC_A5
  PF12   ------> FSMC_A6
  PF13   ------> FSMC_A7
  PF14   ------> FSMC_A8
  PF15   ------> FSMC_A9
  PG0   ------> FSMC_A10
  PG1   ------> FSMC_A11
  PE7   ------> FSMC_D4
  PE8   ------> FSMC_D5
  PE9   ------> FSMC_D6
  PE10   ------> FSMC_D7
  PE11   ------> FSMC_D8
  PE12   ------> FSMC_D9
  PE13   ------> FSMC_D10
  PE14   ------> FSMC_D11
  PE15   ------> FSMC_D12
  PD8   ------> FSMC_D13
  PD9   ------> FSMC_D14
  PD10   ------> FSMC_D15
  PD11   ------> FSMC_A16
  PD12   ------> FSMC_A17
  PD13   ------> FSMC_A18
  PD14   ------> FSMC_D0
  PD15   ------> FSMC_D1
  PG2   ------> FSMC_A12
  PG3   ------> FSMC_A13
  PG4   ------> FSMC_A14
  PG5   ------> FSMC_A15
  PD0   ------> FSMC_D2
  PD1   ------> FSMC_D3
  PD4   ------> FSMC_NOE
  PD5   ------> FSMC_NWE
  PG10   ------> FSMC_NE3
  PE0   ------> FSMC_NBL0
  PE1   ------> FSMC_NBL1
  */
  HAL_GPIO_DeInit(GPIOF, 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);

  HAL_GPIO_DeInit(GPIOG, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
                          |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_10);

  HAL_GPIO_DeInit(GPIOE, 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_PIN_0|GPIO_PIN_1);

  HAL_GPIO_DeInit(GPIOD, 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_PIN_0|GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5);

  /* USER CODE BEGIN FSMC_MspDeInit 1 */

  /* USER CODE END FSMC_MspDeInit 1 */


void HAL_SRAM_MspDeInit(SRAM_HandleTypeDef* hsram)
  /* USER CODE BEGIN SRAM_MspDeInit 0 */

  /* USER CODE END SRAM_MspDeInit 0 */
  HAL_FSMC_MspDeInit();
  /* USER CODE BEGIN SRAM_MspDeInit 1 */

  /* USER CODE END SRAM_MspDeInit 1 */


外部SRAM的种类

外部SRAM注意事项

为使外部SRAM器件达到出最佳性能,建议遵循以下原则:

使用与连接的主系统控制器的接口数据带宽相同的SRAM。

如果管脚使用或板上空间的限制高于系统性能要求,可以使用较连接的控制器的数据带宽小一些的SRAM设备,以便减少管脚数量并减少PCB板上可能的存储器数量。然而这种变化将导致降低SRAM接口的性能。

外部SRAM的种类外部SRAM的种类

有多种SRAM器件可供选择。最常见的种类如下:

异步SRAM – 由于其不依靠时钟,所以是最慢的一种SRAM。

同步sram(***AM)– 同步SRAM运行同步于一个时钟信号 。同步SRAM的速度比异步SRAM的要快,但是也更昂贵。

伪SRAM – 伪SRAM(PSRAM)是指具有***AM接口的动态RAM(DRAM)

零总线周转时间SRAM –零总线周转时间SRAM(ZBT SRAM)从读到写的转换需要零个时钟周期,这使得它的反应时间很短。ZBT SRAM通常需要一个专用的控制器使其低反应时间的优势发挥出来。

以上是关于STM32HAL库使用外部SRAM程序的主要内容,如果未能解决你的问题,请参考以下文章

创建STM32F103ZET6的HAL库工程

STM32 HAL库学习系列第9篇---NVIC按键外部中断函数

STM32 HAL库串口使用笔记

STM32G0学习手册——使用HAL库进行EXTI中断实验

STM32使用HAL库实现串口通讯——实战操作

STM32基于HAL库的中断详细学习