我是这个领域的初学者。我的目标是根据电位计更改8个LED(连接到PORTA)的输出。我已将电位计的中线连接到PF0,即ADC0。我还将另外两条线连接到5V和地。

我知道芯片或连接没有问题,因为LED正常工作。

但是,无论我如何更改下面的代码(通过更改ADMUX和ADCSRA寄存器来表示更改的意思),都不会显示输出!

我正在使用带有16MHZ时钟的atmega128。以下是我要解决的代码。

#include <asf.h>
#include <avr/io.h>
#define F_CPU 16000000L

int init_board(void)
{
  DDRA=0xff;
  PORTA=0x01;
}

int ADC_init(void)
{
  //ADCSRA
  ADCSRA = 0b10000111;
  //ADMUX
  ADMUX = 0b01100000; // middle line connected to ADC0
}

int main (void)
{
  init_board();
  ADC_init();

  ADCSRA |= (ADSC >> 1);
  while(1)
  {
    if(ADSC == 0)
    {
      uint8_t disp_value = ADCL;
      PORTA = disp_value;
      delay_ms(200);
      ADCSRA |= (ADSC >> 1);
    }
  }
}


我不知道为什么代码不起作用。

我想是因为它没有正确设置我的寄存器,但是我遵循了atmega128数据表上的所有说明。

最佳答案

第一个问题是您的移位,应该为ADCSRA |= (1 << ADSC)

下一个问题是结果阅读。您将ADMUX的第五位设置为1,因此ADLAR = 1,并且在该模式下,对结果进行了调整,因此您应该读取ADCH。

此外,当您切换到10位分辨率时,即开始处理多字节结果时,请注意仅读取ADCL是不够的,请参见数据表23.3进行解释:“一旦读取ADCL,就会阻止ADC对数据寄存器的访问。这意味着,如果已经读取ADCL,并且在读取ADCH之前完成转换,则不会更新任何寄存器,并且转换结果将丢失。读取ADCH时,将重新启用对ADCH和ADCL寄存器的ADC访问。”

最后,使用硬编码的延迟进行读取不是一种好习惯,尤其是当您稍后更改代码以尽可能快地读取ADC时。在这种情况下,转换开始后,您应该检查是否设置了ADIF标志或在设置ADEN时与Interrup进行了反应。有关详细信息,请参见数据表。

10-01 15:35