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

AVR in C - Storing value of register in variable

我正在使用 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在ADCH:ADCL中存储了值576。是否有可能以某种方式实现变量 a 取相同的值? (即 a=576;)。

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

a = ADC;

但是如果你想手动阅读这两部分,那么

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

这必须在两个单独的语句中完成,以强制最后读取 ADCH。 I/O 模块有一个临时寄存器来保存高字节,防止模块本身在更改寄存器值时破坏读取值。 (即如果 ADC 完成另一次转换并存储新值。)

如果您有访问 ADC 的中断(或需要使用 a 处的值),则需要在访问期间禁用它们(这也适用于 a = ADC, 因为它也编译成多个 8 位读取)。

上面的答案很接近,根据芯片厂商的建议还是有点短。为了安全起见,您应该按照下面链接的权威参考中的说明进行操作。

只需在之前关闭中断并在之后恢复它们:

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

此参考文献中的每个示例 来自芯片制造商 都遵循此模式进行原子 16 位读写。参考:AVR Application Note 072.