Код АЦП ATmega16 не работает

#define F_CPU 1000000UL
#include <avr/io.h>

volatile uint8_t adcvalue;


int main(void)
{
    DDRA =0x00;
    DDRC = 0xff;

// enable adc
    ADCSRA |= (1<<ADEN);
// using division factor 8
    ADCSRA |= (1<<ADPS0) | (1<<ADPS1);

// enable 8 bit conversion
    ADMUX |= (1<<ADLAR);
// take input from PA0
    ADMUX |= (1<<MUX0);

    while (1)
    {
        // Start conversion
        ADCSRA |= (1<<ADSC);

        // wait until conversion is done
        while (ADCSRA & (1<<ADSC));

        // save result to adcvalue
        adcvalue = ADCH;

        // show result on 8 leds connected to PORT C
        PORTC = adcvalue;       
    }
    return 0;
}

Приведенный выше код должен принимать аналоговое значение от PA0 (с помощью потенциометра) и отображать цифровое значение на 8 светодиодах, подключенных к PORT C. Когда я моделирую схему на Proteus, светодиоды всегда горят, даже когда я изменяю значение потенциометра, и появляется сообщение о том, что «[AVR AD CONVERTER] Эталонное значение = 0».

Благодарю, если вы можете помочь мне узнать, что не так.


person user247954    schedule 21.12.2016    source источник
comment
Какое у вас опорное напряжение? Какова ценность Поти? Какое значение вы ожидаете? Вы измеряли напряжение на PA0? Оно ниже вашего эталонного напряжения? Пожалуйста, приложите некоторые усилия и дайте хотя бы базовую информацию.   -  person Rev    schedule 22.12.2016


Ответы (3)


// take input from PA0
    ADMUX |= (1<<MUX0);

Это неправильно, в этой строке вы принимаете PA1/ADC1 в качестве входных данных, а не PA0/ADC0.

Ознакомьтесь со спецификацией на странице 218: http://www.atmel.com/images/doc2466.pdf

MUX 4..0 00000 — это PA0, а 00001 — это PA1

Вы устанавливаете значение MUX 4..0 на 00001 с помощью

ADMUX |= (1<<MUX0);

и, следовательно, используя PA1 в качестве источника.

Ваше здоровье

person Hetti    schedule 21.12.2016
comment
Спасибо. Я исправил это, но все равно такое же поведение - person user247954; 22.12.2016
comment
Я не вижу разницы в инициализации, которую вы предлагаете. Правильным было бы неявно очистить MUX4..0, чтобы убедиться, что выбран PA0. - person Rev; 22.12.2016
comment
Забудьте об этом, я думал, вы предложили изменить его на вторую кодовую цитату. - person Rev; 22.12.2016

Чтобы удалить сообщение об ошибке [AVR AD CONVERTER]Reference Value = 0 из proteus, вы должны удалить следующие две строки в исходном коде:

// enable 8 bit conversion
ADMUX |= (1<<ADLAR);
// take input from PA0
ADMUX |= (1<<MUX0);

и добавьте эту строку вместо

 ADMUX = 0b01100000;

Кроме того, не забудьте подключить 5 Вольт Vcc к контакту AVcc.

диаграмма

person Rabia Yousuf Ansari    schedule 28.01.2017

У меня сейчас нет даташита, поэтому напишу в общем виде. на AVR некоторые регистры разделяют некоторые конфигурации. В вашем случае ADMUX разделяет MUX и 8-битное преобразование.

Ваша инструкция:

ADMUX |= (1<<MUX0);

устанавливает бит в позиции MUX0 в высокий уровень, а затем он записывается в или в регистр. Это означает, что если MUX1, MUX2, MUXN были высокими до того, как они будут высокими после вашей команды.

Безопасной инициализацией будет:

ADMUX &= ~(_BV(MUX0)|_BV(MUX1)|_BV(MUXN)
ADMUX |= (1<<MUX0);

Регистр ADMUX по памяти имеет все биты, установленные в 0, как первый вывод АЦП. поэтому в вашем случае первая инструкция:

ADMUX &= ~(_BV(MUX0)|_BV(MUX1)|_BV(MUXN)

является единственным необходимым.

person andyinno    schedule 28.12.2016