I'm very new to Arduino but have quite some embedded programming experience (arm platforms) for a few years now. So I thought I know how thinks are working.
It seems I'm wrong or missing something essential with my first Arduino experience.
The plan is to get analog value with a sample rate of 8kHz using timer 1 and ADC interrupt. Additionally a LCD, serial and I2C communication should be used on an Arduino Micro.
I started implementing my code and LCD and Serial output is working stand-alone. As soon as I setup timer1 interrupt my LCD doesn't show anything and also serial output is stopped. It seems that timer1 interrupt completely destroys everything since even uploading new code is only possible if I press the reset button and immediately upload code. If I wait until board is up /dev/ttyAMC0 disapears.
Problem occures if I enable the timer interrupt. When commenting the line setting TIMSK1 register LCD and serial works fine.
Here is my (stripped down) code.
#include <math.h>
#include <LiquidCrystal.h>
#define SAMPLE_RATEÂ Â Â Â Â Â Â Â 8000
LiquidCrystal lcd(12, 11, 10, 9, 8, 7, 6);
ISR(TIMER1_COMPA_vect)
{
  lcd.setCursor(0, 1);
  lcd.print(millis() / 1000);
}
void setup()
{
  // Start serial
  Serial.begin(9600);
  lcd.begin(20, 4);
  // Disable interrupts
  cli();
  /*
  * setup timer 1 to sample with SAMPLE_RATE Hz
  */
  // Normal operation and CTC mode
  TCCR1A &= ~(_BV(COM1A1) | _BV(COM1A0) | _BV(COM1B1) | _BV(COM1B0) | _BV(WGM11) | _BV(WGM10));
  // CTC with reset on OCR1A and no prescaler
  TCCR1B &= ~(_BV(WGM13) | _BV(CS11) | _BV(CS12));
  TCCR1B |= _BV(WGM12) | _BV(CS11) | _BV(CS10);
  OCR1A = F_CPU / SAMPLE_RATE;
  // Enable OCR1A interrupt
  TIMSK1 |= OCIE1A;
  // Enable interrupts
  sei();
  lcd.print("Hallo Welt");
}
void loop()
{
}
The code I posted was not the one I found the problem. I changed it a bit to find what causes the problem and also deleted not needed parts to post it here.
Moving the code from ISR (so it is completely empty) to loop() has exactly the same effect.
I also removed serial code because I thought that maybe serial uses timers and interrupts I break with my code. But I had a look at serial code and couldn't find any relationship to my timer.
Setting up the timer seems to be perfectly fine but as soon as I enable interrupt it stops working.
In my original code I used serial and LCD only in loop() for some debug outputs.
There's no reason to suppose the lcd library is re-entrant (technical term meaning
you can call its methods(*) from an ISR). In general few libraries are disigned to be
re-entrant, re-entrancy is difficult to achieve(+)
(*) In general methods that just return information without side-effects are likely to
work, but anything that causes output or has side-effects should not be called from
an ISR (as the library may already be executing).
(+) Some of the basic Arduino functions are re-entrant, like digitalWrite().
BTW I'm using "re-entrant" sloppily here, I'm mixing up "thread-safe" and "re-entrant"
I think.
Sorry, I think you got me wrong. I stripped it down to find out the root cause on my own. Not to post it here. Unfortunately I didn't undo my change to copy the print to LCD from loop() to ISR.
Here is the original code including serial:
#include <math.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 10, 9, 8, 7, 6);
ISR(TIMER1_COMPA_vect)
{
}
void setup()
{
  int32_t i = 0;
  pinMode(PIN_LCD_BL, OUTPUT);
  digitalWrite(PIN_LCD_BL, HIGH);
  // Start serial
  Serial.begin(9600);
  lcd.begin(20, 4);
  // Disable interrupts
  cli();
  /*
  * setup timer 1 to sample with SAMPLE_RATE Hz
  */
  // Normal operation and CTC mode
  TCCR1A &= ~(_BV(COM1A1) | _BV(COM1A0) | _BV(COM1B1) | _BV(COM1B0) | _BV(WGM11) | _BV(WGM10));
  // CTC with reset on OCR1A and no prescaler
  TCCR1B &= ~(_BV(WGM13) | _BV(CS11) | _BV(CS12));
  TCCR1B |= _BV(WGM12) | _BV(CS11) | _BV(CS10);
  OCR1A = F_CPU / SAMPLE_RATE;
  // Enable OCR1A interrupt
  TIMSK1 |= OCIE1A;
  // Enable interrupts
  sei();
  lcd.print("Hallo Welt");
}
void loop()
{
  lcd.setCursor(0, 1);
  lcd.print(millis() / 1000);
  Serial.println(millis() / 1000);
}
sketch_sep08a.ino: In function ‘void setup()’:
sketch_sep08a:15: error: ‘PIN_LCD_BL’ was not declared in this scope
sketch_sep08a:36: error: ‘SAMPLE_RATE’ was not declared in this scope