Помогите с ADC atmega48

Обсуждаем контроллеры компании Atmel.
Ответить
Aselicon
Первый раз сказал Мяу!
Сообщения: 27
Зарегистрирован: Вс июл 25, 2010 14:19:37

Помогите с ADC atmega48

Сообщение Aselicon »

Провожу измерения по 4м каналам, значения ацп лезут между всеми каналами. Что я делаю не так?
Спойлер

Код: Выделить всё

interrupt [ADC_INT] void adc_isr(void)
{ 
// Read the 8 most significant bits
// of the AD conversion result

switch (ADMUX) {
    
    case 0x64 :     //PC4
    {
     
    ADCvol2[z2]=ADCH;
    zz2+=ADCvol2[z2]; 
    z2++;
    if (z2>=10) {adctotal_2=zz2/10; z2=0; zz2=0;}      
    
    if ((adctotal_2+1 == adctotal_22)||(adctotal_2-1 == adctotal_22)||(adctotal_2+2 == adctotal_22)||(adctotal_2-2 == adctotal_22))
     {ADC_CURRENT=adctotal_2; 
      adctotal_22=(adctotal_2+adctotal_22+adctotal_22)/3;}

     else
      {
       ADC_CURRENT=adctotal_2;
       adctotal_22=adctotal_2;
      } 
    ADMUX = 0x65;  
    break; 
    }    
    
     case 0x65 :    //PC5
    {

    ADCvol1[z1]=ADCH;
    zz1+=ADCvol1[z1];
    z1++;
    if (z1>=10) {adctotal_1=zz1/10; z1=0; zz1=0;}  
    
    if ((adctotal_1+1 == adctotal_12)||(adctotal_1-1 == adctotal_12)||(adctotal_1+2 == adctotal_12)||(adctotal_1-2 == adctotal_12))
     {ADC_U_DCBUS=adctotal_1; 
      adctotal_12=(adctotal_1+adctotal_12+adctotal_12)/3;}

     else
      {
       ADC_U_DCBUS=adctotal_1;
       adctotal_12=adctotal_1;
      }  
    ADMUX = 0x63;  
    break; 
    }  

    
case 0x63 :           //PC3
    { 
    ADCvol3[z3]=ADCH;
    zz3+=ADCvol3[z3];
    z3++;
    if (z3>=10) {adctotal_3=zz3/10; z3=0; zz3=0;}    
    
    if ((adctotal_3+1 == adctotal_32)||(adctotal_3-1 == adctotal_32)||(adctotal_3+2 == adctotal_32)||(adctotal_3-2 == adctotal_32))
     {ADC_U_3PHASE=adctotal_3; 
      adctotal_32=(adctotal_3+adctotal_32+adctotal_32)/3;}

     else
      {
       ADC_U_3PHASE=adctotal_3;
       adctotal_32=adctotal_3;
      }
    ADMUX = 0x62;   
    break; 
    }  
 
case 0x62 :              //PC2
    {  
    ADCvol4[z4]=ADCH;
    zz4+=ADCvol4[z4];
    z4++;
    if (z4>=10) {adctotal_4=zz4/10; z4=0; zz4=0;}
    
    if ((adctotal_4+1 == adctotal_42)||(adctotal_4-1 == adctotal_42)||(adctotal_4+2 == adctotal_42)||(adctotal_4-2 == adctotal_42))
     {ADC_TEMP_IRAMS=adctotal_4; 
      adctotal_42=(adctotal_4+adctotal_42+adctotal_42)/3;}

     else
      {
       ADC_TEMP_IRAMS=adctotal_4;
       adctotal_42=adctotal_4;
      } 
    ADMUX = 0x64;    
    break; 
    }   
}; 

// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Start the AD conversion
ADCSRA|=0x40; 

}


Реклама
Аватара пользователя
DruidCat
Встал на лапы
Сообщения: 116
Зарегистрирован: Чт май 03, 2012 06:27:23
Откуда: Челябинск

Re: Помогите с ADC atmega48

Сообщение DruidCat »

Это у тебя такой код в прерывании? Для меня не знакома такая записи кода. Я пользуюсь avr toolchain.
Кот должен прожить жизнь без сожаления.
Реклама
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: Помогите с ADC atmega48

Сообщение oleg110592 »

значения ацп лезут между всеми каналами
тоже была подобная проблема - избавился так: после переключения канала пропускал два сэмпла измерений ацп - третий уже был нормальный.
у АЦП на входе есть так называемый "sample and hold" конденсатор ёмкостью несколько пикофарад. При переключении каналов АЦП к этому конденсатору через мультиплексор подключаются разные входы. И если вход никуда не подключен, или сопротивление источника сигнала велико, то этот конденсатор не успевает перезарядится. Из-за этого естественно есть некоторое взаимное влияние каналов друг не друга, и чем больше частота переключение каналов и выше выходное сопротивление источников сигнала, тем оно выше.
Аватара пользователя
zero648
Вымогатель припоя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Re: Помогите с ADC atmega48

Сообщение zero648 »

Что я делаю не так?
Для начала вынеси все расчеты из прерывания в основной цикл, а в прерывании оставь только чтение АЦП.
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
ИС-пытатель
Вымогатель припоя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Re: Помогите с ADC atmega48

Сообщение ИС-пытатель »

у АЦП на входе есть так называемый "sample and hold" конденсатор ёмкостью несколько пикофарад. При переключении каналов АЦП к этому конденсатору через мультиплексор подключаются разные входы. И если вход никуда не подключен, или сопротивление источника сигнала велико, то этот конденсатор не успевает перезарядится. Из-за этого естественно есть некоторое взаимное влияние каналов друг не друга, и чем больше частота переключение каналов и выше выходное сопротивление источников сигнала, тем оно выше.
Посмотри, там у него раз в 10 мкс запуск происходит. По идее, не надо никаких пропусков. Хотя, зависит от частоты работы самого АЦП.

Для ТС
А попробуй изменить в мейне запуск АЦП. Введи в прерывание переменную-флаг (volatile), что результат был обработан, а в мейне ее проверяй. Если установлена - запуск и сброс флага. Чтобы она не в цикле пускалось. Может, проблема в постоянном запуске работающего АЦП, хотя не должно быть такой.
Реклама
Аватара пользователя
ИС-пытатель
Вымогатель припоя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Re: Помогите с ADC atmega48

Сообщение ИС-пытатель »

Дай полный код программы.
Реклама
Ответить

Вернуться в «AVR»