bigbat 发表于 2025-1-21 23:11

【FRDM-MCXN947测评】AD采集和设置测试及功耗测量

<p><strong>1、测试介绍</strong></p>

<p>本测试使用ADC外设中断模式采集电压数据。MCXN947VDF MCU有两组16bit ADC核心。</p>

<p>1)每个 ADC 可用作两个单端输入 ADC 或一个差分输入 ADC。<br />
2)在 16 位模式下高达 2 Msps,在 12 位模式下高达 3.15 Msps。<br />
3)多达 75 个 ADC 输入通道。<br />
4)每个 ADC 外设集成一个温度传感器作为温度补偿使用。</p>

<p>通常的MCU中多数为12bit的ADC,很少集成为16bit的ADC。所以MCXN947VDF使用为高档仪表较为理想。</p>

<p>硬件:</p>

<p>FRDM-MCXN947一块。</p>

<p>USB type-c电缆线一条。</p>

<p>简易电压信号发生器一台。</p>

<p>万用表一块。</p>

<p>软件:</p>

<p>GCC ARM Embedded 13.2.1编译器。</p>

<p>测试通过J8端口 28引脚采集电压。该引脚与MCU P4_23通道连接,本次测试使用14bit模式进行采集。</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p><strong>2、程序与测试设置</strong></p>

<p>将MCU的ADC0的通道A2打开。</p>

<p>&nbsp; 编写中断和初始化程序</p>

<p>中断服务程序。程序中使用LPADC_GetConvResult()函数获得ADC转化值。并且将g_LpadcConversionCompletedFlag = true;标记置为true用来提示采集完成。</p>

<pre>
<code class="language-cpp">void DEMO_LPADC_IRQ_HANDLER_FUNC(void)
{
    g_LpadcInterruptCounter++;
#if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) &amp;&amp; (FSL_FEATURE_LPADC_FIFO_COUNT == 2U))
    if (LPADC_GetConvResult(DEMO_LPADC_BASE, &amp;g_LpadcResultConfigStruct, 0U))
#else
    if (LPADC_GetConvResult(DEMO_LPADC_BASE, &amp;g_LpadcResultConfigStruct))
#endif /* FSL_FEATURE_LPADC_FIFO_COUNT */
    {
      g_LpadcConversionCompletedFlag = true;
    }
    SDK_ISR_EXIT_BARRIER;
}
</code></pre>

<p>ADC初始化代码,代码的配置是通过mLpadcConfigStruct数据结构在各配置函数中进行传递。</p>

<p>1)LPADC_GetDefaultConfig(&amp;mLpadcConfigStruct);函数取得默认配置,填充默认值。</p>

<p>2)对mLpadcConfigStruct各域进行赋值,即进行设置。</p>

<p>将预制值打开</p>

<p>选择参考电压源</p>

<p>选择均值模式</p>

<p>初始化ADC</p>

<pre>
<code class="language-cpp">LPADC_GetDefaultConfig(&amp;mLpadcConfigStruct);
    mLpadcConfigStruct.enableAnalogPreliminary = true;
#if defined(DEMO_LPADC_VREF_SOURCE)
    mLpadcConfigStruct.referenceVoltageSource = DEMO_LPADC_VREF_SOURCE;
#endif /* DEMO_LPADC_VREF_SOURCE */
#if defined(FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS) &amp;&amp; FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS
    mLpadcConfigStruct.conversionAverageMode = kLPADC_ConversionAverage128;
#endif /* FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS */
    LPADC_Init(DEMO_LPADC_BASE, &amp;mLpadcConfigStruct);</code></pre>

<p>设置采集模式和校准ADC。</p>

<pre>
<code class="language-cpp">/* Request LPADC calibration. */
#if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE) &amp;&amp; FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE
    LPADC_SetOffsetCalibrationMode(DEMO_LPADC_BASE, DEMO_LPADC_OFFSET_CALIBRATION_MODE);
#endif /* FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE */

#if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFS) &amp;&amp; FSL_FEATURE_LPADC_HAS_CTRL_CALOFS
#if defined(DEMO_LPADC_DO_OFFSET_CALIBRATION) &amp;&amp; DEMO_LPADC_DO_OFFSET_CALIBRATION
    LPADC_DoOffsetCalibration(DEMO_LPADC_BASE); /* Request offset calibration, automatic update OFSTRIM register. */
#else                                           /* Update OFSTRIM register manually. */

#if defined(FSL_FEATURE_LPADC_HAS_OFSTRIM) &amp;&amp; FSL_FEATURE_LPADC_HAS_OFSTRIM
#if defined(FSL_FEATURE_LPADC_OFSTRIM_COUNT) &amp;&amp; (FSL_FEATURE_LPADC_OFSTRIM_COUNT == 2U)
    LPADC_SetOffsetValue(DEMO_LPADC_BASE, DEMO_LPADC_OFFSET_VALUE_A, DEMO_LPADC_OFFSET_VALUE_B);
#elif defined(FSL_FEATURE_LPADC_OFSTRIM_COUNT) &amp;&amp; (FSL_FEATURE_LPADC_OFSTRIM_COUNT == 1U)
    LPADC_SetOffsetValue(DEMO_LPADC_BASE, DEMO_LPADC_OFFSET_VALUE);
#endif /* FSL_FEATURE_LPADC_OFSTRIM_COUNT */

#else/* For other OFSTRIM register type. */
    if (DEMO_LPADC_OFFSET_CALIBRATION_MODE == kLPADC_OffsetCalibration12bitMode)
    {
      LPADC_SetOffset12BitValue(DEMO_LPADC_BASE, DEMO_LPADC_OFFSET_VALUE_A, DEMO_LPADC_OFFSET_VALUE_B);
    }
    else
    {
      LPADC_SetOffset16BitValue(DEMO_LPADC_BASE, DEMO_LPADC_OFFSET_VALUE_A, DEMO_LPADC_OFFSET_VALUE_B);
    }
#endif /* FSL_FEATURE_LPADC_HAS_OFSTRIM */

#endif /* DEMO_LPADC_DO_OFFSET_CALIBRATION */
#endif /* FSL_FEATURE_LPADC_HAS_CTRL_CALOFS */

#if defined(FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ) &amp;&amp; FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ
    /* Request auto calibration (including gain error calibration and linearity error calibration). */
    LPADC_DoAutoCalibration(DEMO_LPADC_BASE);
#endif /* FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ */

#if (defined(FSL_FEATURE_LPADC_HAS_CFG_CALOFS) &amp;&amp; FSL_FEATURE_LPADC_HAS_CFG_CALOFS)
    /* Do auto calibration. */
    LPADC_DoAutoCalibration(DEMO_LPADC_BASE);
#endif /* FSL_FEATURE_LPADC_HAS_CFG_CALOFS */

#if (defined(FSL_FEATURE_LPADC_HAS_CFG_CALOFS) &amp;&amp; FSL_FEATURE_LPADC_HAS_CFG_CALOFS)
    /* Do auto calibration. */
    LPADC_DoAutoCalibration(DEMO_LPADC_BASE);
#endif /* FSL_FEATURE_LPADC_HAS_CFG_CALOFS */

    /* Set conversion CMD configuration. */
    LPADC_GetDefaultConvCommandConfig(&amp;mLpadcCommandConfigStruct);
    mLpadcCommandConfigStruct.channelNumber = DEMO_LPADC_USER_CHANNEL;
#if defined(DEMO_LPADC_USE_HIGH_RESOLUTION) &amp;&amp; DEMO_LPADC_USE_HIGH_RESOLUTION
    mLpadcCommandConfigStruct.conversionResolutionMode = kLPADC_ConversionResolutionHigh;
#endif /* DEMO_LPADC_USE_HIGH_RESOLUTION */
    LPADC_SetConvCommandConfig(DEMO_LPADC_BASE, DEMO_LPADC_USER_CMDID, &amp;mLpadcCommandConfigStruct);

    /* Set trigger configuration. */
    LPADC_GetDefaultConvTriggerConfig(&amp;mLpadcTriggerConfigStruct);
    mLpadcTriggerConfigStruct.targetCommandId       = DEMO_LPADC_USER_CMDID;   /* CMD15 is executed. */
    mLpadcTriggerConfigStruct.enableHardwareTrigger = false;
    LPADC_SetConvTriggerConfig(DEMO_LPADC_BASE, 0U, &amp;mLpadcTriggerConfigStruct); /* Configurate the trigger0. */

    /* Enable the watermark interrupt. */
#if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) &amp;&amp; (FSL_FEATURE_LPADC_FIFO_COUNT == 2U))
    LPADC_EnableInterrupts(DEMO_LPADC_BASE, kLPADC_FIFO0WatermarkInterruptEnable);
#else
    LPADC_EnableInterrupts(DEMO_LPADC_BASE, kLPADC_FIFOWatermarkInterruptEnable);
#endif /* FSL_FEATURE_LPADC_FIFO_COUNT */
    EnableIRQ(DEMO_LPADC_IRQn);

    PRINTF("ADC Full Range: %d\r\n", g_LpadcFullRange);</code></pre>

<p><strong>3、测试过程</strong></p>

<p>将J8的28pin和GND短接进行测试。</p>

<p> &nbsp;</p>

<p>经过多次测试,发现电压的范围变化不是很大。最高不超过2,2*3.3/4096=1.6mV毫伏。如果做平均则可以几乎接近为0V电压。</p>

<p>将J8接口28pin与信号发生器输出相接,信号输出设置为1.5V,输出如下:</p>

<p> &nbsp;</p>

<p>大致在1961附近跳动,理论电压为1961*3.3/4096=1.579V,由于参考电压VDD_ANA为电源电压直接连接。所以对实际的电压进行测量为:3.27V</p>

<p> &nbsp;</p>

<p>1961*3.27/4096=1.5655V,从测量来看,电压的精度一般。信号发生器的输出1.5014V(万用表测量值)。</p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p>使用的是lpADC设备,顺便测量了一下功耗,16.49*3.27=53.9mW,ADC和串口的共同功耗为53.9毫瓦。</p>

<p><strong>&nbsp; 4、总结</strong></p>

<p>本次测试ADC从数值分析ADC的精度不是十分理想(也可以是无法获得实际参考电压的原因),功耗也较低功耗应用有一定的差距。本次的测试也可以受限测量方法的原因,所以有知道的请告知。</p>

<p>&nbsp;</p>

Jacktang 发表于 2025-1-22 07:48

<p>ADC从数值分析ADC的r虽然精度不是十分理想,测试的方法还是值得借鉴</p>

秦天qintian0303 发表于 2025-1-22 09:21

<p>整体的功耗外设太多了,不过才16mA确实也挺不错的&nbsp;&nbsp;</p>
页: [1]
查看完整版本: 【FRDM-MCXN947测评】AD采集和设置测试及功耗测量