Xmega 32A4 and ADC

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

I'm struggeling with the ADC on my 32A4 device.
The code below describes the setup, function called each ms and the interrupts.
I tries to convert 7 input at portA. A 2.5V extern reference is connected on PIN0. The conversion on PIN1 seems to be OK. I have muxed this to both ADch0 and 1. But if do the same with PIN2 (and other) it is not working. (The voltage on the input pins is measured and OK.) PORTA is not canged and ar input.

Can anybody help me?

//Setting up the ADC
ADCA.CTRLB =  ADC_RESOLUTION_12BIT_gc | ( false ? ADC_CONMODE_bm : 0);  //12 bit, unsigned
ADCA.REFCTRL = ADC_REFSEL_AREFA_gc | ADC_BANDGAP_bm ;                   // ref on port A (pin0)
ADCA.PRESCALER = ADC_PRESCALER_DIV256_gc;
ADCA.CH0.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc | ADC_CH_GAIN_1X_gc;    // single end, gain 1
ADCA.CALH = (CLD.ADCACAL >> 8) & 0xff;                                  // load the cal value
ADCA.CALL = CLD.ADCACAL & 0xff;

ADCA.CH0.INTCTRL = ADC_CH_INTLVL0_bm ;      //set interrupt
ADCA.CH1.INTCTRL = ADC_CH_INTLVL0_bm ;      //set interrupt
ADCA.CH2.INTCTRL = ADC_CH_INTLVL0_bm ;      //set interrupt
ADCA.CH3.INTCTRL = ADC_CH_INTLVL0_bm ;      //set interrupt
ADCA.CTRLA |= ADC_ENABLE_bm;

// This function i called every 1 ms.
switch ( adgroup ) {
case 0:
    adcmode= adgroup *4;
    ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN1_gc ;  // AD0
    ADCA.CH1.MUXCTRL = ADC_CH_MUXPOS_PIN2_gc ;  // AD1
    ADCA.CH2.MUXCTRL = ADC_CH_MUXPOS_PIN3_gc ;  // AD2
    ADCA.CH3.MUXCTRL = ADC_CH_MUXPOS_PIN4_gc ;  // AD3
    ADCA.CTRLA |= (ADC_CH0START_bm | ADC_CH1START_bm | ADC_CH2START_bm | ADC_CH3START_bm);
    break;
case 1:
    adcmode= adgroup *4;
    ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN5_gc ;  // AD0
    ADCA.CH1.MUXCTRL = ADC_CH_MUXPOS_PIN6_gc ;  // AD1
    ADCA.CH2.MUXCTRL = ADC_CH_MUXPOS_PIN7_gc ;  // AD2
    ADCA.CH3.MUXCTRL = ADC_CH_MUXPOS_PIN1_gc ;  // AD3
    ADCA.CTRLA |= (ADC_CH0START_bm | ADC_CH1START_bm | ADC_CH2START_bm | ADC_CH3START_bm );
    break;
}


ISR ( ADCA_CH0_vect ){
    ADData[0 + adcmode] = ADCA.CH0.RES - 200;       // subtract offset, see page 292 and 295 in manual
}
ISR ( ADCA_CH1_vect ){
    ADData[1 + adcmode] = ADCA.CH1.RES -200;
}

ISR ( ADCA_CH2_vect ){
    ADData[2 + adcmode] = ADCA.CH2.RES - 200;
}
ISR ( ADCA_CH3_vect ){
    ADData[3 + adcmode] = ADCA.CH3.RES - 200;
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm trying to understand your code. Is what you've posted working correctly or is it not? If it isn't, which part is not working like you think it should.

I haven't used ADC interrupts on the xmega yet, but I've been able to mux between pins when using the polling method.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

My code is working for PIN1 moxed to ADCH0 but not for the rest of the PINs.
But if I mux PIN2 to ADCH0 it is not working.
The function starte with switch is called each 1 ms so I switch between adgroup 0 and 1 each time to convert all 7 pins on the port.
May be it is more clear now.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

1. I think that there is no need to use ADC_BANDGAP_bm if it's external referenced;

2. You're setting MUX each time for each channel used, but the INPUTMODE you set just once, for channel 0 only.

ADCA.CH0.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc | ADC_CH_GAIN_1X_gc;    // single end, gain 1

Try to do it with other channels too.

Hope this will help.