Перейти к содержанию
    

АЦП ATmega8. Смена каналов ADMUX

Всем привет!

 

Первый раз работаю с ATmega8 в режиме чтения нескольких аналоговых сигналов.

Пишу в IARе...

 

Аналоговые входы: РС5 (28-я нога), РС3 (26-я нога), РС2 (25-я нога).

Кварц 11.0592 MHz

 

// инициализация АЦП

ADMUX = 0x03; // REFS1=REFS0=0 Uопорн на AREF

// MUX3..0=0011 вход на ножке PC3

ADCSR = 0x8F; // ADEN=1 ADC enable

// ADSC=0 запуск позже;

// ADIE=1 ADC interrupt enable

// ADPS2..0=111 Fosc/128 = 86,4кГц

 

Запускаю преобразование таймером каждые 10мс:

ADCSR_Bit6 = 1; // ADSC=1 старт АЦП

 

И вот собственно обработчик прерывания:

//Обработчик прерывания по завершению преобразования в АЦП

#pragma vector = ADC_vect

__interrupt void OnADCConversionComplete ()

{ unsigned int tmp, tmpH;

 

tmp = (unsigned int) ADCL;

tmpH = (unsigned int) ADCH; tmpH = tmpH << 8;

tmp = tmp + tmpH;

tmp = tmp >> 2; // получаем результат в младших 8 битах

 

if (ADMUX == 0x03)

{ U26 = (unsigned char) tmp; // в U26 - напряжение на 26-й ноге

ADMUX = 0x05;

}

else

{ if (ADMUX == 0x05)

{ U28 = (unsigned char) tmp; // в U28 - напряжение на 28-й ноге

ADMUX = 0x02;

}

else

{ if (ADMUX == 0x02)

{ U25 = (unsigned char) tmp; // в U25 - напряжение на 25-й ноге

ADMUX = 0x03;

}

}

}

ADCSR_Bit6 = 0; // ADSC=0 запрет АЦП

}

 

 

Вроде все просто, но есть подозрение, что что-то не так...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вместо:

tmp = (unsigned int) ADCL;

tmpH = (unsigned int) ADCH; tmpH = tmpH << 8;

tmp = tmp + tmpH;

tmp = tmp >> 2; // получаем результат в младших 8 битах

 

я бы сделал так:

 

tmp = (unsigned int) ADCL;
tmpH = (unsigned int) ADCH;
tmp+=tmpH*0x100;
tmp>>=2;

 

Хотя вроде можно к ADC обратится как 16-разрядному регистру, поэтому первые 3 операции можно исключить.

 

Все вышесказанное верно, если у вас не включен режим выравнивания результата влево.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

IAR действительно позволяет ADC сразу считать.

unsigned int tmp=ADC;

 

А вот так, например, у меня от таймера перебирает каналы:

#pragma vector=TIMER0_OVF_vect
__interrupt void TIMER0()
{
 static unsigned char adc_chanel=0;
 unsigned int value=ADC;
 switch(adc_chanel)
 {
   case 0:
     U0=value;
     adc_chanel++;
     break;
   case 1:
     U1=value;
     adc_chanel++;
     break;
   case 2:
     U2=value;
     adc_chanel++;
     break;
   case 3:
     U3=value;
    adc_chanel=6;
     break;
   case 6:
     U6=value;
     adc_chanel++;
     break;
   case 7:
     U7=value;
     adc_chanel=0;
     break;
 }
 //Запустим следующее преобразование
 ADMUX=adc_chanel;
 ADCSR|=(1<<ADSC);
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...