Hi,
I am trying calibration of ADC in S32K146. After integrating calibration of ADC, I am not getting proper readings (much worse than without calibration). Please point out any mistakes in calibration or initialization. Thanks in advance.
I am using the following code:
void ADC0_calibration(void)
{
PCC->PCCn[PCC_ADC0_INDEX] &=~ PCC_PCCn_CGC_MASK; // Disable clock to change PCS
PCC->PCCn[PCC_ADC0_INDEX] |= PCC_PCCn_PCS(6); // PCS=6: Select SPLLDIV2_CLK 40 MHz
PCC->PCCn[PCC_ADC0_INDEX] |= PCC_PCCn_CGC_MASK; // Enable bus clock in ADC
ADC0->CFG1 = ADC_CFG1_ADIV(1) // ADIV=1: Prescaler=2; 40/2= 20MHz
|ADC_CFG1_MODE(1) // MODE=1: 12-bit conversion
|ADC_CFG1_ADICLK(0); // Same clk
ADC0->CFG2 = 0x00000000C; // SMPLTS=12: sample time is 13 ADC clks
ADC0->SC2 = 0x00000000; // ADTRG=0: SW trigger
// ACFE,ACFGT,ACREN=0: Compare func disabled
// DMAEN=0: DMA disabled
// REFSEL=0: Voltage reference pins= VREFH, VREEFL
ADC0->SC3 = ADC_SC3_CAL(1)
|ADC_SC3_AVGE(1)
|ADC_SC3_AVGS(3);
while(((ADC0->SC1[0] & ADC_SC1_COCO_MASK)>>ADC_SC1_COCO_SHIFT)==0); //wait for COCO bit to set
}
After calibration, I am changing the clock frequency in this function:
void ADC0_init(void)
{
PCC->PCCn[PCC_ADC0_INDEX] &=~ PCC_PCCn_CGC_MASK; // Disable clock to change PCS
PCC->PCCn[PCC_ADC0_INDEX] |= PCC_PCCn_PCS(6); // PCS=6: Select SPLLDIV2_CLK 40 MHz
PCC->PCCn[PCC_ADC0_INDEX] |= PCC_PCCn_CGC_MASK; // Enable bus clock in ADC
ADC0->SC1[0] =0x00001F; /* ADCH=1F: Module is disabled for conversions*/
/* AIEN=0: Interrupts are disabled */
ADC0->CFG1 = 0x000000004; /* ADICLK=0: inputCLK=SPLLDIV2_CLK= 40 MHz
/* ADIV=0: Prescaler=1 */
/* MODE=1: 12-bit conversion */
ADC0->CFG2 = 0x00000000C; /* SMPLTS=12: sample time is 13 ADC clks */
ADC0->SC2 = 0x00000000; /* ADTRG=0: SW trigger */
/* ACFE,ACFGT,ACREN=0: Compare func disabled */
/* DMAEN=0: DMA disabled */
/* REFSEL=0: Voltage reference pins= VREFH, VREEFL */
ADC0->SC3 = 0x00000000; /* CAL=0: Do not start calibration sequence */
/* ADCO=0: One conversion performed */
/* AVGE,AVGS=0: HW average function disabled */
}
The functions are called in main function in the following sequence:
NormalRUNmode_80MHz() ; // Init clocks: 80 MHz sysclk & core, 40 MHz bus, 20 MHz flash
PORT_init() ; // Configure ports
ADC0_calibration(); //CALIBRATION
ADC0_init() ; // Init ADC resolution 12 bit
for(;;)
{
convertAdc0Chan(14); /* Convert Channel ADC0_SE14 */
while(adc0_complete()==0){} /* Wait for conversion complete flag */
x = read_adc0_chx();
delay();
}
Hello @k_g,
Please refer to AN12217 S32K1xx ADC guidelines, spec and configuration
3. Best practices to increase accuracy
https://www.nxp.com/docs/en/application-note/AN12217.pdf
So it could be unstable VREFH, for example.
Based on your code, the sampling is very fast on a single pin.
What source resistance is there on the input?
Do you use an RC filter on the pin?
Have you tried measuring the input voltage with an oscilloscope during the conversion?
Regards,
Daniel