Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Atmega8: АЦП мереет то чего нет.
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Spider
Имеем AtMega8 с подключеными на ADC0,ADC1,ADC2 сигналами.
Но измерения мягко говоря странные. ADC0 и ADC2 "близки к нолю", т.е. по сути там делитель "вход" которого "висит" в воздухе. На ADC1 есть напряжение около 3х вольт.
Результат измерения получается 4, 805, 800 (ну +-3 от раза к разу). Ну 4 ладно, это 0,018 вольта, 805 тоже понимаю это где-то 3.8В, но от куда 800? Стою осцилографом на этой шожке и ничего не вижу, а измерение есть...
В коде измеряем значения следующим образом:
Код
#include <avr/io.h>
#define AD_CNT        3
#define AD_CLC        5
volatile uint16_t    ADBuf[AD_CNT][AD_CLC];
volatile uint16_t    ADSum[AD_CNT];
volatile uint8_t    src=0,ad_calc=0;

void init_adc(void) {
    uint8_t i,j;
    for (i=0;i<AD_CNT;i++) {
        for (j=0;j<AD_CLC;j++)
            ADBuf[i][j] = 0;
        ADSum[i] = 0;
    }
    ADCH = 0;
    ADCL = 0;
    ADMUX = _BV(REFS0);
    ADCSRA = _BV(ADEN) | _BV(ADPS2) | _BV(ADPS1) | _BV(ADSC);
}

int main(void) {
    PORTC = 0;
    DDRC = 0;

    ....

    init_adc();

    ....

    while(1) {        
        if (bit_is_clear(ADCSRA,ADSC)) {
            uint16_t ADres=ADC;
          

            ADSum[src] -= ADBuf[src][ad_calc];
            ADBuf[src][ad_calc] = ADres;        // Place new value into Buffer
            ADSum[src] += ADres;

            ad_calc++;
            ad_calc%=AD_CLC;
            if (!ad_calc) {
                src++;
                src%=AD_CNT;
                ADMUX = _BV(REFS0) | src;            
            }
            ADCSRA |= _BV(ADSC);
        }
        ....
    }
}
bzx
на AREF ёмкость стоит?
Spider
Цитата(bzx @ Apr 29 2008, 12:40) *
на AREF ёмкость стоит?

Да, конечно. 1uF керамика.
Dog Pawlowa
Цитата(Alexey Belyaev @ Apr 29 2008, 11:11) *

Попробуйте мой код, в чужом разбираться лень smile.gif
Сервис вставьте в цикл, на а инициализацию - в старт-ап.

Код
#define adcExtPow   6
#define adcEnter    5
#define adcUp       4
#define adcDn       3
#define adcEsc      2

#define ADCoff      ADCSR=0


unsigned int adc_values[7];
unsigned char adc_channel;
unsigned char adc_ready=0;


void InternalAdcInit(void)
{
  ADCSRA =
    (1 << ADEN) |  //ADC ON,
  //     ADSC     not start conversion
  //    ADATE     auto trigger disable
    (1 << ADIF) |  // clear conversion flag writing 1 to it
  //    ADIE     interrupt disable
    (1 << ADPS2) |   //prescaler =64 (ADPS2=1, ADPS1=1, ADPS0=0)
    (1 << ADPS1) |
  //    ADPS0
    0;

  ADMUX = //REFS1 |
    (1 << REFS0) |  // REFerence = AVCC with C on pin Vref (REFS1=0, REFS0=1)
//    (1 << ADLAR) |  // left adjust results - read high byte only
    0;
}


#define SetAdcChannel(mux) ADMUX = (0xE0 & ADMUX) | (mux)
#define StartAdcConversion() ADCSRA |= (1 << ADIF) | (1 << ADSC)
#define AdcConversionComplete (!(ADCSRA & (1 << ADSC)))

void InternalAdcService(void)
{
  static char adc_status;
    char my_adcl;

  switch (adc_status)
  {
  case 0:
    InternalAdcInit();
    SetAdcChannel(adc_channel = 0);
    StartAdcConversion();
    adc_status = 1;
    break;
  case 1:
    if (AdcConversionComplete)
    {    my_adcl=ADCL;
      adc_values[adc_channel] = (ADCH<<8) + my_adcl;
      if (++adc_channel >= COUNT_ELEMENTS(adc_values))
      {
        adc_channel = 0;
        adc_ready = 1;
      }
      SetAdcChannel(adc_channel);
      StartAdcConversion();
    }
    break;
  default:
    adc_status = 0;
  }
}

Ой, забыл, у меня Mega32. Даже не знаю, есть ли отличия.
bloodden
Подтяжка висит. И ещё: там с фузами есть нюанс, только непомню какой и или в м8 или м16.
Tolyaha
А на AVcc питание подано?
Spider
Цитата(Tolyaha @ Apr 29 2008, 18:14) *
А на AVcc питание подано?

Конечно!

Цитата(bloodden @ Apr 29 2008, 18:08) *
Подтяжка висит. И ещё: там с фузами есть нюанс, только непомню какой и или в м8 или м16.

Эм.. А подтяжка не к земле ли? или речь о внутренней? Так ведь DDRC=0
Фьюзов связанных с ACP не обнаружил.
Tolyaha
А если тот канал, где 3 V весит (ADC1) закоротить, на ADC2 пропадет???
попробуйте накоротко на общий позакорачивать, может у вас слишком вывокоомная схема (или нога ADC2 в воздухе висит, тогда если после ADC1 сразу мерять ADC2, то емкость коммутатора не успеет разрядиться и вы померяете слегка разрядившееся напряжение от ADC1)
Spider
Цитата(Tolyaha @ Apr 30 2008, 13:37) *
А если тот канал, где 3 V весит (ADC1) закоротить, на ADC2 пропадет???
попробуйте накоротко на общий позакорачивать, может у вас слишком вывокоомная схема (или нога ADC2 в воздухе висит, тогда если после ADC1 сразу мерять ADC2, то емкость коммутатора не успеет разрядиться и вы померяете слегка разрядившееся напряжение от ADC1)

Близко к тому. А как быть? smile.gif
bloodden
Цитата(Alexey Belyaev @ Apr 30 2008, 09:05) *
Конечно!
Эм.. А подтяжка не к земле ли? или речь о внутренней? Так ведь DDRC=0
Фьюзов связанных с ACP не обнаружил.

DDRC=0 - означает что выводы будем юзать входами. А если при этом PORTC=0xFF, то на входах включаются подтяжки к VCC. Я замечал, что если пару входов использовать в качестве входов АЦП и при этом из ТОГО ЖЕ порта использовать выходы, то состояние этих выходов влияет на уровни, которые оцифровываем.
Elegorod
Оказывается, это написано в datasheet. Для ATmega8 с. 62, Table 27. Overriding Signals for Alternate Functions in PC3..PC0. Там везде ноли. Это означает, что входы АЦП по-прежнему контролируются регистрами DDRC, PORTC. Просто к выводам ещё и АЦП подключен. То есть сначала нужно выставить вход без pull-up резистора.
P.S. И самому полезно узнать...
Посмотрев в первоначальный код, так и стоит PORTC = 0; DDRC = 0; Так что не в том дело
Дон Амброзио
Цитата(Elegorod @ May 1 2008, 00:08) *
Это означает, что входы АЦП по-прежнему контролируются регистрами DDRC, PORTC. Просто к выводам ещё и АЦП подключен.

Во как.... Не знал... Спасибо за инфу
arttab
Если источник сигнала высокоомный, то так и должно быть. или жди те когда емкость разрядится или обеспечте низкое сопротивление измеряемого сигнала
defunct
Цитата(Alexey Belyaev @ Apr 30 2008, 15:11) *
А как быть? smile.gif

Подтянуть к земле.
Какое сопротивление источника сигнала? Схему входа приведите.
Если пин просто оставить болтаться то ясное дело получите 50Гц наводку с размахом 0..ARef.
Tolyaha
Цитата(Alexey Belyaev @ Apr 30 2008, 15:11) *
Близко к тому. А как быть? smile.gif

кондер на ентот пин и общий повесить ( на ADC2). При этом если нужна скорость - контроллировать постоянную времени RC (задержка фильтра), где R - сопротивление подключаемой измерительной цепи, а C - рекомендуемый кондер, при этом считайте что емкость входа не менее 40 пф.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.