AnsweredAssumed Answered

MK22FN128VLH10 ADC noise

Question asked by Frank Yang on Mar 28, 2016
Latest reply on Mar 28, 2016 by xiangjun.rong

1. ADC generates Noise out and reads according value but, in very noise.

example when 1V was forced to ADC port at 16bit mode, it read 32882, 40049, 44011, 35050 in a short time.

2. I implemented the ADC in MK22FN128VLH10.

Environment:

Windows 10

KDS3.0

KSDK 1.2.0

3. Attached are "TPC Board_Program O.png", "MCU_ADC_port.png"

When applying MCU_ADC_port.png", and eleminating R1, R2 that means open ADC port from other circuit or connecting them,

pin 11(ADC1_DP0), pin 9(ADC0_DP0) generates noise like "TPC Board_Program O.png",

and reads swaying value.

4. I implemented two ways that are polling and interrupt.

My source code is as following:

- interrupt

const adc16_converter_config_t adConv1_InitConfig0 = {

  .lowPowerEnable =
false,

  .clkDividerMode = kAdc16ClkDividerOf1,


.longSampleTimeEnable = false,

  .resolution = kAdc16ResolutionBitOf16,

  .clkSrc = kAdc16ClkSrcOfBusClk,

  .asyncClkEnable =
false,

  .highSpeedEnable =
false,

  .longSampleCycleMode
=
kAdc16LongSampleCycleOf24,

  .hwTriggerEnable =
false,

  .refVoltSrc = kAdc16RefVoltSrcOfVref,

.continuousConvEnable
= false,

  .dmaEnable = false,

};

 

// HW compare

const adc16_hw_cmp_config_t adConv1_HwConfig0 = {

  .hwCmpEnable =
false,


.hwCmpGreaterThanEnable = false,

  .hwCmpRangeEnable =
false,

  .cmpValue1 = 0U,

  .cmpValue2 = 0U,

};

 

 

// VDDA

const adc16_chn_config_t adConv1_ChnConfig0 = {

  .chnIdx = kAdc16Chn29,


.convCompletedIntEnable = false,

  .diffConvEnable =
false

};

 

// ADC0_DP0

const adc16_chn_config_t adConv1_ChnConfig1 = {

  .chnIdx = kAdc16Chn0d,

  //.convCompletedIntEnable
= false,


.convCompletedIntEnable = true,

  .diffConvEnable =
false

};

 

// ADC1_DP0

const adc16_chn_config_t adConv1_ChnConfig2 = {

  .chnIdx = kAdc16Chn3d,

  //.convCompletedIntEnable
= false,

  .convCompletedIntEnable
= true,

  .diffConvEnable =
false

};

 

ADC16_DRV_Init(FSL_ADCONV1,
&adConv1_InitConfig0);

adc16_calibration_param_t adcCalibraitionParam;

ADC16_DRV_GetAutoCalibrationParam(FSL_ADCONV1,
&adcCalibraitionParam);

ADC16_DRV_SetCalibrationParam(FSL_ADCONV1,
&adcCalibraitionParam);

ADC16_DRV_Init(FSL_ADCONV1,
&adConv1_InitConfig0);

 

// ADC0 : MONITOR ->
Pressure Sensor

ADC16_DRV_ConfigConvChn(
FSL_ADCONV1, ADC16_CHN_GROUP, &adConv1_ChnConfig1
);     
// Software trigger the conversion.

// ADC1 : INPUT

ADC16_DRV_ConfigConvChn(
FSL_ADCONV1, ADC16_CHN_GROUP, &adConv1_ChnConfig2
);     
// Software trigger the conversion.

 

 

Main.c

while(1)

{

// ADC0 : MONITOR -> Pressure Sensor

ADC16_DRV_ConfigConvChn( FSL_ADCONV1, ADC16_CHN_GROUP,
&adConv1_ChnConfig1 );   // Software trigger the conversion.

// ADC1         : INPUT

ADC16_DRV_ConfigConvChn( FSL_ADCONV1, ADC16_CHN_GROUP,
&adConv1_ChnConfig2 );   // Software trigger the conversion.

}

 

Event.c

/*! adConv1 IRQ handler
*/

void ADC0_IRQHandler(void)

{

/*
Write your code here ... */

static
uint16_t readNr = 0;

if(readNr == 0) // ADC0, Pressure Sensor

    
{

readNr = 1;

Var_pressureAdc16 =
ADC16_DRV_GetConvValueSigned(FSL_ADCONV1, ADC16_CHN_GROUP);  
// Fetch the conversion value.

}

       else if(readNr == 1)   // ADC1, Input

      
{

             
readNr = 0;

Var_inputAdc16 = ADC16_DRV_GetConvValueSigned(FSL_ADCONV1,
ADC16_CHN_GROUP);       // Fetch the conversion
value.

}

}

 

- polling

adc16_converter_config_t
adcUserConfig;   // structure for user config

 

ADC16_DRV_StructInitUserConfigDefault(&adcUserConfig);

adcUserConfig.resolution = kAdc16ResolutionBitOf16;

ADC16_DRV_Init(FSL_ADCONV1,
&adcUserConfig);

ADC_Calibration();

ADC16_DRV_Init(FSL_ADCONV1,
&adcUserConfig);

 

uint16_t ADC16_Measure(uint32_t instance, uint16_t channel_group, adc16_chn_t channel)

{

       uint16_t adcValue;

    adc16_chn_config_t
chnConfig;

 

    // Configure the
conversion channel

    // differential and
interrupt mode disable.

  
chnConfig.
chnIdx     =
(
adc16_chn_t)channel;

  
chnConfig.
diffConvEnable = false;

  
chnConfig.
convCompletedIntEnable  = false;

 

    // Software trigger the
conversion.

  
ADC16_DRV_ConfigConvChn(instance, channel_group, &chnConfig);

 

    // Wait for the conversion
to be done.

  
ADC16_DRV_WaitConvDone(instance, channel_group);

 

    // Fetch the conversion
value.

    adcValue
= ADC16_DRV_GetConvValueSigned(instance, channel_group);

 

    // Pause the conversion.

  
ADC16_DRV_PauseConv(instance, channel_group);

 

    return adcValue;

}

 

 

 

 

Main.c

while(1)
{

Var_inputAdc16 =
ADC16_Measure(FSL_ADCONV1, ADC16_CHN_GROUP, ADC1_DP0);

}

Both issues...

 

I need a solution to eleminate noise from adc port and read exact value, ugently.

Outcomes