硬汉嵌入式论坛

 找回密码
 立即注册
查看: 271|回复: 1
收起左侧

[DMA] STM32H7 MDMA传输数据前部分是0问题

[复制链接]

5

主题

6

回帖

21

积分

新手上路

积分
21
发表于 2023-11-26 02:19:44 | 显示全部楼层 |阅读模式
STM32H7 FMC AD7606采集大量数据,存SDRAM
AD7606_BUFSIZE 配置成16,在传输完成中断和半中断里面,每次采用MDMA传输4个通道的数据到SDRAM(我只需要AD7606前4个通道数据)
每启动1次,AD7606的数据采集1W条
首次启动,SDRAM里面能正常存进去数据
后续再次启动,采集开始的时候SDRAM数数据,前几百条都是0,要后续的才能有正确的数据?这个是为什么呢?
MDMA去传输数据的时候也和DCAHE有关系?
FMC DATA总线,DMA,MDMA,CPU都是访问的时候,哪个优先级最高?FMC有没有相关的仲裁机制?

MPU配置:    /* 保护SDRAM区域,共32M字节 */
    mpu_set_protection( 0XC0000000,                 /* 基地址 */
                              MPU_TEX_LEVEL1,
                        MPU_REGION_SIZE_32MB,       /* 长度 */
                        MPU_REGION_NUMBER0,         /* NUMER2 */
                        MPU_REGION_FULL_ACCESS,     /* 全访问 */
                        MPU_ACCESS_NOT_SHAREABLE,   /* 禁止共享 */
                        MPU_ACCESS_NOT_CACHEABLE,   /* 允许cache */
                        MPU_ACCESS_NOT_BUFFERABLE);     /* 允许缓冲 */
DMA1双缓冲:

/* DMA传输完成回调函数,弱定义 */
__weak void AD7606_DmaCplCb(DMA_HandleTypeDef *hdma)
{
        HAL_MDMA_Start_IT(&MDMA_Handle, (uint32_t)&g_sAd7606Buf[8], (uint32_t)&adc_buff[adc_num] , 8, 1);
        adc_num+=4;
        if(adc_num>max_num)
        {
                adc_over=1;
                AD7606_StopRecord();
        }
}

/* DMA半传输完成回调函数,弱定义 */
__weak void AD7606_DmaHalfCplCb(DMA_HandleTypeDef *hdma)
{
        HAL_MDMA_Start_IT(&MDMA_Handle, (uint32_t)&g_sAd7606Buf[0], (uint32_t)&adc_buff[adc_num] ,8, 1);
        adc_num+=4;
}

MDMA配置:

void MDMA_init(void)
{
        /* MDMA配置 **********************************************************************/
        __HAL_RCC_MDMA_CLK_ENABLE();  

        MDMA_Handle.Instance = MDMA_Channel0;  

        MDMA_Handle.Init.Request              = MDMA_REQUEST_SW;         /* 软件触发 */
        MDMA_Handle.Init.TransferTriggerMode  = MDMA_BLOCK_TRANSFER;     /* 块传输 */
        MDMA_Handle.Init.Priority             = MDMA_PRIORITY_HIGH;      /* 优先级高*/
        MDMA_Handle.Init.Endianness           = MDMA_LITTLE_ENDIANNESS_PRESERVE; /* 小端 */
        MDMA_Handle.Init.SourceInc            = MDMA_SRC_INC_HALFWORD;         /* 源地址自增,双字,即8字节 */
        MDMA_Handle.Init.DestinationInc       = MDMA_DEST_INC_HALFWORD;        /* 目的地址自增,双字,即8字节 */
        MDMA_Handle.Init.SourceDataSize       = MDMA_SRC_DATASIZE_HALFWORD;    /* 源地址数据宽度双字,即8字节 */
        MDMA_Handle.Init.DestDataSize         = MDMA_DEST_DATASIZE_HALFWORD;   /* 目的地址数据宽度双字,即8字节 */
        MDMA_Handle.Init.DataAlignment        = MDMA_DATAALIGN_PACKENABLE;       /* 小端,右对齐 */                    
        MDMA_Handle.Init.SourceBurst          = MDMA_SOURCE_BURST_4BEATS;      /* 源数据突发传输,SourceBurst*SourceDataSize <  BufferTransferLength*/
        MDMA_Handle.Init.DestBurst            = MDMA_DEST_BURST_4BEATS;        /* 目的数据突发传输,DestBurst*DestDataSize < BufferTransferLength */

        MDMA_Handle.Init.BufferTransferLength = 8;    /* 每次传输128个字节 */

        MDMA_Handle.Init.SourceBlockAddressOffset  = 0; /* 用于block传输,地址偏移0 */
        MDMA_Handle.Init.DestBlockAddressOffset    = 0; /* 用于block传输,地址偏移0 */

        /* 初始化MDMA */
        if(HAL_MDMA_Init(&MDMA_Handle) != HAL_OK)
        {
                // Error_Handler(__FILE__, __LINE__);
        }
       
//        MDMA_Handle.Instance->CTCR |=0x80000000;
       
        /* 设置传输完成回调和中断及其优先级配置 */
        HAL_MDMA_RegisterCallback(&MDMA_Handle, HAL_MDMA_XFER_CPLT_CB_ID, MDMA_TransferCompleteCallback);
        HAL_NVIC_SetPriority(MDMA_IRQn, 2, 0);
        HAL_NVIC_EnableIRQ(MDMA_IRQn);  
}

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
发表于 2023-11-27 07:57:03 | 显示全部楼层
使用MDMA最大的问题是没法同步做定时器触发,每次转换完成了都要复制粘贴一次,这种用法上作用不是很大。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-28 08:10 , Processed in 0.152098 second(s), 26 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表