![](/img/trans.png)
[英]Arduino (AVR ATMega328) Timer1 does not seem to trigger at the right time
[英]Arduino Uno Timer1 seemingly starts itself
時(忙); 循環立即被跳過。 但唯一可以將 busy 設置為 0 的地方是在 Timer1 ISR 中。 但是定時器 1 停止並且僅在處於引腳變化 ISR 時才啟動。
從 UART 輸出我可以看出 Timer 1 ISR 發生了,而 Pin Change ISR 永遠不會發生。 這是不可能的,對吧?
我錯過了什么?
在我的主要功能中:
...
uint32_t temp = 0;
busy = 1;
mode = 1;
// Timer Interrupt Init
TCCR1B &= ~((1<<2) | (1<<1) | (1<<0)); // Makeing sure timer is not running
TIMSK1 |= (1 << TOIE1); // Timer 1 overflow interrupt enable
TCNT1 = 0; // Makeing sure Timer is on 0
// Pin Change Interrupt Init
PCICR |= (1<<2); // Activating PCMSK2
PCMSK2 |= (1<<6); // PCMSK2 -> PCINT23.. 16 seem to correspond to physical pins D 0-7
UartSendstring("1");
// Scanning (see ISR)
sei();
TCCR1B &= ~((1<<2) | (1<<1) | (1<<0));
while(busy);
cli();
...
定時器 1 中斷服務程序:
ISR(TIMER1_OVF_vect)
{
UartSendstring("3");
busy = 0;
}
引腳更改 ISR:
ISR(PCINT2_vect)
{
UartSendstring("2");
//todo make first values not empty
TCCR1B &= ~((1<<2) | (1<<1) | (1<<0));// CS12 - CS10 are set to 0 to stop the timer
data[addr] |= TCNT1L;
data[addr] |= (TCNT1H << 8); // High and low byte are saved to data
TCNT1 = 0; // Timer is reset
TCCR1B |= ((1<<1) | (1<<0)); // CS12 is set to 1 to restart the timer with prescaler 64 -> tick time = 4us
// Signal period duration is 1s / 38 000 = 26us
// -> at least on timer tick in one signal period
addr++; // Prepares to write to the next address with next edge
}
Uart輸出為:
13
編輯
我嘗試移動TIMSK1 |= (1 << TOIE1);
到引腳更改 ISR。 現在它至少像我想要的那樣進入那里一次,但是一旦我啟用中斷,它就會再次觸發 ISR 並結束。
由於 Arduino 內核默認啟動所有定時器(由於 PWM),有可能中斷標志已經設置,並且一旦您啟用相應的中斷,它們就會觸發。 因此,您必須在重新啟用中斷之前清除它們。 但是有一個小小的障礙:通過將邏輯 1 寫入相應位來清除中斷標志。 因此你必須使用這樣的東西TIFR1 = _BV(ICF1) | _BV(OCF1B) | _BV(OCF1A) | _BV(TOV1);
TIFR1 = _BV(ICF1) | _BV(OCF1B) | _BV(OCF1A) | _BV(TOV1);
(但是由於您不使用任何其他 Timer1 中斷,您只能清除 TOV1 標志)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.