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.
我正在使用 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.