3

I'm trying to use CTC mode on Arduino 1 but I have the following problem. I need to generate an interrupt on threshold B and A and I have set the prescaler to 1 since I want to generate interrupt A at 15999 (correspond to 1ms) and interupt B at 15( ie a number small enough from the start of counting). I'have write a println function in ISR(A and B) to proof the calling of the latter but the program does not print all the characters in the println function and furthermore the counter does not reset at treshold A but stop his work. How I can resolve the problem?

Here is the program I wrote:

void setup() {  
    TCCR1A = 0x00;                // No outputs on compare math, no PWM mode    
    TCCR1B = 1 | (1 << WGM12);    // Enable CTC mode up to OCR1A and prescaler /1 -> Start
    //TCCR1B = 0b00001001;  
    TCCR1C = 0x00;                // Nothing to set into C register  


    OCR1A = 15999;                // Set Threshold A  
    OCR1B = 15;                // Set Threshold B  
    TCNT1 = 0;                    // Clear Counter  

    TIFR1 = (1 << OCIE1A) | (1 << OCIE1B);    // Clear Interrupt flag Match A and B

    TIMSK1 = (1 << OCIE1A) | (1 << OCIE1B);   // Enable Interrapt flag Match A and B

    analogRead(A0);            // Dummy Read to make Arduino setting the AD  
    ADCSRA |= (1 << ADIE);     // Enable AD Interrupt on conversion completed  
    ADCSRB = 5;                // Select Timer 1 Match B as trigger  
    ADCSRA |= 1 << ADATE;      // Enable Auto trigger  


    Serial.begin(115200);      // Initialize the USART  
    Serial.println("Start");   // Write the welcome message  



}  

void loop() {  
    // Nothing to do    
}  


ISR(ADC_vect)  
{ 
    Serial.print(TCNT1);  
    Serial.print(" - ADC Conversion Completed (");   
    Serial.print(ADC);  
    Serial.println(")");  
}

ISR(TIMER1_COMPA_vect)  
{  
    TCNT1=0;  
    Serial.print(TCNT1);  
    Serial.println(" - Interrupt A");  
}  

ISR(TIMER1_COMPB_vect)  
{  
    Serial.print(TCNT1);  
    Serial.println(" - Interrupt B");  
}  
  • In CTC mode TCNT1 is automatically set back to 0 when it reaches OCR1A. So there is no need to do that inside the ISR. In fact TCNT1 might have already increase in value by the time the ISR is called, so the interval would be slightly more that the 1ms you want. – Gerben Oct 24 '14 at 18:11
4

I don't know about configuring the timers on an AVR off hand, but one thing I will point out:

  • Never ever use Serial in an ISR.

Serial is interrupt driven - when there are characters in the outgoing serial buffer an interrupt routine sends them out through the serial port. That can't happen when you're in an interrupt routine yourself, so when the buffer fills up the next Serial.write() (print, etc) blocks until there is room in the buffer for the next character. As the ISR can't run, that space never appears, so the print(), write(), etc never finish and the program locks up.

Instead you should store any incoming values in your ISRs into volatile variables, and set flags to indicate to your main program what has happened in the ISR - then your main loop() reads (and resets) those flags and prints out the statuses you want.

  • Ok thanks, but why if I increment prescaler setting and threshold the program works? – lui14 Oct 24 '14 at 10:44
  • If you're running the timer slower you're giving it more time between ISR calls to empty out the serial buffer. – Majenko Oct 24 '14 at 11:31
  • 1
    serial in an ISR is still bad practice; However, the arduino Serial library detects if interrupts are disabled and will manually run the serial interrupt handlers when necessary so lock up never happens. printing will take a (relatively) long and inconsistent amount of time though. – BrettAM Oct 24 '14 at 16:44
  • @BrettAM: Interesting, thanks for the note. This seems to be the case since release 1.5.6 BETA. Interestingly, it appears that, although this behaviour was implemented in April 2013, almost a month before the 1.0.5 release, it didn't make it to 1.0.5, ant not even to 1.0.6, which came eight months after 1.5.6 BETA. – Edgar Bonet Feb 10 '16 at 13:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.