ATmega328P ADC help - Page 1
Forum section: electronics / general

author: technix
author_rank: Super Contributor
timestamp: November 11, 2017, 12:46:02 pm
content: I am trying to set up continuous conversion on ATmega328P ADC. However the ADC interrupt is not firing. What mistake am I making here?Code:void adc_init(void){skip_sample = true;sample_id = 0;ADMUX = 0;ADCSRA = _BV(ADEN) | _BV(ADATE) | _BV(ADIE) | _BV(ADPS1) | _BV(ADPS0);ADCSRB = 0;DIDR0 = _BV(ADC0D);ADCSRA |= _BV(ADSC) | _BV(ADIF);}

author: MasterT
author_rank: Frequent Contributor
timestamp: November 11, 2017, 01:21:34 pm
content: Have you missed to include interrupt subroutine?

author: Siwastaja
author_rank: Super Contributor
timestamp: November 11, 2017, 02:14:31 pm
content: Interrupts still globally turned off? I.e., have you forgotten sei()?

author: StillTrying
author_rank: Super Contributor
timestamp: November 11, 2017, 02:28:18 pm
content: _BV(ADPS1) | _BV(ADPS0);Implies the system clock is only 1.6Mhz.Should ADIFbe ADIE.

author: technix
author_rank: Super Contributor
timestamp: November 11, 2017, 02:50:43 pm
content: Quote from: Siwastaja on November 11, 2017, 02:14:31 pmInterrupts on. Other interrupts are firing normally.

author: technix
author_rank: Super Contributor
timestamp: November 11, 2017, 02:55:52 pm
content: Quote from: MasterT on November 11, 2017, 01:21:34 pmThat is where a portion of application code resides. Those are left out intentionally.

author: technix
author_rank: Super Contributor
timestamp: November 11, 2017, 02:58:53 pm
content: Quote from: StillTrying on November 11, 2017, 02:28:18 pmI have a 8MHz clock. Changed the clock divider to ck/64 (125kHz at 8MHz system clock) but still no luck.I have set both ADIF and ADIE, set ADIF to clear it, set ADIE to enable the interrupt.

author: MasterT
author_rank: Frequent Contributor
timestamp: November 11, 2017, 03:27:57 pm
content: Quote from: technix on November 11, 2017, 02:55:52 pmHow we supposed to know your spelling is correct?ISR(ADC_vect) {}And what makes you think it's not fired?

author: technix
author_rank: Super Contributor
timestamp: November 11, 2017, 03:45:03 pm
content: Quote from: MasterT on November 11, 2017, 03:27:57 pmI have no compiler warning or error with -Wall, which makes me believe that my spelling is correct. Missed typings on function prototype will lead to a compiler warning.I have a breakpoint on this function (I am debugging through an Atmel ICE) but the it is not hit.

author: HwAoRrDk
author_rank: Super Contributor
timestamp: November 11, 2017, 04:12:04 pm
content: Quote from: Siwastaja on November 11, 2017, 02:14:31 pmSigh, been there. I once spent the better part of an entire day banging my head against the wall trying to figure out what was going on before I realised.

author: Siwastaja
author_rank: Super Contributor
timestamp: November 11, 2017, 04:41:10 pm
content: Try this:Code:ISR(ADC_vect){// turn on LED here. Never turn it off, so you can see if this ever fires}main(){// turn on LED here to test it worksdelay_ms(500);// turn off LED heredelay_ms(500);ADMUX = 0; // should be irrelevant to this problem// Magical code lines copypasted from some of my old random project, which works, runs ADC (ATMega640) in continuous mode and gives interrupts:ADCSRB = 0b00000000; // free running modeADCSRA = 0b11101110; // prescaler = 64: auto trigger.// and...sei();while(1);}If this works, just compare what's different between this and yours.

author: georges80
author_rank: Frequent Contributor
timestamp: November 11, 2017, 06:13:08 pm
content: We assume you haven't powered down the ADC via the PRR0 register.Besides... You have set the auto trigger bits to free running (000). From the datasheet:If ADATE in ADCSRA is written to one, the value of these bits selects which source will trigger an ADCconversion. If ADATE is cleared, the ADTS[2:0] settings will have no effect. A conversion will be triggeredby the rising edge of the selected Interrupt Flag. Note that switching from a trigger source that is clearedto a trigger source that is set, will generate a positive edge on the trigger signal. If ADEN in ADCSRA isset, this will start a conversion. Switching to Free Running mode (ADTS[2:0]=0) will not cause a triggerevent, even if the ADC Interrupt Flag is set.Table 29-6 ADC Auto Trigger Source SelectionADTS[2:0] Trigger Source000 Free Running mode001 Analog Comparator010 External Interrupt Request 0011 Timer/Counter0 Compare Match A100 Timer/Counter0 Overflow101 Timer/Counter1 Compare Match B110 Timer/Counter1 Overflow111 Timer/Counter1 Capture EventHint: Seems to imply that no trigger even will occur in free running mode... No trigger event means a new conversion won't be initiated.cheers,george.

author: technix
author_rank: Super Contributor
timestamp: November 11, 2017, 06:47:24 pm
content: Quote from: Siwastaja on November 11, 2017, 04:41:10 pmNot working...Quote from: georges80 on November 11, 2017, 06:13:08 pmI have tried to sort-of emulate continuous mode by not setting ADATE in adc_init, but set ADSC in the end of the ADC interrupt. No luck either, there isn't even an initial conversion.

author: Siwastaja
author_rank: Super Contributor
timestamp: November 11, 2017, 10:13:47 pm
content: Look at the ADC flag register, and the conversion result register - are the flags/value updating? What do the flags say? This way you can rule out either one:1) ADC not enabled at all, or not triggering2) ADC converting, but interrupt not firingIf case 2, can you set a breakpoint in the interrupt vector table - or at least take a look at the binary? That would verify there is no issue in the jump table generation. (If I remember the AVR architecture correctly.)

author: Siwastaja
author_rank: Super Contributor
timestamp: November 11, 2017, 10:34:11 pm
content: Have you tried single shot first? It would narrow down possibilities.For example, try this oneliner if you like to try random things by magic number copypasting:// ADCSRB = 0 as reset valuesei();ADCSRA = 0b11001110;