S32K ADC calibration

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

S32K ADC calibration

1,203 Views
k_g
Contributor II

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();		
}

 

 

0 Kudos
1 Reply

1,175 Views
danielmartynek
NXP TechSupport
NXP TechSupport

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

 

0 Kudos