gpt4 book ai didi

c - ADC 仅在 ATMEGA324PA 上工作一次

转载 作者:太空宇宙 更新时间:2023-11-03 23:43:03 26 4
gpt4 key购买 nike

我有一些代码应该读取几个 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,似乎合理。)

我试过:

  • 降低电压:adc0 和 adc1 保持不变,仅在重新刷新 AVR 代码(并因此重启芯片)时才降低。
  • 调高电压:adc0 和 adc1 保持不变,只有在重新刷新 AVR 代码(并因此重启芯片)时才会升高。
  • hw_read_adc() 返回 count 而不是 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解决了问题。

我对发生的事情的猜测是:

  • 发生了从 ADCH 的读取。
  • 从 ADCL 读取具有锁定 ADC 结果的作用,以防止撕裂。
  • 下一个 ADC 读取无处写入其结果,因为 ADC 结果已锁定。
  • 重复...

关于c - ADC 仅在 ATMEGA324PA 上工作一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40653325/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com