打印
[STM32MP1]

实现DMA采集到的数据直接放到外部SRAM中

[复制链接]
405|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
是你的乱码|  楼主 | 2024-7-30 18:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
STM32 MCU已经正确连接到外部SRAM,并且已经配置好FSMC之类的外部存储控制器。

初始化外部SRAM。这里假设你使用的是STM32F4系列的MCU,并且外部SRAM通过FSMC连接。



FSMC配置(以STM32F4为例)


c


#include "stm32f4xx_hal.h"

// Declare the SRAM handle
SRAM_HandleTypeDef hsram;

// FSMC initialization
void FSMC_Init(void) {
    FSMC_NORSRAM_TimingTypeDef Timing;

    // Configure FSMC parameters
    hsram.Instance = FSMC_NORSRAM_DEVICE;
    hsram.Extended = FSMC_NORSRAM_EXTENDED_DEVICE;

    // Timing configuration for SRAM
    Timing.AddressSetupTime = 1;
    Timing.AddressHoldTime = 1;
    Timing.DataSetupTime = 2;
    Timing.BusTurnAroundDuration = 0;
    Timing.CLKDivision = 2;
    Timing.DataLatency = 2;
    Timing.AccessMode = FSMC_ACCESS_MODE_A;

    hsram.Init.NSBank = FSMC_NORSRAM_BANK1;
    hsram.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE;
    hsram.Init.MemoryType = FSMC_MEMORY_TYPE_SRAM;
    hsram.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16;
    hsram.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE;
    hsram.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW;
    hsram.Init.WrapMode = FSMC_WRAP_MODE_DISABLE;
    hsram.Init.WaitSignalActive = FSMC_WAIT_TIMING_BEFORE_WS;
    hsram.Init.WriteOperation = FSMC_WRITE_OPERATION_ENABLE;
    hsram.Init.WaitSignal = FSMC_WAIT_SIGNAL_DISABLE;
    hsram.Init.ExtendedMode = FSMC_EXTENDED_MODE_DISABLE;
    hsram.Init.AsynchronousWait = FSMC_ASYNCHRONOUS_WAIT_DISABLE;
    hsram.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE;

    // Initialize the SRAM controller
    if (HAL_SRAM_Init(&hsram, &Timing, &Timing) != HAL_OK) {
        // Initialization Error
        Error_Handler();
    }
}


使用特权

评论回复
沙发
是你的乱码|  楼主 | 2024-7-30 18:32 | 只看该作者
DMA配置
然后,配置DMA以从数据源采集数据并将其传输到外部SRAM。以下是一个配置DMA的示例:

3.1 DMA初始化
假设你正在使用DMA从ADC采集数据并将其存储在外部SRAM中:

c
#include "stm32f4xx_hal.h"

// Declare the DMA handle
DMA_HandleTypeDef hdma_adc;

void DMA_Init(void) {
    __HAL_RCC_DMA2_CLK_ENABLE(); // Enable the clock for DMA2

    hdma_adc.Instance = DMA2_Stream0;
    hdma_adc.Init.Channel = DMA_CHANNEL_0;
    hdma_adc.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_adc.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_adc.Init.MemInc = DMA_MINC_ENABLE;
    hdma_adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
    hdma_adc.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
    hdma_adc.Init.Mode = DMA_CIRCULAR;
    hdma_adc.Init.Priority = DMA_PRIORITY_HIGH;
    hdma_adc.Init.FIFOMode = DMA_FIFOMODE_DISABLE;

    if (HAL_DMA_Init(&hdma_adc) != HAL_OK) {
        // Initialization Error
        Error_Handler();
    }

    // Link DMA to ADC handle
    __HAL_LINKDMA(&hadc, DMA_Handle, hdma_adc);
}


使用特权

评论回复
板凳
是你的乱码|  楼主 | 2024-7-30 18:32 | 只看该作者
ADC配置和DMA启动
最后,配置ADC并启动DMA传输:

c
#include "stm32f4xx_hal.h"

// Declare the ADC handle
ADC_HandleTypeDef hadc;

// ADC initialization
void ADC_Init(void) {
    __HAL_RCC_ADC1_CLK_ENABLE(); // Enable the clock for ADC1

    hadc.Instance = ADC1;
    hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
    hadc.Init.Resolution = ADC_RESOLUTION_12B;
    hadc.Init.ScanConvMode = DISABLE;
    hadc.Init.ContinuousConvMode = ENABLE;
    hadc.Init.DiscontinuousConvMode = DISABLE;
    hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
    hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
    hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
    hadc.Init.NbrOfConversion = 1;
    hadc.Init.DMAContinuousRequests = ENABLE;
    hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;

    if (HAL_ADC_Init(&hadc) != HAL_OK) {
        // Initialization Error
        Error_Handler();
    }

    // Configure ADC regular channel
    ADC_ChannelConfTypeDef sConfig;
    sConfig.Channel = ADC_CHANNEL_0;
    sConfig.Rank = 1;
    sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
    if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) {
        // Channel Configuration Error
        Error_Handler();
    }
}

// Start DMA transfer
void Start_DMA_Transfer(void) {
    // Define the address of external SRAM
    uint32_t ext_sram_address = (uint32_t)0x60000000; // Example address, adjust based on your configuration

    if (HAL_ADC_Start_DMA(&hadc, (uint32_t *)ext_sram_address, BUFFER_SIZE) != HAL_OK) {
        // Start Error
        Error_Handler();
    }
}

int main(void) {
    HAL_Init(); // Initialize the HAL Library

    SystemClock_Config(); // Configure the system clock

    FSMC_Init(); // Initialize FSMC for external SRAM

    DMA_Init(); // Initialize DMA

    ADC_Init(); // Initialize ADC

    Start_DMA_Transfer(); // Start DMA transfer

    while (1) {
        // Main loop
    }
}

使用特权

评论回复
地板
是你的乱码|  楼主 | 2024-7-30 18:32 | 只看该作者
调试和验证
确保外部SRAM正常工作,DMA配置正确,并且数据能够正确写入外部SRAM。可以使用调试器或打印日志来验证数据传输是否正确。

总结
通过正确初始化外部SRAM、配置DMA和ADC,可以实现将DMA采集到的数据直接放入外部SRAM中。根据具体的硬件和应用需求,可能需要调整配置参数和地址。

使用特权

评论回复
5
抹茶妹妹| | 2024-7-30 18:52 | 只看该作者
下面是一个详细的示例代码,展示如何初始化 FSMC 以便与外部 SRAM 进行通信。

使用特权

评论回复
6
我爱台妹mmd| | 2024-7-31 23:17 | 只看该作者
这个例子假设你使用的是 16 位宽度的 SRAM,并已经正确连接到 FSMC。

使用特权

评论回复
7
为你转身| | 2024-8-31 13:42 | 只看该作者
这个代码片段配置了 FSMC以正确连接并初始化外部 SRAM。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

30

主题

369

帖子

1

粉丝