2017-06-10 82 views
-1

我正在使用ATmega328。我目前正在使用10位ADC進行多次測量。我想存儲它在變量中轉換的值,以便能夠與它們一起操作。例如:AVR在C - 存儲變量中的寄存器值

int a; 
(...) 
ADMUX = 0b01000011; //Vref = 5V, ADC3 
ADCSRA |= (1<<ADSC); //Starts conversion 
while(!(ADCSRA & (1<<ADIF))); //Wait until it finishes 
ADCSRA |= (1<<ADIF); //Clear flag 

假設ADC存儲在ADCH:ADCL576。在某種程度上,是否有可能實現變量a以獲得相同的值? (即a=576;)。

回答

1

完整的16位結果寄存器should be accessible as such

a = ADC; 

但是,如果你想手動閱讀兩部分,然後

a = ADCL; 
a |= ADCH << 8; 

已在兩個單獨的語句來進行強制ADCH最後讀。 I/O模塊有一個臨時寄存器來保存高字節,防止模塊本身在更改寄存器值時破壞讀取值。 (即如果ADC完成另一次轉換並存儲新值)。

如果您有訪問ADC的中斷(或需要使用a處的值),則需要在訪問(這也適用於a = ADC,因爲它也編譯成多個8位讀取)。

+0

這容易腐敗。見下面的答案。 – TomServo

+0

@JLH,指向。儘管請注意應用筆記中的文字是「如果中斷函數訪問相同的資源,則訪問必須進行原子操作」。如果沒有訪問ADC的中斷,則沒有問題。 – ilkkachu

+0

從OP的代碼中可以看出,當這個存儲器被存儲時,是否有其他ADC可以啓動。比對不起更安全。 – TomServo

1

上面的答案很接近,根據芯片製造商的建議,仍然有點短。爲了安全起見,您應該按照下面鏈接的權威性參考中的說明進行操作。

之前簡單地關閉中斷和後恢復它們:

unsigned int a; // 16-bit word 
// other code 
cli(); 
a = ADCL; 
a |= ADCH << 8; 
sei(); 

每個實例在該參考文獻從芯片製造商遵循該圖案用於原子16位讀取和寫入。參考:AVR Application Note 072

+0

*另一個ADC測量值*不會發生 - 一旦讀取了「ADCL」,AVR就會鎖定ADC寄存器以應對ADC的變化,直到您還讀取了ADCH。見手冊。爲什麼一箇中斷服務程序應該能夠破壞'a'值,除非它現在寫入它逃脫我。但是,它不應該嘗試*使用半更新的'a'值。 – tofro

+0

@tofro到目前爲止已經足夠了,但除非我們看到OP的所有**代碼,否則我們無法知道還會發生什麼。按照AVR072中的說明,我從來沒有出錯過。 – TomServo