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.

[参考译文] MSPM0G3519-Q1:两个 ADC 上同时进行硬件均值计算问题

Guru**** 2957960 points

Other Parts Discussed in Thread: SYSCONFIG

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1648430/mspm0g3519-q1-concurrent-h-w-averaging-on-both-adcs-issue

器件型号: MSPM0G3519-Q1
主题: SysConfig 中讨论的其他器件

当同时在两个 ADC 上启用硬件均值计算时、如果 ADC0 的硬件均值计算关闭的代码中唯一的差异、则输出似乎仅在 ADC0 上进行均值计算、而在 ADC1 上不进行均值计算、但 ADC1 的设置保持不变 — ADC1 上似乎会出现硬件均值计算。 无法找到有关此类问题的任何信息。 请提供建议。

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

    此 pic 展示了启用硬件均值计算功能的两个 ADC

    下面显示了禁用硬件均值计算的紫色通道、而绿色通道具有零个改变:


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

    您好、

    您可以共享 SysConfig 文件以供参考吗?

    我建议您测试通道的 ADC 转换时间、在启用硬件均值计算模式后、可以用更长的时间观察到通道的转换时间。

    B.R.

    Sal

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

    嘿、Sal、谢谢您的回复、很遗憾我的工程不使用 SysConfig

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

    您好、

    我已经测试了函数、没有发现明显的故障。 硬件平均值功能适用于 ADC0 和 ADC1。

    测试结果如下:

    测试代码如下:

    #include "ti_msp_dl_config.h"
    
    volatile bool gCheckADC;
    volatile uint16_t gAdcResult0[200]={0};
    volatile uint16_t gAdcResult1[200]={0};
    volatile uint16_t cnt;
    
    int main(void)
    {
        SYSCFG_DL_init();
    
        cnt = 0;
    
        while (1) {
            DL_GPIO_clearPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_0_PIN);
            DL_ADC12_startConversion(ADC12_0_INST);
            while(DL_ADC12_getRawInterruptStatus(ADC12_0_INST, DL_ADC12_INTERRUPT_MEM0_RESULT_LOADED) != DL_ADC12_INTERRUPT_MEM0_RESULT_LOADED)
                ;
            gAdcResult0[cnt] = DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_0);
            DL_GPIO_setPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_0_PIN);
            DL_ADC12_clearInterruptStatus(ADC12_0_INST, DL_ADC12_INTERRUPT_MEM0_RESULT_LOADED);
    
            delay_cycles(32);
    
            DL_GPIO_clearPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
            DL_ADC12_startConversion(ADC12_1_INST);
            while(DL_ADC12_getRawInterruptStatus(ADC12_1_INST, DL_ADC12_INTERRUPT_MEM0_RESULT_LOADED) != DL_ADC12_INTERRUPT_MEM0_RESULT_LOADED)
                ;
            gAdcResult1[cnt] = DL_ADC12_getMemResult(ADC12_1_INST, DL_ADC12_MEM_IDX_0);
            DL_GPIO_setPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
            DL_ADC12_clearInterruptStatus(ADC12_1_INST, DL_ADC12_INTERRUPT_MEM0_RESULT_LOADED);
    
            delay_cycles(32);
            cnt++;
            if(cnt==200)cnt=0;
            DL_ADC12_enableConversions(ADC12_0_INST);
            DL_ADC12_enableConversions(ADC12_1_INST);
        }
    }

    #include "ti_msp_dl_config.h"
    
    /*
     *  ======== SYSCFG_DL_init ========
     *  Perform any initialization needed before using any board APIs
     */
    SYSCONFIG_WEAK void SYSCFG_DL_init(void)
    {
        SYSCFG_DL_initPower();
        SYSCFG_DL_GPIO_init();
        /* Module-Specific Initializations*/
        SYSCFG_DL_SYSCTL_init();
        SYSCFG_DL_ADC12_0_init();
        SYSCFG_DL_ADC12_1_init();
    }
    
    SYSCONFIG_WEAK void SYSCFG_DL_initPower(void)
    {
        DL_GPIO_reset(GPIOA);
        DL_GPIO_reset(GPIOB);
        DL_GPIO_reset(GPIOC);
        DL_ADC12_reset(ADC12_0_INST);
        DL_ADC12_reset(ADC12_1_INST);
    
        DL_GPIO_enablePower(GPIOA);
        DL_GPIO_enablePower(GPIOB);
        DL_GPIO_enablePower(GPIOC);
        DL_ADC12_enablePower(ADC12_0_INST);
        DL_ADC12_enablePower(ADC12_1_INST);
        delay_cycles(POWER_STARTUP_DELAY);
    }
    
    SYSCONFIG_WEAK void SYSCFG_DL_GPIO_init(void)
    {
    
        DL_GPIO_initDigitalOutput(GPIO_LEDS_USER_LED_0_IOMUX);
    
        DL_GPIO_initDigitalOutput(GPIO_LEDS_USER_LED_1_IOMUX);
    
        DL_GPIO_clearPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
        DL_GPIO_setPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_0_PIN);
        DL_GPIO_enableOutput(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_0_PIN |
    		GPIO_LEDS_USER_LED_1_PIN);
    
    }
    
    
    
    SYSCONFIG_WEAK void SYSCFG_DL_SYSCTL_init(void)
    {
    
    	//Low Power Mode is configured to be SLEEP0
        DL_SYSCTL_setBORThreshold(DL_SYSCTL_BOR_THRESHOLD_LEVEL_0);
    
        
    	DL_SYSCTL_setSYSOSCFreq(DL_SYSCTL_SYSOSC_FREQ_BASE);
    	/* Set default configuration */
    	DL_SYSCTL_disableHFXT();
    	DL_SYSCTL_disableSYSPLL();
    
    }
    
    
    /* ADC12_0 Initialization */
    static const DL_ADC12_ClockConfig gADC12_0ClockConfig = {
        .clockSel       = DL_ADC12_CLOCK_ULPCLK,
        .divideRatio    = DL_ADC12_CLOCK_DIVIDE_1,
        .freqRange      = DL_ADC12_CLOCK_FREQ_RANGE_24_TO_32,
    };
    SYSCONFIG_WEAK void SYSCFG_DL_ADC12_0_init(void)
    {
        DL_ADC12_setClockConfig(ADC12_0_INST, (DL_ADC12_ClockConfig *) &gADC12_0ClockConfig);
        DL_ADC12_configConversionMem(ADC12_0_INST, ADC12_0_ADCMEM_0,
            DL_ADC12_INPUT_CHAN_0, DL_ADC12_REFERENCE_VOLTAGE_VDDA_VSSA, DL_ADC12_SAMPLE_TIMER_SOURCE_SCOMP0, DL_ADC12_AVERAGING_MODE_ENABLED,
            DL_ADC12_BURN_OUT_SOURCE_DISABLED, DL_ADC12_TRIGGER_MODE_AUTO_NEXT, DL_ADC12_WINDOWS_COMP_MODE_DISABLED);
        DL_ADC12_setPowerDownMode(ADC12_0_INST,DL_ADC12_POWER_DOWN_MODE_MANUAL);
        DL_ADC12_configHwAverage(ADC12_0_INST,DL_ADC12_HW_AVG_NUM_ACC_32,DL_ADC12_HW_AVG_DEN_DIV_BY_32);
        DL_ADC12_setSampleTime0(ADC12_0_INST,16);
        DL_ADC12_enableConversions(ADC12_0_INST);
    }
    /* ADC12_1 Initialization */
    static const DL_ADC12_ClockConfig gADC12_1ClockConfig = {
        .clockSel       = DL_ADC12_CLOCK_ULPCLK,
        .divideRatio    = DL_ADC12_CLOCK_DIVIDE_1,
        .freqRange      = DL_ADC12_CLOCK_FREQ_RANGE_24_TO_32,
    };
    SYSCONFIG_WEAK void SYSCFG_DL_ADC12_1_init(void)
    {
        DL_ADC12_setClockConfig(ADC12_1_INST, (DL_ADC12_ClockConfig *) &gADC12_1ClockConfig);
        DL_ADC12_configConversionMem(ADC12_1_INST, ADC12_1_ADCMEM_0,
            DL_ADC12_INPUT_CHAN_0, DL_ADC12_REFERENCE_VOLTAGE_VDDA_VSSA, DL_ADC12_SAMPLE_TIMER_SOURCE_SCOMP0, DL_ADC12_AVERAGING_MODE_ENABLED,
            DL_ADC12_BURN_OUT_SOURCE_DISABLED, DL_ADC12_TRIGGER_MODE_AUTO_NEXT, DL_ADC12_WINDOWS_COMP_MODE_DISABLED);
        DL_ADC12_setPowerDownMode(ADC12_1_INST,DL_ADC12_POWER_DOWN_MODE_MANUAL);
        DL_ADC12_configHwAverage(ADC12_1_INST,DL_ADC12_HW_AVG_NUM_ACC_32,DL_ADC12_HW_AVG_DEN_DIV_BY_32);
        DL_ADC12_setSampleTime0(ADC12_1_INST,16);
        DL_ADC12_enableConversions(ADC12_1_INST);
    }
    

    /*
     *  ============ ti_msp_dl_config.h =============
     *  Configured MSPM0 DriverLib module declarations
     *
     *  DO NOT EDIT - This file is generated for the MSPM0G351X
     *  by the SysConfig tool.
     */
    #ifndef ti_msp_dl_config_h
    #define ti_msp_dl_config_h
    
    #define CONFIG_MSPM0G351X
    #define CONFIG_MSPM0G3519
    
    #if defined(__ti_version__) || defined(__TI_COMPILER_VERSION__)
    #define SYSCONFIG_WEAK __attribute__((weak))
    #elif defined(__IAR_SYSTEMS_ICC__)
    #define SYSCONFIG_WEAK __weak
    #elif defined(__GNUC__)
    #define SYSCONFIG_WEAK __attribute__((weak))
    #endif
    
    #include <ti/devices/msp/msp.h>
    #include <ti/driverlib/driverlib.h>
    #include <ti/driverlib/m0p/dl_core.h>
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    /*
     *  ======== SYSCFG_DL_init ========
     *  Perform all required MSP DL initialization
     *
     *  This function should be called once at a point before any use of
     *  MSP DL.
     */
    
    
    /* clang-format off */
    
    #define POWER_STARTUP_DELAY                                                (16)
    
    
    
    #define CPUCLK_FREQ                                                     32000000
    
    
    
    
    /* Defines for ADC12_0 */
    #define ADC12_0_INST                                                        ADC0
    #define ADC12_0_INST_IRQHandler                                  ADC0_IRQHandler
    #define ADC12_0_INST_INT_IRQN                                    (ADC0_INT_IRQn)
    #define ADC12_0_ADCMEM_0                                      DL_ADC12_MEM_IDX_0
    #define ADC12_0_ADCMEM_0_REF                DL_ADC12_REFERENCE_VOLTAGE_VDDA_VSSA
    #define GPIO_ADC12_0_C0_PORT                                               GPIOA
    #define GPIO_ADC12_0_C0_PIN                                       DL_GPIO_PIN_27
    #define GPIO_ADC12_0_IOMUX_C0                                    (IOMUX_PINCM60)
    #define GPIO_ADC12_0_IOMUX_C0_FUNC                (IOMUX_PINCM60_PF_UNCONNECTED)
    
    /* Defines for ADC12_1 */
    #define ADC12_1_INST                                                        ADC1
    #define ADC12_1_INST_IRQHandler                                  ADC1_IRQHandler
    #define ADC12_1_INST_INT_IRQN                                    (ADC1_INT_IRQn)
    #define ADC12_1_ADCMEM_0                                      DL_ADC12_MEM_IDX_0
    #define ADC12_1_ADCMEM_0_REF                DL_ADC12_REFERENCE_VOLTAGE_VDDA_VSSA
    #define GPIO_ADC12_1_C0_PORT                                               GPIOA
    #define GPIO_ADC12_1_C0_PIN                                       DL_GPIO_PIN_15
    #define GPIO_ADC12_1_IOMUX_C0                                    (IOMUX_PINCM37)
    #define GPIO_ADC12_1_IOMUX_C0_FUNC                (IOMUX_PINCM37_PF_UNCONNECTED)
    
    
    
    /* Port definition for Pin Group GPIO_LEDS */
    #define GPIO_LEDS_PORT                                                   (GPIOA)
    
    /* Defines for USER_LED_0: GPIOA.0 with pinCMx 1 on package pin 1 */
    #define GPIO_LEDS_USER_LED_0_PIN                                 (DL_GPIO_PIN_0)
    #define GPIO_LEDS_USER_LED_0_IOMUX                                (IOMUX_PINCM1)
    /* Defines for USER_LED_1: GPIOA.1 with pinCMx 2 on package pin 2 */
    #define GPIO_LEDS_USER_LED_1_PIN                                 (DL_GPIO_PIN_1)
    #define GPIO_LEDS_USER_LED_1_IOMUX                                (IOMUX_PINCM2)
    
    
    /* clang-format on */
    
    void SYSCFG_DL_init(void);
    void SYSCFG_DL_initPower(void);
    void SYSCFG_DL_GPIO_init(void);
    void SYSCFG_DL_SYSCTL_init(void);
    void SYSCFG_DL_ADC12_0_init(void);
    void SYSCFG_DL_ADC12_1_init(void);
    
    
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif /* ti_msp_dl_config_h */

    B.R.

    Sal

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

    您好、Sal、感谢您的意见。 结果是   DL_ADC12_setPowerDownMode (ADC12_0_INST、DL_ADC12_POWER_DOWN_MODE_MANUAL);

    如果设置为“常开“、ADC 会产生相当一致的返回值、但在默认情况下、在不进行转换时断电、相同稳定输入上的结果会分散得更广泛。 这是一个已知的功能吗?

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

    尊敬的 Mykhaylo:

    是、这在“TRM ADC“一章中有提到:

    如果没有极端的功耗要求、我们建议使用手动断电模式。

    否则、我们需要设置更大的采样时间来覆盖 ADC 唤醒和启用时间。

    B.R.

    Sal

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

    谢谢 Sal 的帮助。 我想得到的是常开模式和默认自动断电模式之间的转换结果稳定性差异。 想象一下非常稳定的 1V 模拟输入如何转换为 ADC 的数字 100 输出。 如果它始终处于打开状态 — 读数为 99,100 和 101、无需更多。 但如果自动断电正在发挥作用 — 读数开始跳至 97、98,102 和 103、至少偶尔跳至 96 或 104。 你能看到这种影响你的一面吗? 它是否记录在任何地方? 或者、我的电路板布局布线可能存在一些问题、这是电源电压骤降并产生此类读数时电流驱动增大的属性? 请提供建议

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

    尊敬的 Mykhaylo:

    正如我提到的、这是因为在自动模式下工作时 ADC 不能稳定来启动 ADC 转换。 我们没有分析其影响的关系。

    虽然我认为如果您设置的采样时间更长(涵盖 ADC 唤醒、使能和原始 ADC 通道采样时间)、那么您可以获得相同的稳定 ADC 转换结果。

    唤醒时间最多需要 5 μ s:

    启用时间通常需要几个 ULPCLK 周期:

    例如、如果您将原始采样时间设置为 1us、则应将其设置为 1+5+0.1=6.1us 以满足所需的时序要求。

    在硬件平均模式下工作时、这种方法不够充分、因为只有第一次转换需要更大的采样时间来等待 ADC 唤醒、而以下重复转换(对于硬件平均值)仅寻求较小的采样时间。

    B.R.

    Sal