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.

[参考译文] MSP430FR6043:ADC 转换启动触发器

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1419601/msp430fr6043-adc-conversion-start-trigger

器件型号:MSP430FR6043
主题中讨论的其他器件:MSP430WARE

工具与软件:

您好!

我希望每1s 启动一次 ADC 转换、而不是连续转换。 转换后、ADC  应进入睡眠状态。

  1. 采样时间1ms
  2. ACD12_B 时钟为 ACLK 32kHz
  3. 我正在检测来自两个 ADC 通道(A8和 A14)(通道序列)的数据

有任何与此相关的 driverlib 示例吗?

我在数据表中找到了下面的屏幕截图、请说明以下数据。

提前感谢、

Sarwath

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

    您好、Sarwath、

    感谢您问这个问题! 我认为、MSP430Ware 3.80.14.01 SDK 中的 msp430fr6043_ADC12_11示例是一个很好的实施起点。 此示例包含计时器代码、因此您可以对其进行调整以每秒触发 ADC 采样。 此 SDK 中还有一些示例、提供了将 MCU 置于低功耗模式、对多个 ADC 通道进行采样等的代码   

    相对于图表中的数据、这里显示了 ADC 不同的可用外部触发源连接。 您还可以使用基于软件的触发器、它是表中的第一个触发器。  

    -Brian  

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

    尊敬的 Brian Dempsey:

    感谢您的答复。

    我学习了这个msp430fr6043_adc12_11示例、并在 ADC 应用中进行了类似的设置。

    我以32kHz 的 ACLK 运行 ADC 和 Timer_A1。

    ADC 设置:

    Fadcclock=32kHz

    1个周期= 31.25us

    "我的采样时间为1ms、所以我要ADC12_B_CYCLEHOLD_32_CYCLESADC12_B_setupSamplingTimer函数中进行设置

    void adcSetup()
    {
        /***** adc hw setup ******/
        adc_init.clockSourceSelect = ADC12_B_CLOCKSOURCE_ACLK;
        adc_init.clockSourceDivider = ADC12_B_CLOCKDIVIDER_1;
        adc_init.clockSourcePredivider = ADC12_B_CLOCKPREDIVIDER__1;
        adc_init.internalChannelMap = ADC12_B_NOINTCH;
        adc_init.sampleHoldSignalSourceSelect = ADC12_B_SAMPLEHOLDSOURCE_4;
    
        /*****  sc bat channel A8 setup ******/
        memory_init1.memoryBufferControlIndex = ADC12_B_MEMORY_0;
        memory_init1.inputSourceSelect = ADC12_B_INPUT_A8;
        memory_init1.refVoltageSourceSelect = ADC12_B_VREFPOS_INTBUF_VREFNEG_VSS;
        memory_init1.endOfSequence = ADC12_B_NOTENDOFSEQUENCE;
        memory_init1.windowComparatorSelect = ADC12_B_WINDOW_COMPARATOR_DISABLE;
        memory_init1.differentialModeSelect = ADC12_B_DIFFERENTIAL_MODE_DISABLE;
    
        /***** bat inv channel A14 setup ******/
        memory_init2.memoryBufferControlIndex = ADC12_B_MEMORY_1;
        memory_init2.inputSourceSelect = ADC12_B_INPUT_A14;
        memory_init2.refVoltageSourceSelect = ADC12_B_VREFPOS_INTBUF_VREFNEG_VSS;
        memory_init2.endOfSequence = ADC12_B_ENDOFSEQUENCE;
        memory_init2.windowComparatorSelect = ADC12_B_WINDOW_COMPARATOR_DISABLE;
        memory_init2.differentialModeSelect = ADC12_B_DIFFERENTIAL_MODE_DISABLE;
    
        /***** adc initialization ******/
        ADC12_B_init(ADC12_B_BASE, &adc_init);
    
        /***** adc sampling timer ******/
        ADC12_B_setupSamplingTimer(ADC12_B_BASE, ADC12_B_CYCLEHOLD_32_CYCLES,
                                   ADC12_B_CYCLEHOLD_4_CYCLES,
                                   ADC12_B_MULTIPLESAMPLESENABLE);
    
        /***** configuring Memory 0 ******/
        ADC12_B_configureMemory(ADC12_B_BASE, &memory_init1);
    
        /***** configuring Memory 1 ******/
        ADC12_B_configureMemory(ADC12_B_BASE, &memory_init2);
    
        /***** clear adc interrupt ******/
        ADC12_B_clearInterrupt(ADC12_B_BASE, 0, 0);
    
        /***** enable adc interrupt on memory 1 ******/
        //ADC12_B_enableInterrupt(ADC12_B_BASE, ADC12_B_IE1, 0, 0);
    
        /***** enable adc ******/
        ADC12_B_enable(ADC12_B_BASE);
    
        /***** start conversion ******/
        ADC12_B_startConversion(ADC12_B_BASE, ADC12_B_START_AT_ADC12MEM0,
                                ADC12_B_SEQOFCHANNELS);
    
    
    }

    计时器 A1设置:

    FtimerA1时钟:32kHz/8:4kHz

    一个周期为250 µs。 我想生成10秒的 ISR。 每隔10秒、ADC 会在 Timer_A1 ISR 中开始转换、并且我将通过轮询来读取 ADC 数字转换数据

    void timerSetup()
    {
        TA1CCTL0 = CCIE;
        TA1CCR0 = 40000-1;                       // PWM Period
        TA1CCTL1 = OUTMOD_3;                    // TACCR1 set/reset
        TA1CCR1 = 39999;                         // TACCR1 PWM Duty Cycle
        TA1CTL = TASSEL__ACLK|ID__8| MC__UP;         // ACLK, up mode
    }
    
    #pragma vector = TIMER1_A0_VECTOR
    __interrupt void Timer1_A0_ISR (void){
        /**** enable adc *****/
        ADC12_B_enable(ADC12_B_BASE);
    
        /***** start conversion *****/
        ADC12_B_startConversion(ADC12_B_BASE, ADC12_B_START_AT_ADC12MEM0,
                                ADC12_B_SEQOFCHANNELS);
    }

    在运行时、我只在第一次转换时获得 ADC 数据。 如果我更改电压、ADC 数据保持不变(之前的数据)。

    如何得出 ADC 转换时间。 是否有任何可用的公式

    提前感谢、

    Sarwath

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

    这里显示为混合模式:startConversion 使用 ADC12SC 启动转换(就像 ADC12SHS=0一样)、但通过设置 ADC12SHS=4、计时器也会触发转换。  

    转换需要(SAMPLE_TIME + 13* ADC_CLOCK_PERIOD)或大约(1ms + 13 * 32usec)或大约1.4ms。 由于计时器在计时器中断之前发生(8*32usec)=~250usec、因此当 startConversion 再次启动时、ADC 很可能仍在运行。 这(加上您的症状)表明您因勘误表 ADC42而跳闸、在上一个转换处于活动状态时触发新的转换会使 ADC 停转[参考勘误表(SLAZ715B)第5页]。  

    考虑到您所显示的代码、最简单/最小的更改可能是在 ISR 中保留 startConversion 调用、但切换到 ADC12_B_SAMPLEHOLDSOURCE_0 (软件触发器)。  

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

    您好 Bruce McKenney、

    我已根据上述建议对代码进行了更改。

    1. ADC 转换触发: ADC12_B_SAMPLEHOLDSOURCE_SC

    void adcSetup()
    {
        /***** adc hw setup ******/
        adc_init.clockSourceSelect = ADC12_B_CLOCKSOURCE_ACLK;
        adc_init.clockSourceDivider = ADC12_B_CLOCKDIVIDER_1;
        adc_init.clockSourcePredivider = ADC12_B_CLOCKPREDIVIDER__1;
        adc_init.internalChannelMap = ADC12_B_NOINTCH;
        adc_init.sampleHoldSignalSourceSelect = ADC12_B_SAMPLEHOLDSOURCE_SC;
    
        /*****  sc bat channel A8 setup ******/
        memory_init1.memoryBufferControlIndex = ADC12_B_MEMORY_0;
        memory_init1.inputSourceSelect = ADC12_B_INPUT_A8;
        memory_init1.refVoltageSourceSelect = ADC12_B_VREFPOS_INTBUF_VREFNEG_VSS;
        memory_init1.endOfSequence = ADC12_B_NOTENDOFSEQUENCE;
        memory_init1.windowComparatorSelect = ADC12_B_WINDOW_COMPARATOR_DISABLE;
        memory_init1.differentialModeSelect = ADC12_B_DIFFERENTIAL_MODE_DISABLE;
    
        /***** bat inv channel A14 setup ******/
        memory_init2.memoryBufferControlIndex = ADC12_B_MEMORY_1;
        memory_init2.inputSourceSelect = ADC12_B_INPUT_A14;
        memory_init2.refVoltageSourceSelect = ADC12_B_VREFPOS_INTBUF_VREFNEG_VSS;
        memory_init2.endOfSequence = ADC12_B_ENDOFSEQUENCE;
        memory_init2.windowComparatorSelect = ADC12_B_WINDOW_COMPARATOR_DISABLE;
        memory_init2.differentialModeSelect = ADC12_B_DIFFERENTIAL_MODE_DISABLE;
    
        /***** adc initialization ******/
        ADC12_B_init(ADC12_B_BASE, &adc_init);
    
        /***** adc sampling timer ******/
        ADC12_B_setupSamplingTimer(ADC12_B_BASE, ADC12_B_CYCLEHOLD_32_CYCLES,
                                   ADC12_B_CYCLEHOLD_4_CYCLES,
                                   ADC12_B_MULTIPLESAMPLESENABLE);
    
        /***** configuring Memory 0 ******/
        ADC12_B_configureMemory(ADC12_B_BASE, &memory_init1);
    
        /***** configuring Memory 1 ******/
        ADC12_B_configureMemory(ADC12_B_BASE, &memory_init2);
    
    }

    2.在10秒内开始 ADC 转换 Timer1_A0_ISR 触发信号。

    void timerSetup()
    {
        TA1CCTL0 = CCIE;
        TA1CCR0 = 40000-1;                       // PWM Period
        TA1CCTL1 = OUTMOD_3;                    // TACCR1 set/reset
        TA1CCR1 = 39999;                         // TACCR1 PWM Duty Cycle (39999 cycles is 10seconds)
        TA1CTL = TASSEL__ACLK|ID__8 | MC__UP;         // ACLK, up mode
    }
    
    #pragma vector = TIMER1_A0_VECTOR
    __interrupt void Timer1_A0_ISR (void){
    
       /**** enable adc *****/
        ADC12_B_enable(ADC12_B_BASE);
    
        /**** start conversion *****/
        ADC12_B_startConversion(ADC12_B_BASE, ADC12_B_START_AT_ADC12MEM0,
                                ADC12_B_SEQOFCHANNELS);
    }

    在我的应用程序中、我正在使用ADC12_B_SEQOFCHANNELS而不是ADC12_B_REPEATED_SEQOFCHANNELS。 ADC 转换在计时器 ISR 中开始、并在转换时间后完成。 要启动下一次转换、ADC 必须等待计时器 ISR 再次触发它。

    我担心的是转换之间的等待时间:在此等待时间期间、ADC 是否会进入自动关断模式? 在我的应用中、我还使用低功耗模式3 (LPM3)来节约能源。

    谢谢!

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

    是的、它将在突发之间自动断电。 [勘误表 ADC65仅适用于突发脉冲、因此 在使用 ADC12_B_MULTIPLESAMPLESENABLE 时并不重要。]

    如果你想确定一点、可以 在 ADC 完成 ISR 中调用 ADC12_B_disableConversions()、设置 ADC12ENC=0。  您稍后的 ADC12_B_startConversion ()将为您设置 ADC12ENC=1。

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

     使用时会自动断电吗  ADC12_B_MULTIPLESAMPLESENABLE。

    2.是的,我理解你的观点。 ADC 转换完成并触发 ISR 后、我将读取数据、然后禁用 ADC 转换。 在10秒计时器 ISR 中、我将启用 ADC 转换。  ADC12_B_disableConversions禁用 ADC 转换是更好ADC12_B_disable的选择、还是更好的选择?

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

    1)是的,一旦爆破完成——在那一点,它已经完成了它被要求做的一切。

    2) 2) ADC12_B_DISABLE 设置 ADC12ON=0。 (它还会设置 ADC12ENC=0、这样可以节省一个步骤。) 我不知道设置 ADC12ON=0或者关于这一点、ADC12ENC=0是否会为你节省任何可测量值(我还没有测量它)。 另一方面,如果你每10秒只做一次,这可能被认为是"廉价保险"(强调"廉价")。 切记在您返回时调用 ADC12_B_ENABLE (ADC12ON=1)、因为 startConversion 不会提供。