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 */
本文来自博客园,作者:浇筑菜鸟,转载请注明原文链接:https://www.cnblogs.com/jzcn/p/17388482.html
如本博客的内容侵犯了你的权益,请与以下地址联系,本人获知后,马上删除。同时本人深表歉意,并致以崇高的谢意! cn_jiaozhu@qq.com
外部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程序的主要内容,如果未能解决你的问题,请参考以下文章