2017-02-22 200 views
1

我在麪包板上製作了一個帶有Arduino Uno和電阻器梯形圖的基本波形發生器。我使用loop函數和micros()根據需要更改電壓電平以在每個電壓變化之間延遲。這不是完美的,但它與壓電效果很好。analogRead需要太多時間

我的問題是我在我的代碼中設置信號頻率,我希望能夠使用一個鍋例如更改它。但只要我在我的代碼中放置analogRead(所有代碼都在loop()函數中),輸出信號就會改變。我發現了analogRead功能可能需要長達100μs的運行,這是比每個電壓變化,因此實際信號週期之間的延遲時,不正確的是:

unsigned long now, next; 
int freq; 

void loop(){ 

    //if I put analogRead() here it takes to much time 

    now = micros(); 

    if(now >= next){ 
     //Here I change the output analog value using a R-2R ladder 
     //then I change the value of next 
    } 
} 

我嘗試了一些解決方案,包括使用開關代替的一壺,但digitalRead加上if語句似乎並不更有效。我也嘗試過帶有中斷的開關,但結果與digitalRead相同。

有人知道另一種解決方案嗎?

謝謝!

+0

請您提供您的*基於中斷的嘗試的描述*?在我看來,將輸出處理從* loop()*轉換爲*中斷服務程序*應該是一種可行的方法..這應該允許您在不改變信號的情況下使用'analogRead()',優先感謝處理*中斷* ..或者我錯了嗎? –

回答

2

analogRead一直等到轉換完成,所以如果你想做別的事情,你必須以不同的方式處理它。

您可以使用ADC中斷和自由運行模式。或者,您可以通過多種來源(如定時器比較)觸發ADC轉換週期。

或者你可以通過基於「事件」的方法來完成 - 通過檢查ADC轉換完成並通過向該標誌寫入邏輯1來重置它。

// in setup: 
ADCSRA |= _BV(ADATE); // enable auto trigger mode 
ADCSRB = 0; // free running mode for the auto trigger 

// and in the loop: 
if (ADCSRA & _BV(ADIF)) { 
    value = ADC; // get ADC value 
    ADCSRA |= _BV(ADIF); // reset flag by writing logic one into it 
    // whatever you want with the current value 
    // or ADCSRA |= _BV(ADSC); // start another conversion if you don't want free running mode 
} 

BTW:宏_BV(BIT)被替換到1<<(BIT)(如果你想知道爲什麼我使用它)

+0

謝謝你的回答!我會測試它,但我想它比Arduino的analogRead花費的時間要少 – 695nb