2017-01-02 60 views
1

我一直在使用Arduino並遇到了一個非常奇怪的問題。這裏是我使用的代碼:Arduino問題:使用TimerOne和delayMicroseconds()

#include <TimerOne.h> 

const int LED_PIN = 8; 

const int PERIOD = 3000; // micros 

void setup() 
{ 
    pinMode(LED_PIN, OUTPUT); 

    Timer1.initialize(PERIOD); 
    Timer1.attachInterrupt(sendPulse); 

    Serial.begin(115200); 
} 

void loop() 
{ 

} 

void sendPulse() 
{ 
    Serial.println(micros()); 
    delayMicroseconds(x); 
    Serial.println(); 
} 

所以,我試圖改變x的sendPulse()的值。例如,如果x爲300,則串行監視器按預期輸出「3016 6016 9016 ...」。然而,當x大於或等於835時會出現奇怪的現象 - 串行監視器輸出「3016 4992 7992 ....」我的問題是爲什麼第一個和第二個中斷之間的時間不是3000?此外,如果我的中斷中修改代碼:

Serial.println(micros()); 
    delayMicroseconds(x); 
    digitalWrite(LED_PIN, HIGH); 
    Serial.println(); 

代碼奇怪的行爲對於x大於或等於830,而不是835。爲什麼會出現這種情況?謝謝!

+4

如果不知道arduino庫是如何實現引擎蓋下的東西的話,我們無法確定。但是你不應該在中斷服務程序中延遲或運行一個大的工作。設置一些標誌並儘快返回。否則,新的中斷事件可能會丟失,因爲AVR中的中斷不能產生中斷,導致事情混亂。添加'數字寫入'調用降低最大延遲時間的事實似乎與這種觀點一致。 – Unimportant

回答

0

根據this

  1. 你不應該在中斷服務程序使用Serial.print()/Serial.read(),因爲Serial最新版本使用中斷讀寫但他們被禁止從內部ISR

  2. ,你不應該使用delay()/delayMicroseconds(),因爲他們再次利用中斷但它們將被禁止從ISR ..你的風險使得定時器錯過一些中斷和適度寬鬆的軌道內正確時間流程


這樣的話我在這裏重複了什麼在評論中說,通過@Unimportant:的ISR中的代碼應儘可能短,儘可能快。