Serial comm issue: serial_send serial_send_blocking

I am trying to use a timer to record an array of data for a fixed sample time. So I set timer1 which is not used in the avr-pololu lib and use interrupt to call serial communication functions. I used the following code for timer setting and interruption.

void timer1_init(void) { DDRB |= (1 << 0); // Set LED as output TCCR1B |= (1 << WGM12); // Configure timer 1 for CTC mode TIMSK1 |= (1 << OCIE1A); // Enable CTC interrupt sei(); // Enable global interrupts OCR1A = 53391; // Set CTC compare value to 10Hz at 20MHz AVR clock, with a prescaler of 8 TCCR1B |= (1 << CS11); // Start timer at Fcpu/8 }

ISR(TIMER1_COMPA_vect) { set_digital_output(IO_B0, TOGGLE); //wait_for_sending_to_finish(); sprintf(send_buffer,"%d\r\n",1); serial_send_blocking(send_buffer,strlen(send_buffer)); //serial_send(send_buffer,strlen(send_buffer)); }
One interesting thing is, when I use the combination of serial_send and wait_for_sending_to_finish(), the interruption only happens once, and stuck at the second “wait_for_sending_to_finish”. However, when I tried the serial_send_blocking, which as I see is nothing but combination of serial_send and wait_for_sending_to_finish(), it works well.

I am very curious about what happened here. Hope anybody is interesting and give me some clue.

Thanks for your concerns.

Hello.

The problem is that you are inside an interrupt when you are trying to use the interrupt-driven serial functions. When an interrupt service routine executes, it by default prevents other interrupts from being able to execute. Because of this and the nature of interrupts, the general strategy should be to make them minimally invasive (i.e. short and quick), so you should as much as possible avoid slow things in interrupts, such as serial communication. A better approach would be to have the interrupt set a flag (this should be a volatile variable) and then poll the state of that flag in your main loop.

-Jamee

[quote=“Jamee”]Hello.

The problem is that you are inside an interrupt when you are trying to use the interrupt-driven serial functions. When an interrupt service routine executes, it by default prevents other interrupts from being able to execute. Because of this and the nature of interrupts, the general strategy should be to make them minimally invasive (i.e. short and quick), so you should as much as possible avoid slow things in interrupts, such as serial communication. A better approach would be to have the interrupt set a flag (this should be a volatile variable) and then poll the state of that flag in your main loop.

-Jamee[/quote]

Thanks for your explanation. That is exactly I suspected.