C中的AVR - 在变量中存储寄存器的值

时间:2017-06-10 18:30:01

标签: c avr atmega adc

我正在使用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;)。

2 个答案:

答案 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