|
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 以上配置不清楚是否正确,是否以上配置后就可以自动工作 ,请用过的老师指点一下 |
STM32Programmer能识别芯片,Keil无法识别
STM32H7进入BOOTLoader模式
请教STM32F103的DMA空闲接收问题
stm32H743使用CubeMxAi导入模型文件,需要将测试数据进行识别,不知道如何传入参数
STM32H725VGT3内存不足问题
串口DMA收发出现ORE错误
stm32h7s78-dk烧录
关于外部事件(EXTI0)触发SPI读取数据
STM32H7 USB3300底层寄存器问题
STM32F429突然死机
微信公众号
手机版
你好
我测试是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中断里面工作是正常的)
芯片为STM32H7A3RG,
ADC输入时钟100MHz(ADC内部硬件2分频得到50MHz的ADC工作频率),
ADC1+DMA1_Stream0+ADC2调整为交替采样模式, DMA设为LL_ADC_MULTI_REG_DMA_RES_8B;/双通道混合DMA 8位数据模式/,
32KHz正弦波测试频率,输入到ADC12的快速输入通道和TIM5的通道1捕获波形,用上升沿触发TIM1使能工作,在DMA1_Stream0传输完成中关闭TIM1, 每次DMA结束后,停止采样 ,通过320*240显示屏显示波形,根据显示波形的数量,推算出采样频率, 达到3.5MHz+3.5MHz采样率时大约显示1.1个周期的波形(7 000 000/32000=218点/周期波形,240点/218点=1.1周期波形),(14MSPS采样率只显示0.5个周期波形), 调整TIM1的ARR值从300到80, 当TIM1的触发频率最开始为280 000 000/1/300=0.93Mhz , 最开始提高触发频率,采样率会随触发频率上升 当TIM1的触发频率调整到280 000 000/1/80=3.5Mhz , ADC1(3.5Mhz)+ADC2(3.5Mhz)的合计每秒的采样数大约为7MHz, 再继续升高触发频率 ,采样数不会继续上升,
以上只是说双ADC交替模式达不到(7MSPS+7MSPS)的采样率,
已验证使用两个ADC1+DMA1_Stream0+ADC2+DMA1_Stream1的独立模式是可以达到7MSPS+7MSPS速度的,但是独立模式需要将两个DMA的数据再合并排序一次,不太方便,(而交替模式的数据不需要重新排序),
[md]你所测得的采样率不知你具体怎么得到的?单说ADC采样率其实也没啥好测的,数据手册写的
都是有保证的。
我怀疑你是测得的外部触发频率,比方来自定时器的触发频率,以每触发一次得到对应的正确结果,你这个数字是有可能的。这显然不能等同ADC自身的采样率。
我这边也做了测试,这个结果除了跟分辨率选择、跟ADC时钟、采样参数都有关系,如果8位格式,40Mhz 的fadc。 能测得的可靠【所谓可靠就是触发一次得到一次结果】有效触发频率大概4Mhz的样子。我用DMA搬运结果。
基于STM32H7芯片实现这个功能,原理上讲应该是没啥问题。
刚好前不久我也做了类似的应用验证,下面文章你可以参考下,介绍得也算详细了。
STM32H7 MDMA 与通用DMA的联动传输示例
你先参考、比较下,特别注意有些配置细节。若还有问题,我们可以继续沟通。
[md]你好 谢谢!
意思就是设为硬件触发模式后,也是用
HAL_MDMA_Start这个函数设置一次源地址+目的地址+数据个数+块数,然后就可以自动转运了,不同于软件触发每次转运都需要运行一次HAL_MDMA_Start
请问是这样理解吗?
我的使用场景是将ADC1的采样数据与ADC2的采样数据用MDMA进行交叉合并得到14MSPS的采样数据,软件触发模式ok,现在想改为硬件触发模式(尝试过双ADC交替采样模式最高速度只能7MSPS)
[md]你是说ADC结果先经过通用DMA搬运,搬运一批数据后,再由MDMA转运,是可以的。
至于是否需要每次搬运一批数据后再启动,这取决于DMA是工作在normal模式还是circular模式。
我这边也发现了跟你同样的现象,目前还没有找到根本原因。
我找个临时应对方案,就是在MDMA完成中断里再次使能了MDMA的传输通道,无须重启MDMA的启动函数及初始化。
__HAL_MDMA_ENABLE(&hmdma_mdma_channel0_dma1_stream0_tc_0);
[md]谢谢 ! 这样就相当于软件触发一样了。
这里看起来硬件原因,MDMA 完成一次传输后,硬件将EN 位关闭了。
测试了一下,也是只能触发一次。所以只能向大佬说的那样,重新配置,记得包括字节数等。
[attach]730879[/attach]
其实,不用完全重新配置,只需将DMA相关通道使能位再置位即可,这比重新配置简单、快捷得多。
好的 知道 谢谢
另外请问一下 STM32H7A3 定时器触发ADC1+DMA+ADC2 双通道交替模式8位采样是否可以获得14Msps的采样速度,我测试最多只能够7Msps,与单通道采样速度一样
(STM32F405三通道交替采样可以得到3倍的单通道采样速度7.2MSPS)
[md]不知是你误会了还是我误会你了。
你说使用双ADC交错采样得到7MSPS,对于两个ADC而言不就是14MSPS吗?每次得到的数据都是两个模块转换得到的。
[md]你好 我的意思是使用双ADC交错采样最多只能得到ADC1的3.5MSPS+ADC2的3.5MSPS的数据,定时器触发超过3.5MHz,ADC1和ADC2的采样速度不会继续上升了
[md]哦 那我明白了。
这个地方我要验证下,验证过后再分享与你。
不过,初步估计问题应该不在ADC这里。