Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: АЦП ATtiny44A
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
wayfarer_lex
Доброго времени суток!
Прошу помощи, не могу получить корректный результат преобразования из АЦП модуля.
Написал простейшую прогу:
Код
#include <ioavr.h>

#define ADMUX_VALUE  0x81 //Выбираем внутренний источник опорного напряжения и канал ADC1
#define ADCSRA_VALUE 0x85 //Выбираем предделитель частоты для задания опорной частоты АЦП; так же задаем режим одиночного АЦ преобразования
#define ADCSRB_VALUE 0x00

int main(void){
unsigned char v;

   PRR_PRADC = 0; //Выключаем режим пониженного потребления, то есть разрешаем работу АЦП
   ADCSRA_ADEN = 1; //Включаем модуль АЦП, до включения все попытки доступа к битовым полям регистров АЦП будут некорректными
   //Инициализируем АЦП регистры
   ADCSRA = ADCSRA_VALUE;
   ADMUX  = ADMUX_VALUE;
   ADCSRB = ADCSRB_VALUE;
   //В порт Б будем выводить младший ниббл результата АЦ преобразования
   DDRB  = 0x0F;
   PORTB = 0x00;
   for (;;){
      ADCSRA_ADSC = 1; //Запускаем преобразование
      while (ADCSRA_ADIF == 0){}; //Дожидаемся окончания преобразования
      v = ADCMn; //Вычитываем младшие разряды результата преобразования
      PORTB = v;
   }
   return 0;
}


В итоге на выходах порта B имею постоянно одно и тоже значение. То есть АЦП не работает.
Подобный исходник легко запускается на ATmega16 и выдает нормальные значения.
Подскажите какие есть особенности у АЦП ATtiny44A.

IDE: IAR 5.51.0

Заранее спасибо за ответы.
ReAl
Первое, что сразу бросается в глаза, у Вас не сбрасывается флаг ADCSRA_ADIF, поэтому while() пролетает насквозь при первом же заходе и вообще получается каша.
Ну, у ATmega16 он сбрасывался, так как команда sbi для выполнения ADCSRA_ADSC = 1; у старых AVR была RMW со всем байтом IO-регистра и ADIF сбрасывался обратной записью прочитанной из него единицы.

Цитата(Документация на ATmega16, раздел I/O memory)
Some of the Status Flags are cleared by writing a logical one to them. Note that the CBI and SBI instructions will operate on all bits in the I/O Register, writing a one back into any flag read as set, thus clearing the flag.

А у tiny44A, как у всех новых, не сбрасывается:
Цитата(Документация на ATtiny44A, раздел I/O memory)
Some of the Status Flags are cleared by writing a logical one to them. Note that CBI and SBI instructions will only operate on the specified bit, and can therefore be used on registers containing such Status Flags.


Во вторых, читать только младший байт ADCL вроде как нельзя (я просто не пробовал sm.gif )
Цитата(Документация на ATtiny44A, раздел ADCL and ADCH – ADC Data Register)
When ADCL is read, the ADC Data Register is not updated until ADCH is read. Consequently, if the result is left adjusted and no more than 8-bit precision is required, it is sufficient to read ADCH. Otherwise, ADCL must be read first, then ADCH.
Т.е. если читать только ADCL, то АЦП-то там может что-то и делает, но результат в пару ADCH:ADCL не переносится.
Это актуально и для других AVR, что ставит под сомнение достаточную степень «подобности» исходника, работавшего на ATmega16.
wayfarer_lex
Да, Вы правы исходник для ATmega16A (я запускал и на ATmega16) немного отличен от кода для ATtiny44A.
В соответствии с Вашими замечаниями я подкорректировал код, в итоге получил желаемое.
Прямо стыдно, что поленился прочитать до конца соответствующий раздел ДШ.
Спасибо за помощь!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.