【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> </p>
<p> </p>
<p><strong>2、程序与测试设置</strong></p>
<p>将MCU的ADC0的通道A2打开。</p>
<p> 编写中断和初始化程序</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) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2U))
if (LPADC_GetConvResult(DEMO_LPADC_BASE, &g_LpadcResultConfigStruct, 0U))
#else
if (LPADC_GetConvResult(DEMO_LPADC_BASE, &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(&mLpadcConfigStruct);函数取得默认配置,填充默认值。</p>
<p>2)对mLpadcConfigStruct各域进行赋值,即进行设置。</p>
<p>将预制值打开</p>
<p>选择参考电压源</p>
<p>选择均值模式</p>
<p>初始化ADC</p>
<pre>
<code class="language-cpp">LPADC_GetDefaultConfig(&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) && FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS
mLpadcConfigStruct.conversionAverageMode = kLPADC_ConversionAverage128;
#endif /* FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS */
LPADC_Init(DEMO_LPADC_BASE, &mLpadcConfigStruct);</code></pre>
<p>设置采集模式和校准ADC。</p>
<pre>
<code class="language-cpp">/* Request LPADC calibration. */
#if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE) && 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) && FSL_FEATURE_LPADC_HAS_CTRL_CALOFS
#if defined(DEMO_LPADC_DO_OFFSET_CALIBRATION) && 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) && FSL_FEATURE_LPADC_HAS_OFSTRIM
#if defined(FSL_FEATURE_LPADC_OFSTRIM_COUNT) && (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) && (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) && 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) && 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) && 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(&mLpadcCommandConfigStruct);
mLpadcCommandConfigStruct.channelNumber = DEMO_LPADC_USER_CHANNEL;
#if defined(DEMO_LPADC_USE_HIGH_RESOLUTION) && DEMO_LPADC_USE_HIGH_RESOLUTION
mLpadcCommandConfigStruct.conversionResolutionMode = kLPADC_ConversionResolutionHigh;
#endif /* DEMO_LPADC_USE_HIGH_RESOLUTION */
LPADC_SetConvCommandConfig(DEMO_LPADC_BASE, DEMO_LPADC_USER_CMDID, &mLpadcCommandConfigStruct);
/* Set trigger configuration. */
LPADC_GetDefaultConvTriggerConfig(&mLpadcTriggerConfigStruct);
mLpadcTriggerConfigStruct.targetCommandId = DEMO_LPADC_USER_CMDID; /* CMD15 is executed. */
mLpadcTriggerConfigStruct.enableHardwareTrigger = false;
LPADC_SetConvTriggerConfig(DEMO_LPADC_BASE, 0U, &mLpadcTriggerConfigStruct); /* Configurate the trigger0. */
/* Enable the watermark interrupt. */
#if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (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> </p>
<p>经过多次测试,发现电压的范围变化不是很大。最高不超过2,2*3.3/4096=1.6mV毫伏。如果做平均则可以几乎接近为0V电压。</p>
<p>将J8接口28pin与信号发生器输出相接,信号输出设置为1.5V,输出如下:</p>
<p> </p>
<p>大致在1961附近跳动,理论电压为1961*3.3/4096=1.579V,由于参考电压VDD_ANA为电源电压直接连接。所以对实际的电压进行测量为:3.27V</p>
<p> </p>
<p>1961*3.27/4096=1.5655V,从测量来看,电压的精度一般。信号发生器的输出1.5014V(万用表测量值)。</p>
<p> </p>
<p> </p>
<p>使用的是lpADC设备,顺便测量了一下功耗,16.49*3.27=53.9mW,ADC和串口的共同功耗为53.9毫瓦。</p>
<p><strong> 4、总结</strong></p>
<p>本次测试ADC从数值分析ADC的精度不是十分理想(也可以是无法获得实际参考电压的原因),功耗也较低功耗应用有一定的差距。本次的测试也可以受限测量方法的原因,所以有知道的请告知。</p>
<p> </p>
<p>ADC从数值分析ADC的r虽然精度不是十分理想,测试的方法还是值得借鉴</p>
<p>整体的功耗外设太多了,不过才16mA确实也挺不错的 </p>
页:
[1]