2017-06-10 68 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