Avr gcc:计时器/计数器中断与UART冲突? 请考虑以下示例(在ARDUNO IDE 0022、Ubuntu 11.04、ARDUIO ATMEGA 2560上尝试),在这里我尝试启动计时器/计数器中断,同时使用ARDUINO 系列< /代码>类: 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); }

Avr gcc:计时器/计数器中断与UART冲突? 请考虑以下示例(在ARDUNO IDE 0022、Ubuntu 11.04、ARDUIO ATMEGA 2560上尝试),在这里我尝试启动计时器/计数器中断,同时使用ARDUINO 系列< /代码>类: 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); },timer,interrupt-handling,avr-gcc,uart,Timer,Interrupt Handling,Avr Gcc,Uart,如示例所示,通过串行方式打印的输出将为: Hello from setup Hello from loop: A Hello from loop: B Hello from loop: A Hello from loop: B 。。。然后,所有处理将停止(LED引脚13和34上均未动作表示);我猜,这就是你在芯片世界中所说的BSOD:)表面上看,只要ISR例程第一次启动,就会停止 如果取出“寄存器更新部分”,则串行打印输出将永远运行,正如预期的那样,并且(如预期的那样)没有ISR运行。但是,如

如示例所示,通过串行方式打印的输出将为:

Hello from setup
Hello from loop: A
Hello from loop: B
Hello from loop: A
Hello from loop: B
。。。然后,所有处理将停止(LED引脚13和34上均未动作表示);我猜,这就是你在芯片世界中所说的BSOD:)表面上看,只要ISR例程第一次启动,就会停止

如果取出“寄存器更新部分”,则串行打印输出将永远运行,正如预期的那样,并且(如预期的那样)没有ISR运行。但是,如果“寄存器更新部分”被保留,而两行“
Serial.println(…
”行被注释,则程序只打印“Hello from setup”-但中断确实运行(由引脚34上的脉冲证明)

这似乎告诉我,你不能在ATMega2560上同时运行定时器ISR和UART-这很愚蠢,因为我以前在ATMega328上成功地使用过同样的方法

所以,我想知道我想做的事情(串行打印输出和引脚脉冲)在这种架构下根本不可能实现,还是我只是在设置中遗漏了什么

提前感谢您的回答, 干杯

(我只是想指出,这个串行类实际上是在Arduino IDE包的HardwareSerial.cpp中的类定义上运行的;这个类定义了接收USART中断例程;虽然这可能是问题所在,但我在ATMega328中使用了相同的方法,在那里我看到了它的工作原理。)


编辑:重新发布在

好的,我刚刚在ATMega168和ATMega328上重新运行了相同的代码-它的工作原理与预期一样(带有串行写入的主循环和ISR例程都在运行);因此这一定是ATMEGA2560特定的问题-而不是一般编程的问题

编辑:简短的回答是-使用不同的计时器,因为计时器0已经被ArduinoAPI使用

(更多信息,请参阅Arduino论坛上的报道)


干杯!

好的,我刚刚在ATMega168和ATMega328上重新运行了相同的代码-它的工作原理与预期一样(串行写入的主循环和ISR例程都在运行);因此这一定是ATMEGA2560特定的问题-而不是一般编程的问题

编辑:简短的回答是-使用不同的计时器,因为计时器0已经被ArduinoAPI使用

(更多信息,请参阅Arduino论坛上的报道)

干杯