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.