This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] MSP432P401R:从具有DMA的ADC中获取两个信道,重复模式

Guru**** 2586775 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/616623/msp432p401r-sourcing-two-channels-from-adc-with-dma-repeat-mode

部件号:MSP432P401R

您好,

我想在一段时间内从两个ADC信道连续传输。 我已经阅读了Chris Sterzik在此处发布的解决方案    其中DMA来源两个连续信道,但仅来源一次。 我不知道该如何修改以允许连续转换。

谢谢!

Federico

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Federico,

    让我为您研究一下。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    弗雷德里科
    如果您想使用DMA,有几件事需要考虑。 首先,ADC的工作模式是什么。 您表示您需要两个连续的信道,但这两个信道之间的时间关系是什么? 您可以将ADC置于重复多序列模式,并使触发器自动触发(手动)。 在自动模式下,ADC将以尽可能快的速度转换两个通道。 在手动模式下,它将等待每个信道的触发器,因此如果您在5us信道A测量5us计时器触发器,然后在5us信道B测量5us计时器触发器,则会重复此操作。 我之所以区分这一点,是因为如果您要触发一个通道,然后在第一个通道完成后立即执行第二个通道,则需要处理ADC的启用转换(这在20.2 .8.4 一节中有描述, 在最后一句中,“ADC14ENC低脉冲持续时间必须至少为三个ADC14CLK周期。”)

    如果您使用的是自动模式,那么您可以利用DMA ping模式,在该模式下,主和次要轮流从ADC移动两个数据通道。 从概念上讲,可以有一个循环缓冲区,DMA正在填充该缓冲区,CPU正在从中进行处理。 您需要管理缓冲区,以便CPU和DMA不会访问相同的内存,或者DMA在处理前会覆盖。 移动两个样本后将发生DMA中断,此时必须重新初始化DMA。

    手动模式需要处理ADC14ENC位,因此逻辑选择是DMA散射-收集功能。 在此实现中,您将创建任务来执行从ADC通道的数据移动,ENC的清除/设置,然后重新初始化DMA以保持传输连续。

    这里有一个使用散点收集的示例(www.ti.com/.../slaa741.pdfwww.ti.com/.../slaa741 )。 如果您对您收集的数据量和采样率有任何疑问和/或任何具体信息,请告诉我。

    此致,
    Chris
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    这是另一个变体。

    e2e.ti.com/.../226.703万

    Chris
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Chris:

    感谢您的快速回答。

    ADC配置为自动模式和脉冲。 我希望ADC同时对两个通道进行采样(理想情况下),并在给定时间内尽可能多地进行采样,这由外部信号和另一个中断决定。

    我的理解是否正确,您的建议如下:

    MAP_ADC14_configureMultiSequenceMode (ADC_MEM0,ADC_MEM1,TRUE);
    MAP_ADC14_configureConversionMemory (ADC_MEM0,
    ADC_VREFPOS_INTBUF_VREFNEG_VSS,
    ADC_INPUT_A1,FALSE);
    MAP_ADC14_configureConversionMemory (ADC_MEM1,
    ADC_VREFPOS_INTBUF_VREFNEG_VSS,
    ADC_INPUT_A2,FALSE);
    
    MAP_DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH7_ADC14,
    UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
    MAP_DMA_setChannelTransfer (UDMA_PRI_SELECT | DMA_CH7_ADC14,
    UDMA_MODE_PINGPON,(void*)&ADC14->MEM[0],
    data_array1,sample_length);
    
    MAP_DMA_setChannelControl(UDMA_ALT_SELECT | DMA_CH7_ADC14,
    UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
    MAP_DMA_setChannelTransfer (UDMA_ALT_SELECT | DMA_CH7_ADC14,
    UDMA_MODE_PINGPON,(void*)&ADC14->MEM[1],
    data_array2,sample_length); 

    是否会在data_array1中保存第一个通道的sample_length个样本和data_array2中第二个通道的相同数量的样本?

    我不需要在工作时访问这些值,我可以在收集完所有数据后访问这些值。 我n´t无法锁定UC以便采样和保存。

    此致,

    Federico

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我正在尝试此代码,但它不起作用。

    /********************************************************************************
    **************** configuración ó n de ADC14 **********************
    ***************** /
    
    // Inicializo el módulo Ω ADC
    ADC14_enableModule();
    // Seteo el MCLK como reloj
    ADC14_INITModule (ADC_CLOCKSOURCE_MCLK,ADC_PREDIVIDER_1,ADC_DIVIDER_1,
    0);
    
    //配置中心参数以使用户可以使用perif é rico
    GPIO _setAsPeripheralModuleFunctionInputPin (GPIO_PORT_P5,
    GPIO _PIN5 | GPIO _PIN4,GPIO _STILEARY_MODULE_FUNCTION);
    
    // Configuro conversión secuencial de memoria 0 y 1, en bucle
    MAP_ADC14_configureMultiSequenceMode (ADC_MEM0,ADC_MEM1,TRUE);
    
    // Asigno las Memorias a los canales del ADC,referencia AVCC
    ADC14_configureConversionMemory (ADC_MEM0,ADC_VREFPOS_AVCC_VREFNEG_VSS,
    ADC_INPUT_A0,FALSE);
    ADC14_configureConversionMemory (ADC_MEM1,ADC_VREFPOS_AVCC_VREFNEG_VSS,
    ADC_INPUT_A1,FALSE);
    
    // Cambia entre canales automáticamente í
    ADC14_enableSampleTimer(ADC_AUTOMATICATE_IREDATE);
    
    /******************************************************************************** /
    
    /********************************************************************************
    ************************** configuración de DMA **********************
    ***************** /
    dma_enableModule();
    DMA_setControlBase(controlTable);
    
    MAP_DMA_赋 值通道(DMA_CH7_ADC14);
    
    DMA_disableChannelAttribute(DMA_CH7_ADC14,
    UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
    udma_attr_high _priority |
    udma_attr_REQMAK);
    
    MAP_DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH7_ADC14,
    UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
    MAP_DMA_setChannelTransfer (UDMA_PRI_SELECT | DMA_CH7_ADC14,
    UDMA_MODE_PINGPON,(void*)&ADC14->MEM[0],
    voltaje,sample_length);
    
    MAP_DMA_setChannelControl(UDMA_ALT_SELECT | DMA_CH7_ADC14,
    UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
    MAP_DMA_setChannelTransfer (UDMA_ALT_SELECT | DMA_CH7_ADC14,
    UDMA_MODE_PINGPON,(void*)&ADC14->MEM[1],
    corriente,sample_length);
    
    
    
    MAP_DMA_赋 值中断(DMA_INT1,7);
    MAP_Interrupt_enableInterrupt (INT_DMA_INT1);
    
    
    MAP_DMA_enableChannel(7);
    
    
    // Habilito interrupiones generales
    MAP_Interrupt_enableMaster();
    
    
    // inicio conversión
    ADC14->CTL0 || ADC14_CTL0_ENC | ADC14_CTL0_SC; 

    如果我只在突发模式和基本模式下转换一个信道,则会正常工作。 我不知道该代码有什么问题。

    谢谢

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,

    我发现DMA在多个通道中不工作的问题是错误ADC53,因为我在黑色启动板上测试。 我换了一个红色的(修订版 c)并且它有效。

    但是,经过一些测试后,我意识到ADC的数据是错误的:首先它传输所有CH1,然后传输所有CH2,而我想要的是每个通道交替传输。

    我使用的代码是:

    // Inicializo el módulo Ω ADC
    MAP_ADC14_enableModule();
    // Seteo el MCLK como reloj
    MAP_ADC14_INITModule (ADC_CLOCKSOURCE_MCLK,ADC_PREDIVIDER_1,ADC_DIVIDER_1,
    0);
    
    //配置中心参数以使用户可以使用perif é rico
    MAP_GPIO设置外围模块功能输入引脚(GPIO_PORT_P5,
    GPIO _PIN5 | GPIO _PIN4,GPIO _STILEARY_MODULE_FUNCTION);
    
    // Configuro conversión secuencial de memoria 0 y 1, en bucle
    MAP_ADC14_configureMultiSequenceMode (ADC_MEM0,ADC_MEM1,TRUE);
    
    
    // Asigno las Memorias a los canales del ADC,referencia AVCC
    MAP_ADC14_configureConversionMemory (ADC_MEM0,ADC_VREFPOS_AVCC_VREFNEG_VSS,
    ADC_INPUT_A0,FALSE);
    MAP_ADC14_configureConversionMemory (ADC_MEM1,ADC_VREFPOS_AVCC_VREFNEG_VSS,
    ADC_INPUT_A1,FALSE);
    
    ADC14_setPowerMode (ADC_ULL_POWER_MODE);
    // Cambia entre canales automáticamente í
    MAP_ADC14_enableSampleTimer(ADC_AUTOMATICAL_ITED);
    
    /*MAP_ADC14_enableInterrupt (ADC_INT0);
    MAP_ADC14_enableInterrupt (ADC_INT1);
    
    
    //启用中断
    MAP_Interrupt_enableInterrupt(INT_ADC14);*/
    /******************************************************************************** /
    
    /********************************************************************************
    ************************** configuración de DMA **********************
    ***************** /
    MAP_DMA_enableModule();
    MAP_DMA_setControlBase(controlTable);
    
    MAP_DMA_赋 值通道(DMA_CH7_ADC14);
    
    MAP_DMA_DisableChannelAttribute(DMA_CH7_ADC14,
    UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
    udma_attr_high _priority |
    udma_attr_REQMAK);
    MAP_DMA_enableChannelAttribute(DMA_CH7_ADC14, UDMA_ATTR_USEBURST);
    
    
    MAP_DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH7_ADC14,
    UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
    MAP_DMA_setChannelTransfer (UDMA_PRI_SELECT | DMA_CH7_ADC14,
    UDMA_MODE_PINGPON,(void*)&ADC14->MEM[0],
    voltaje,sample_length);
    
    MAP_DMA_setChannelControl(UDMA_ALT_SELECT | DMA_CH7_ADC14,
    UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
    MAP_DMA_setChannelTransfer (UDMA_ALT_SELECT | DMA_CH7_ADC14,
    UDMA_MODE_PINGPON,(void*)&ADC14->MEM[1],
    corriente,sample_length);
    
    
    
    MAP_DMA_赋 值中断(DMA_INT1,7);
    MAP_Interrupt_enableInterrupt (INT_DMA_INT1);
    
    MAP_DMA_enableChannel(7);
    
    
    // Habilito interrupiones generales
    MAP_Interrupt_enableMaster();
    
    
    // inicio conversión
    MAP_ADC14_enableConversion();
    MAP_ADC14_ToggleConversionTrigger();
    

    谢谢!

    Federico