MK22FN128VLH10 ADC noise

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MK22FN128VLH10 ADC noise

829 Views
양승도
Contributor II

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.

0 Kudos
1 Reply

606 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Frank,

Regarding your question, I have some recommendation, but I do not guarantee to solve your problem, pls have a try.

1)from the schematics, it seems you use 10K ohm serial resistor on the ADC channel, it is too large, pls use 100 ohm or less.

2)The ADC clock frequency takes effect on the ADC accuracy, note that the ADC clock frequency should range from 2mHz to 12Mhz for K22, I suggest you set the fADCK as 2MHz to 8mhz.

How about not calibrating for a try.

For the firmware, I suggest you call the following function in ISR rather than in while(1). If you call it in while(), you should set a flag in ISR and poll the flag in while().

ADC16_DRV_ConfigConvChn( FSL_ADCONV1, ADC16_CHN_GROUP,

&adConv1_ChnConfig1 );   // Software trigger the conversion.

BR

Xiangjun Rong

0 Kudos