代码之家  ›  专栏  ›  技术社区  ›  Nicholas Lee

atmega128中电位器adc的实践

adc c
  •  0
  • Nicholas Lee  · 技术社区  · 7 年前

    我是这个领域的初学者。我的目标是根据电位计改变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数据表上的所有说明。

    1 回复  |  直到 7 年前
        1
  •  0
  •   andy    7 年前

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

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

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

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