[SOLVED] mega328pb ADC auto trigger only run once?

Hi, I am trying to use ADC auto triggered by TIMER0 CTC mode.
But, If I don't enable the TIMER0 interrupt, ADC will only trigger once.
Otherwise, it is working.

Is there necessary to enable TIMER0 interrupt? or I made wrong setting?

Here is my code. Thanks.

    // -----------------------------------
    // Timer0, for ADC trigger
    // Clear Timer on Compare Match (CTC) Mode
    // f = cpu_f / (2 * N * (1 + OCR0A))
    // WGM   [1:0] = 10, CTC Mode
    TCCR0A = _BV(WGM01);
    
    // CS    [2:0] = 011, clkIO/64 (From prescaler)
    // f = 8000000 / (2 * N * (1 + OCR0A))
    // f = 500Hz
    // OCR0A = 8000000 / 500 / (2*64) - 1 = 125
    TCCR0B = _BV(CS01) | _BV(CS00);
    OCR0A  = (uint8_t)125;
    TIMSK0 = _BV(OCIE0A);


    // -----------------------------------
    // ADC
    // Trigger by Timer0 500Hz * 2 = 1000Hz
    // PC0, AD0
    // REFS [7:6] =   11, Internal 1.1V Voltage Reference with external capacitor at AREF pin
    // ADLAR[ 0 ] =    0, right adjusted
    // MUX  [3:0] = 0000, ADC0
    ADMUX = _BV(REFS1) | _BV(REFS0);
    
    // ADEN [ 7 ] = 1, Enable ADC
    // ADATE[ 5 ] = 1, ADC Auto Trigger Enable
    // ADIE [ 3 ] = 1, ADC Interrupt Enable
    // ADPS [2:0] = 111, Division Factor 128
    // ADC_f = 8000000 / 128 = 62500
    ADCSRA = _BV(ADEN) | _BV(ADATE) | _BV(ADIE) | _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0);
    
    // ADTSn[2:0] = 011, Trigger Source = Timer/Counter0 Compare Match A
    ADCSRB = _BV(ADTS1) | _BV(ADTS0);
    
    // When the respective bits are written to logic one,
    // the digital input buffer on the corresponding ADC pin is disabled.
    DIDR0 = _BV(ADC0D);

    ISR(TIMER0_COMPA_vect) {
        // do nothing
    }

    volatile uint16_t adc_v;
    ISR(ADC_vect) {
        Toggle_LED(); // for oscilloscope to check ADC conversion working
        adc_v = ADC;
    }

The ADC is triggered by the rising edge of the COMPA interrupt flag. If you don't clear the flag there won't be a rising edge to trigger the ADC. The flag is cleared when the ISR runs or you can clear the flag by writing the appropriate bit in the interrupt flag register. See the datasheet.

@qscgy4, do not cross-post. Other thread removed.

tf68:
The ADC is triggered by the rising edge of the COMPA interrupt flag. If you don't clear the flag there won't be a rising edge to trigger the ADC. The flag is cleared when the ISR runs or you can clear the flag by writing the appropriate bit in the interrupt flag register. See the datasheet.

Thank you!!

Sorry, I tried to delete the other post, but i can't find delete button :frowning:

qscgy4:
Sorry, I tried to delete the other post, but i can't find delete button :frowning:

Use the "Report to moderator" for deletions, moves, merges, bad behaviour, etc.

Could you also take a few moments to Learn How To Use The Forum.
It will help you get the best out of the forum in the future.
Other general help and troubleshooting advice can be found here.

ballscrewbob:
Use the "Report to moderator" for deletions, moves, merges, bad behaviour, etc.

Could you also take a few moments to Learn How To Use The Forum.
It will help you get the best out of the forum in the future.
Other general help and troubleshooting advice can be found here.

OK!