I am trying to amplify an input signal of 500 uV Vp-p and when i saw the output it was generating a spike going from 65000 and 0. The output looks how an unstable amplifier behaves. This happens even if I don't apply the signals. This is the code I have used to make the PGA work. Also I don't have good idea on how to select the Vref for the PGA. As of now my ADC0 is connected to external Vref.
Code :
This is done to enable the PGA
void adc_pga_config()
{
ADC0_PGA = 0x960000;
//vref_init();
}
// intialise the adc0
void ADC0_Init16b(void)
{
SIM_SCGC6 |= SIM_SCGC6_ADC0_MASK; //Gives clock to ADC0
ADC0_CFG1 = (ADC_CFG1_MODE(3) | ADC_CFG1_ADIV(2)); //16bit mode
ADC0_SC1A = ADC_SC1_ADCH(31); //disable module
/* Configure ADC pins as ADC Inputs manually */
/*In Kinetis the ADC pins are ADC inputs by default */
}
// Function used to get the adc value
unsigned short ADC0_Read16b(unsigned char channelNumber)
{
ADC0_SC1A = 0x22; /* Write to ADCSC1 to start conversion */
while (!(ADC0_SC1A & 0xA2)); /* Wait until the conversion is complete */
return ADC0_RA;
}
Connection :
Input is connected to PGA0_DP0 and PGA0_DM0 is connected to ground. ADC0 channel 2 is used to capture the signal .
Help me out with this one. Thanks in advance.
Dear Renganathan,
I do not know the Kinetis chip you are using. But I have tested on my TWR-K40x256, pls refer to section 3.7.1.9 PGA Integration in the K40P144M100SF2RM.PDF, I suppose the differential input analog pins with PGA is PGA0_DP/ADC0_DP0/ADC1_DP3 and PGA0_DM/ADC0_DM0/ADC1_DM3, only the differential channel DAD2 for K40 is connected to the PGA output, if you use DAD2 channel to measure the differential voltage, you have to Enable PGA. If you disable PGA, the sample of DAD2 channel may be unexpected.
This is the code and the result.
I connect the pin PGA0_DM/ADC0_DM0/ADC1_DM3 to GND, connect the pin PGA0_DP/ADC0_DP0/ADC1_DP3 to 3.3V via A27&A28 on tower primary board, the sample variable is 0x7E0b, it is okay.
The Differential voltage=(0x7E0B*6.6V)/0x7FFF=3.249V.
BTW, because you use differential channel, the common mode voltage should be considered, if you use PGA, the common mode voltage is also amplified, Note that the absolute voltage after PGA amplifier for both DP/DM pin should be less than 3.3V. I suppose the PGA voltage is 3.3V.
I copy the code here:
void ADC0_Init16b(void);
unsigned short ADC0_Read16b(unsigned int channelNumber);
void adc_pga_config(void);
unsigned int sample;
int main(void)
{
int counter = 0;
ADC0_Init16b();
adc_pga_config();
for(;;) {
sample=ADC0_Read16b(0x02);
asm("nop"); //set break point here to check the return value
counter++;
}
return 0;
}
void adc_pga_config(void)
{
//ADC0_PGA = 0x960000;
ADC0_PGA = 0x900000;
//vref_init();
}
// intialise the adc0
void ADC0_Init16b(void)
{
SIM_SCGC6 |= SIM_SCGC6_ADC0_MASK; //Gives clock to ADC0
ADC0_CFG1 = (ADC_CFG1_MODE(3) | ADC_CFG1_ADIV(2)|ADC_CFG1_ADICLK(1)); //16bit mode 50MHz/(2*4)=6MHz ADSC clock
//ADC0_SC1A = ADC_SC1_ADCH(31); //disable module
/* Configure ADC pins as ADC Inputs manually */
// ADC0_SC1A = ADC_SC1_ADCH(2);
/*In Kinetis the ADC pins are ADC inputs by default */
}
// Function used to get the adc value
unsigned short ADC0_Read16b(unsigned int channelNumber)
{
ADC0_SC1A |= 0x20; /* Write to ADCSC1 to start conversion */
ADC0_SC1A&=~(ADC_SC1_ADCH_MASK);
ADC0_SC1A |= ADC_SC1_ADCH(channelNumber);
while (!(ADC0_SC1A & 0x80)) {} /* Wait until the conversion is complete */
return ADC0_RA;
}