Пожалуйста, рассмотрите следующий пример (пробовал в Arduino IDE 0022, Ubuntu 11.04, Arduino AtMEGA 2560), где я пытаюсь запустить прерывание таймера / счетчика и одновременно использовать класс Arduino Serial
:
volatile uint8_t sreg;
// Timer 0 interrupt routine
ISR(TIMER0_COMPA_vect, ISR_NAKED)
{
sreg = SREG; /* Save global interrupt flag */
cli(); /* Disable interrupts */
digitalWrite(34, not((bool)digitalRead(34)));
SREG = sreg; /* Restore global interrupt flag */
reti(); // must for ISR: return and enable interrupt
}
void setup() {
pinMode(13, OUTPUT);
pinMode(34, OUTPUT);
Serial.begin(115200);
Serial.println("Hello from setup");
delay(200);
}
void loop() {
digitalWrite(13, HIGH);
Serial.println("Hello from loop: A");
digitalWrite(13, LOW);
delay(200);
digitalWrite(13, HIGH);
#if 1 // register update part
cli(); // disable interrupts
GTCCR = 0b10000011; // halt timers
// set up Timer/Counter 0
TCCR0A = 0b00000010; // CTC; normal mode (don't use output pin)
TCCR0B = 0b00000101; // no force output; CTC; ... and clock select: prescale 1024
TCNT0 = 0; // init the actual counter variable
TIMSK0 = 0b00000010; // enable (only) Compare Match A Interrupt
OCR0A = 125; //the top value, to which the running counter is compared to
GTCCR = 0b00000000;
sei(); // Enable interrupts once registers have been updated
digitalWrite(13, LOW);
delay(200);
#endif
digitalWrite(13, HIGH);
Serial.println("Hello from loop: B");
digitalWrite(13, LOW);
delay(200);
}
Как пример, распечатка через серийный номер будет:
Hello from setup
Hello from loop: A
Hello from loop: B
Hello from loop: A
Hello from loop: B
... и тогда вся обработка прекратится (на что указывает отсутствие действия на выводах 13 и 34 светодиода); Я думаю, это то, что вы бы назвали BSOD в мире чипов :) Внешне остановка происходит, как только запускается процедура ISR в первый раз.
Если вы удалите «часть обновления регистра», то последовательная распечатка будет выполняться вечно, как и ожидалось, а также (как и ожидалось), ISR не работает. Однако, если «часть обновления регистра» оставлена, а две строки «Serial.println(...
» прокомментированы вместо этого - тогда программа печатает только «Hello from setup» - но прерывание действительно выполняется (о чем свидетельствуют импульсы на выводе 34) ,
Что, по-видимому, говорит мне, что вы не можете запустить таймер ISR и UART на ATMega2560 одновременно - что глупо, учитывая, что ранее я с успехом использовал такой же подход на ATMega328.
Итак, я хочу узнать, является ли принципиально невозможным то, что я хочу сделать (иметь последовательную распечатку и импульсы контактов) с этой архитектурой - или я просто что-то упустил в настройке?
Заранее спасибо за любые ответы,
Ура!
(Просто хотел заметить, что этот класс Serial на самом деле работает с определением класса в HardwareSerial.cpp в пакете IDE Arduino; и этот класс определяет процедуры приема прерываний USART; подумал, что это может быть проблемой - но опять же, я использовал тот же подход в ATMega328, где я видел, как это работает ..)
РЕДАКТИРОВАТЬ: Репост на Avr-gcc: прерывания таймера / счетчика конфликтуют с UART? - Arduino Forum