我正在使用ATmega328。我目前正在使用10位ADC进行多次测量。我想将它转换的值存储在变量中,以便能够使用它们进行操作。例如:
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在576
中存储了值ADCH:ADCL
。是否有可能以某种方式实现变量a
以获取相同的值? (即a=576;
)。
答案 0 :(得分:1)
完整的16位结果寄存器should be accessible as such:
a = ADC;
但如果你想手动阅读这两个部分,那么
a = ADCL;
a |= ADCH << 8;
必须在两个单独的语句中完成,以强制ADCH
最后读取。 I / O模块有一个临时寄存器来保存高字节,防止模块本身在更改寄存器值时破坏读取值。 (即,如果ADC完成另一次转换并存储新值。)
如果您有访问ADC的中断(或需要使用a
处的值),您需要在访问期间禁用它们(也适用于a = ADC
因为它也可以编译成多个8位读取。)
答案 1 :(得分:1)
上面的答案很接近,根据芯片制造商的建议,仍然有点短。为安全起见,您应遵循以下链接的权威参考中的说明。
只需关闭之前的中断并在以下之后恢复它们:
unsigned int a; // 16-bit word
// other code
cli();
a = ADCL;
a |= ADCH << 8;
sei();
来自芯片制造商的此参考中的每个示例都遵循此模式进行原子16位读写。参考:AVR Application Note 072。