2014-09-22 95 views
1

我試圖讀取ATMega128開發板上兩個模擬紅外傳感器的值,然後通過PWM輸出縮放表示。當我將兩個PWM波連接到示波器時,它們保持相同,不應該如此。我的PWM代碼很好,所以我認爲問題在於我的代碼從ADC的通道0和1讀取。從ATMEGA128上的多個ADC通道讀取

int sens1,sens2,sens3; 
volatile const uint8_t adc1 = (1<<ADLAR) | (0<<MUX0)|(0<<MUX1); 
volatile const uint8_t adc2 = (1<<ADLAR) | (1<<MUX0)|(0<<MUX1); 

void main(void) 
{ 


ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); 
ADMUX |= (1 << REFS0); // Set ADC reference to AVCC 
ADMUX |= (1 << ADLAR); // Left adjust ADC result to allow easy 8 bit reading 
ADCSRA |= (1 << ADFR); // Set ADC to Free-Running Mode 
ADCSRA |= (1 << ADEN); // Enable ADC 
ADCSRA |= (1 << ADIE); // Enable ADC Interrupt 
sei(); // Enable Global Interrupts 
ADCSRA |= (1 << ADSC); // Start A2D Conversions 

while (1) 
{ 
} 
} 

ISR(ADC_vect) 
{ 

static uint8_t firstTime = 1; 
static uint8_t val; 

val = ADCH*100; 

if (firstTime == 1){ 
firstTime = 0; 
} 
else if (ADMUX == adc1) 
{ 
    ADMUX = adc2; 
    OCR3A = val; 
} 

else if (ADMUX == adc2) 
{ 
    ADMUX = adc1; 
    OCR1C = val; 
} 
} 
+0

代碼看起來很好看。我將驗證每個ADC通道是否給出了預期的結果,而無需在通道之間進行切換以縮小範圍。 – 2014-09-22 11:18:17

+0

每個通道都會給出預期結果 – user27365 2014-09-22 12:24:12

回答

0

我想你應該在輸入頻道改變後將firstTime設置爲1。 請參閱數據表這樣的:

當改變通道選擇,用戶應遵守以下 準則,以確保選擇正確的通道:

[...] 在自由運行模式,始終選擇 開始第一次轉換之前的通道。寫入ADSC後,通道選擇可能會在一個ADC時鐘週期更改爲 。但是,最簡單的 方法是等待第一次轉換完成,然後 更改通道選擇。由於下一次轉換已經自動開始 ,因此下一個結果將反映先前的 通道選擇。後續轉換將反映新的頻道 選擇。

但爲什麼要使用自由運行模式呢?你想要一箇中斷。所以你可以選擇源和觸發測量並等待中斷。然後手動開始下一個測量。

另一件提醒我的是uint8_t結果乘以100. 您確定這不會溢出?
我們的ADC通道的輸入電壓範圍是多少?

另一個原因可能是採樣頻率。你選擇了一個非常高的預分頻器。 ADC需要至少50kHz的時鐘。所以你的AVR應該運行在> 6Mhz。檢查您的保險絲設置是否設置爲使用外部時鐘源。還有一件事。熔絲位的文檔比特表示AtMega103兼容模式默認情況下處於活動狀態。你可能會參考報表,也許這也會影響你的問題。