你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32H7A3 怎样配置MDMA的硬件触发MDMA_REQUEST_DMA1_Stream0_TC将数据再次转运

[复制链接]
onlap 提问时间:2026-1-10 15:12 / 未解决
ADC2通过DMA1_Stream0转运数据后怎样配置为MDMA_REQUEST_DMA1_Stream0_TC硬件触发将数据再次转运

已知软件触发方式MDMA_REQUEST_SW工作正常(HAL_MDMA_Start_IT(&MDMA_ADC2COPY_Handle,SrcAddress,DstAddress,BlockDataLength,1);)

硬件触发不确认是否按照以下方式


        __HAL_RCC_MDMA_CLK_ENABLE();  //没有使能时钟的情况下就配置 MDMA 很容易失败

        MDMA_ADC2COPY_Handle.Instance = MDMA_Channel3;  

        /* MDMA配置 **********************************************************************/
        __HAL_RCC_MDMA_CLK_ENABLE();  

        MDMA_ADC2COPY_Handle.Instance = MDMA_Channel3;  

        MDMA_ADC2COPY_Handle.Init.Request              = MDMA_REQUEST_DMA1_Stream0_TC;         /*触发源 */
        MDMA_ADC2COPY_Handle.Init.TransferTriggerMode  = MDMA_BLOCK_TRANSFER;     /* 块传输 */
        MDMA_ADC2COPY_Handle.Init.Priority             = MDMA_PRIORITY_HIGH;      /* 优先级高*/
        MDMA_ADC2COPY_Handle.Init.Endianness           = MDMA_LITTLE_ENDIANNESS_PRESERVE; /* 小端 */
        MDMA_ADC2COPY_Handle.Init.SourceInc            = MDMA_SRC_INC_BYTE;         /* 源地址自增,1字节 */
        MDMA_ADC2COPY_Handle.Init.DestinationInc       = MDMA_DEST_INC_HALFWORD;        /* 目的地址自增,2字节 */
        MDMA_ADC2COPY_Handle.Init.SourceDataSize       = MDMA_SRC_DATASIZE_BYTE;    /* 源地址数据宽度1字节 */
        MDMA_ADC2COPY_Handle.Init.DestDataSize         = MDMA_DEST_DATASIZE_BYTE;   /* 目的地址数据宽1字节 */
        MDMA_ADC2COPY_Handle.Init.DataAlignment        = MDMA_DATAALIGN_PACKENABLE;       /* 小端,右对齐 */                    
        MDMA_ADC2COPY_Handle.Init.SourceBurst          = MDMA_SOURCE_BURST_16BEATS;      /* 源数据突发传输*/
        MDMA_ADC2COPY_Handle.Init.DestBurst            = MDMA_DEST_BURST_16BEATS;        /* 目的数据突发传输*/

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

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

        /* 初始化MDMA */
        if(HAL_MDMA_Init(&MDMA_ADC2COPY_Handle) != HAL_OK)
        {
                 Error_Handler();
        }
        /* 设置传输完成回调和中断及其优先级配置 */
        HAL_MDMA_RegisterCallback(&MDMA_ADC2COPY_Handle, HAL_MDMA_XFER_CPLT_CB_ID, MDMA_CH3_TransferCompleteCallback);
        HAL_NVIC_SetPriority(MDMA_IRQn, 0, 0);
        HAL_NVIC_EnableIRQ(MDMA_IRQn);  
        
        MDMA_Channel3->CSAR=&ADC_ConvertedValue[0];//通道3源地址寄存器
        MDMA_Channel3->CDAR=&NEW_DATA_ARRY[0];//通道3目的地址寄存器
        MDMA_Channel3->CBNDTR|=0x001F0001;//通道3块数据字节块寄存器BRC 数据块20:31=1
        MDMA_Channel3->CBNDTR|=0xFFFEFFFF;//通道3块数据字节块寄存器BNDT 数据块16:0=65535 传输的字节数65535


以上配置不清楚是否正确,是否以上配置后就可以自动工作 ,请用过的老师指点一下
收藏 评论13 发布时间:2026-1-10 15:12

举报

13个回答
xmshao 回答时间:2026-1-12 15:01:19

基于STM32H7芯片实现这个功能,原理上讲应该是没啥问题。

刚好前不久我也做了类似的应用验证,下面文章你可以参考下,介绍得也算详细了。

STM32H7 MDMA 与通用DMA的联动传输示例

你先参考、比较下,特别注意有些配置细节。若还有问题,我们可以继续沟通。

onlap 回答时间:2026-1-12 17:20:13

xmshao 发表于 2026-1-12 15:01
基于STM32H7芯片实现这个功能,原理上讲应该是没啥问题。</p>
<p>刚好前不久我也做了类似的应用验证,下面文 ...

[md]你好 谢谢!

意思就是设为硬件触发模式后,也是用HAL_MDMA_Start这个函数设置一次源地址+目的地址+数据个数+块数,

然后就可以自动转运了,不同于软件触发每次转运都需要运行一次HAL_MDMA_Start

请问是这样理解吗?

我的使用场景是将ADC1的采样数据与ADC2的采样数据用MDMA进行交叉合并得到14MSPS的采样数据,软件触发模式ok,现在想改为硬件触发模式(尝试过双ADC交替采样模式最高速度只能7MSPS)

xmshao 回答时间:2026-1-13 09:30:46

onlap 发表于 2026-1-12 17:20
你好 谢谢!</p>
<p>意思就是设为硬件触发模式后,也是用<code>HAL_MDMA_Start</code>这个函数设置一次源地址+目的地址 ...

[md]你是说ADC结果先经过通用DMA搬运,搬运一批数据后,再由MDMA转运,是可以的。

至于是否需要每次搬运一批数据后再启动,这取决于DMA是工作在normal模式还是circular模式。

onlap 回答时间:2026-1-14 08:58:16
xmshao 发表于 2026-1-13 09:30
[md]你是说ADC结果先经过通用DMA搬运,搬运一批数据后,再由MDMA转运,是可以的。

至于是否需要每次搬运 ...

你好

我测试是TIM1触发ADC1+DMA1_Stream0 普通模式,受控于TIM1的工作状态进行采样,只要TIM1工作,DMA1_Stream0就会有TC中断

MDMA配置DMA1_Stream0的TC触发,配置后 MDMA只工作一次就停止了,按照原理是只要DMA1_Stream0不停的产生传输完成中断,MDMA就应该工作,不清楚是否设置有问题,以下是配置内容

void MDMA_Channel2_ADC1_INSERT_COPY_DMA1_0_Init(uint32_t SrcAddress, uint32_t DstAddress, uint32_t BlockDataLength, uint32_t BlockCount)//将源BYTE数组交替插入拷贝到目的HALFWORD数组的0:7位置
{

        __HAL_RCC_MDMA_CLK_ENABLE();
        /* MDMA配置 **********************************************************************/


        hmdma_mdma_channel2_dma1_stream0_tc_0.Instance = MDMA_Channel2;  

        hmdma_mdma_channel2_dma1_stream0_tc_0.Init.Request              = MDMA_REQUEST_DMA1_Stream0_TC;         /* DMA1_Stream0_TC */
        hmdma_mdma_channel2_dma1_stream0_tc_0.Init.TransferTriggerMode  = MDMA_BLOCK_TRANSFER;     /* 块传输 MDMA_BUFFER_TRANSFER;*/
        hmdma_mdma_channel2_dma1_stream0_tc_0.Init.Priority             = MDMA_PRIORITY_HIGH;      /* 优先级高*/
        hmdma_mdma_channel2_dma1_stream0_tc_0.Init.Endianness           = MDMA_LITTLE_ENDIANNESS_PRESERVE; /* 小端 */
        hmdma_mdma_channel2_dma1_stream0_tc_0.Init.SourceInc            = MDMA_SRC_INC_BYTE;         /* 源地址自增,1字节 */
        hmdma_mdma_channel2_dma1_stream0_tc_0.Init.DestinationInc       = MDMA_DEST_INC_HALFWORD;        /* 目的地址自增,2字节 */
        hmdma_mdma_channel2_dma1_stream0_tc_0.Init.SourceDataSize       = MDMA_SRC_DATASIZE_BYTE;    /* 源地址数据宽度1字节 */
        hmdma_mdma_channel2_dma1_stream0_tc_0.Init.DestDataSize         = MDMA_DEST_DATASIZE_BYTE;   /* 目的地址数据宽1字节 */
        hmdma_mdma_channel2_dma1_stream0_tc_0.Init.DataAlignment        = MDMA_DATAALIGN_PACKENABLE;       /* 小端,右对齐 */
        hmdma_mdma_channel2_dma1_stream0_tc_0.Init.BufferTransferLength = 128;    /* 每次传输128个字节 */       
        hmdma_mdma_channel2_dma1_stream0_tc_0.Init.SourceBurst          = MDMA_SOURCE_BURST_16BEATS;      /* 源数据突发传输,*/
        hmdma_mdma_channel2_dma1_stream0_tc_0.Init.DestBurst            = MDMA_DEST_BURST_16BEATS;        /* 目的数据突发传输, */


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

        /* 初始化MDMA */
        if(HAL_MDMA_Init(&hmdma_mdma_channel2_dma1_stream0_tc_0) != HAL_OK)
        {
                 Error_Handler();
        }
       

  /* Configure post request address and data masks */
  if (HAL_MDMA_ConfigPostRequestMask(&hmdma_mdma_channel2_dma1_stream0_tc_0, 0, 0) != HAL_OK)
  {
    Error_Handler();
  }
       
       
       
       
        /* 设置传输完成回调和中断及其优先级配置 */
        HAL_MDMA_RegisterCallback(&hmdma_mdma_channel2_dma1_stream0_tc_0, HAL_MDMA_XFER_CPLT_CB_ID, MDMA_CH2_TransferCompleteCallback);
        HAL_NVIC_SetPriority(MDMA_IRQn, 0, 0);
        HAL_NVIC_EnableIRQ(MDMA_IRQn);  
       
       
        HAL_MDMA_Start_IT(&hmdma_mdma_channel2_dma1_stream0_tc_0,SrcAddress,DstAddress,BlockDataLength,BlockCount);
       
}       

ADC1配置TIM1触发模式 DMA1_Stream0 配置普通模式(MDMA配置为软件触发模式在DMA1_Stream0 TC中断里面工作是正常的)


xmshao 回答时间:2026-1-15 18:03:16

onlap 发表于 2026-1-14 08:58
你好</p>
<p>我测试是TIM1触发ADC1+DMA1_Stream0 普通模式,受控于TIM1的工作状态进行采样,只要TIM1工作,DMA1 ...

我这边也发现了跟你同样的现象,目前还没有找到根本原因。

我找个临时应对方案,就是在MDMA完成中断里再次使能了MDMA的传输通道,无须重启MDMA的启动函数及初始化。

__HAL_MDMA_ENABLE(&hmdma_mdma_channel0_dma1_stream0_tc_0);

onlap 回答时间:2026-1-17 17:02:45

xmshao 发表于 2026-1-15 18:03
我这边也发现了跟你同样的现象,目前还没有找到根本原因。</p>
<p>我找个临时应对方案,就是在MDMA完成中断 ...

[md]谢谢 ! 这样就相当于软件触发一样了。

butterflyspring 回答时间:2026-1-22 15:40:23

onlap 发表于 2026-1-17 17:02
谢谢 ! 这样就相当于软件触发一样了。

这里看起来硬件原因,MDMA 完成一次传输后,硬件将EN 位关闭了。

测试了一下,也是只能触发一次。所以只能向大佬说的那样,重新配置,记得包括字节数等。

[attach]730879[/attach]

butterflyspring 回答时间:2026-1-22 15:41:17
补充一下截图

STM32H7A3 MDMA end EN.PNG
xmshao 回答时间:6 天前

butterflyspring 发表于 2026-1-22 15:40
这里看起来硬件原因,MDMA 完成一次传输后,硬件将EN 位关闭了。</p>
<p>

其实,不用完全重新配置,只需将DMA相关通道使能位再置位即可,这比重新配置简单、快捷得多。

onlap 回答时间:6 天前

xmshao 发表于 2026-1-24 08:31
其实,不用完全重新配置,只需将DMA相关通道使能位再置位即可,这比重新配置简单、快捷得多。
...

好的 知道 谢谢

另外请问一下 STM32H7A3 定时器触发ADC1+DMA+ADC2 双通道交替模式8位采样是否可以获得14Msps的采样速度,我测试最多只能够7Msps,与单通道采样速度一样

(STM32F405三通道交替采样可以得到3倍的单通道采样速度7.2MSPS)

xmshao 回答时间:3 天前

onlap 发表于 2026-1-24 09:35
好的  知道 谢谢</p>
<p>另外请问一下 STM32H7A3  定时器触发ADC1+DMA+ADC2 双通道交替模式8位采样是否可以 ...

[md]不知是你误会了还是我误会你了。

你说使用双ADC交错采样得到7MSPS,对于两个ADC而言不就是14MSPS吗?每次得到的数据都是两个模块转换得到的。

onlap 回答时间:3 天前

xmshao 发表于 2026-1-27 16:57
不知是你误会了还是我误会你了。</p>
<p>你说使用双ADC交错采样得到7MSPS,对于两个ADC而言不就是14MSPS吗 ...

[md]你好 我的意思是使用双ADC交错采样最多只能得到ADC1的3.5MSPS+ADC2的3.5MSPS的数据,定时器触发超过3.5MHz,ADC1和ADC2的采样速度不会继续上升了

xmshao 回答时间:3 天前

onlap 发表于 2026-1-27 17:42</p>
<p>[md]你好 我的意思是使用双ADC交错采样最多只能得到ADC1的3.5MSPS+ADC2的3.5MSPS的数据,定时器触发 ...

[md]哦 那我明白了。

这个地方我要验证下,验证过后再分享与你。

不过,初步估计问题应该不在ADC这里。

所属标签

相似问题

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版