[英]16-bit timer in AVR CTC mode
我正在嘗試使用Arduino Uno開發板( ATmega328,16 MHz)實現這一目標。 因此,我在Internet上進行搜索,然后想到了以下內容:
unsigned long Time=0;
int main (void)
{
Serial.begin(9600);
cli();
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
OCR1A = 15999; // Compare value
TCCR1B |= (1 << WGM12)| (1 << CS10); // Prescaler
TIMSK1 |= (1 << OCIE1A); // Enable timer compare interrupt
sei();
while(1) {
Serial.println(TCNT1);
}
return 0;
}
ISR(TIMER1_COMPA_vect)
{
Time++;
Serial.println(Time);
}
我正在嘗試達到1 kHz的頻率,因此我將能夠創建幾毫秒長的間隔。
這就是為什么我將比較值選擇為15999(即16000-1),並將預分頻器選擇為1的原因,所以我得到了(至少我認為是正確的計算結果):
Frequency = 16.000.000 MHz/16000 = 1000 Hz = 1 kHz
現在的問題是,即使Serial.println(TCNT1)
向我顯示的數字最多計數為16000,回零,最多16000,返回零,..., Serial.println(Time)
最多計數為8 ,盡管TCNT1仍在計數,但它只是停止計數。
我想到某處有某種溢出,但我想不到哪里。 我唯一想到的是比較值可能太大了-正如我認為-顯然不是這樣,因為2^16 -1=65.535>15999
。
例如,如果我將預分頻器設為64,並保留比較值,則Time
按預期計數。 所以我想知道:為什么ISR()
停止以值8調用,而在調高預分頻器時起作用?
我不確定,但是根據您使用的Arduino版本,println調用將被阻塞。 如果調用它的速度超出了在ISR中完成的速度,則堆棧將溢出。
如果您想要更高分辨率的計時,則可以嘗試在Loop()
對getMicroseconds結果進行差分。 您在Loop()
中Loop()
速度應遠遠超過每毫秒一次。
如果要每毫秒執行一次操作,請捕獲一個開始的微秒,然后在Loop()
函數的條件中從當前的微秒中減去它。 當您看到1000多個任務時...
對於我的Arduino Uno(16 MHz)而言,計時器的分辨率似乎過高。 選擇較低的分辨率(即較高的比較值)可以解決我的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.