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"); 
} 
Majenko
106k5 gold badges81 silver badges139 bronze badges
asked Oct 24, 2014 at 9:59
1
  • 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. Commented Oct 24, 2014 at 18:11

1 Answer 1

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.

answered Oct 24, 2014 at 10:17
4
  • Ok thanks, but why if I increment prescaler setting and threshold the program works? Commented Oct 24, 2014 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. Commented Oct 24, 2014 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. Commented Oct 24, 2014 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. Commented Feb 10, 2016 at 13:53

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.