2017-06-10 24 views
-1

私はATmega328を使用しています。私は現在、10ビットADCを使用していくつかの測定を行っています。私はそれを操作できるように、変換する値を変数に保存したいと思います。例えば:C言語のAVR - 変数にレジスタの値を格納

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:ADCLの値576に格納されたとします。どういうわけか、変数aを同じ値にすることは可能ですか? (すなわち、a=576;)。

答えて

1

フル16ビットshould be accessible as such結果レジスタ:

a = ADC; 

しかし、あなたは手動で両方の部分を読みたい場合は、その後、

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

ADCHを強制するために、2つの別々のステートメントで行う必要があります最後に読まれる。 I/Oモジュールには、上位バイトを保持するための一時レジスタがあり、レジスタの値が変更された場合、モジュール自体が読み出し値を破壊するのを防ぎます。 (つまり、ADCが別の変換を完了して新しい値を格納した場合)

ADCにアクセスする割り込みがある場合アクセス(それはa = ADCにも行きます、それは複数の8ビット読み込みにもコンパイルされるからです)。

+0

これは破損する可能性があります。次の回答を参照してください。 – TomServo

+0

@JLH、point。アプリケーションノートのテキストは、「割り込み関数が同じリソースにアクセスする場合は、アクセスはアトミック操作にする必要があります」ということに注意してください。 ADCにアクセスする割り込みがない場合は問題ありません。 – ilkkachu

+0

OPのコードから、このADCが格納されている間に別のADCが起動するかどうかは分かりません。転ばぬ先の杖。 – TomServo

1

上記の答えは近いですが、まだチップメーカーの推奨に基づいて少し短くなります。安全のために、以下にリンクされている権威ある参考文献の指示に従ってください。

単に直前に割り込みをオフにした後、それらを復元:チップメーカーからこの参照

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

すべての例では、16ビットの読み取りと書き込みをアトミックため、このパターンに従います。参考:AVR Application Note 072

+0

*もう1つのADC測定*は起こりません。「ADCL」を読み込むと、ADRも読み取るまで、AVRはADCからの変化に対してADCレジスタをロックします。マニュアルを参照してください。なぜ割り込みサービスルーチンが 'a'値を壊すことができるのでしょうか?ただし、半更新された 'a'値を*使用するようにはしないでください。 – tofro

+0

@tofro OPのコードの**すべて**を見なければ、何が起こっているのか分からない。私はAVR072の指示に従って間違ったことは決してありませんでした。 – TomServo

関連する問題