我有一些代码应该在换向器环路周围每次读取几个ADC引脚的值。
static uint16_t adc0;
static uint16_t adc1;
void init(void) {
...
hw_configure_adcs();
...
}
void loop(void) {
...
adc0 = hw_read_adc(0);
adc1 = hw_read_adc(1);
...
}
void hw_configure_adcs(void) {
ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS0);
}
uint16_t hw_read_adc(uint8_t n) {
ADMUX = (1<<REFS0) | (n & 0x07);
ADCSRA |= (1<<ADSC); // start conversion
uint16_t count;
for (count = 0; !(ADCSRA & (1<<ADIF)); count++); // wait for conversion to complete
// ADCSRA |= (1<<ADIF); // tried with and without this
return (ADCH << 8) | ADCL; // return ADC value
}
我看到的是奇怪的:adc0和adc1的值设置为相同的值,并且从不更改,直到重新启动/刷新AVR芯片。
(在0.71V时值为0x00d1,在1.00V时值为0x0128,这似乎是合理的。)
我试过了:
count
返回hw_read_adc()
而不是ADC值:这将返回0x34和0x38之间变化的数字,这对于两个ADC来说是不同的,并且随时间连续变化。 从这些测试中,我推断正在读取ADC,但是我缺少一些“清除ADCH和ADCL,并使它们准备好接受新的读取”步骤。
我已经重读了http://www.atmel.com/images/Atmel-8272-8-bit-AVR-microcontroller-ATmega164A_PA-324A_PA-644A_PA-1284_P_datasheet.pdf的第23节,但显然忽略了一些重要的内容。
最佳答案
经过大量的谷歌搜索,我发现:http://www.avrfreaks.net/forum/adc-only-happens-once-reset
问题在于return (ADCH << 8) | ADCL;
已编译,因此它首先读取了高位寄存器(正如您可能期望的那样)。
数据表的第252页说:“否则,必须先阅读ADCL,然后再阅读ADCH”。
将我的代码更改为return ADC
可以解决此问题。
我对发生的事情的猜测是:
关于c - ADC在ATMEGA324PA上仅工作一次,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40653325/