Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Atmega168 и АЦП
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
juvf
Не могу запустить ни как АЦП. Настроил запуск по таймеру, выбрал нужный канал, нужную опору. настроил вектор прерывания от АЦП (the ADC Conversion Complete Interrupt). Написал обработчик:
Код
volatile unsigned int codeADC = 0;
ISR(ADC_vect)
{
    TIFR0 = 1;
    codeADC = (ADCH<<8) | ADCL;
}
После старта програмы на входе 0. Отображаю на ЖК экране - 0. Потом подаю (через делитель) +5В.... На экране 0 В. Начал дебажить, точку останова на выход из обработчика прерывания АЦП. На экране "+5В". Дальше работаю в пошаговом режиме - результат на экране соответствует тому, что подано на вход. Меняю вход - меняется экран. Снимаю брейкпоины запускаю непрерывно - на экране значение не меняется, показывает последнее значение из под дебага. тупо жму паузу .... останавливаюсь где-то в дебрях программы.... запускаю (продолжить) .... значение 1 раз обновится на то, что было в паузе и опять не меняется.

Я уже пробовал запуск ацп и от таймера, и программно битом ADSC - результат один: в пошаговом режиме результат АЦП обновляется, в непрерывном - нет.

В чем может быть проблема?

ps может в прерывание ISR(ADC_vect) не попадаю? переписал обработчик на заглушку
Код
ISR(ADC_vect)
{
    TIFR0 = 1;
        static unsigned int a = 0;
    codeADC = a++;
}

запустил без остановки, в результате значения на экране обновляются, т.е. в прерывание попадаю, вывод на экран работает нормально.
Палыч
Может быть проблема в этом:
Цитата
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, to ensure that the content of the Data
Registers belongs to the same conversion. Once ADCL is read, ADC access to Data Registers
is blocked. This means that if ADCL has been read, and a conversion completes before ADCH is
read, neither register is updated and the result from the conversion is lost. When ADCH is read,
ADC access to the ADCH and ADCL Registers is re-enabled.

Такая конструкция
Код
codeADC = (ADCH<<8) | ADCL;
не гарантирует определенную последовательность чтения регистров (т.е. не определено: какой из регистров будет прочитан первым).
Лучше - положится на транслятор (он знает лучше в какой последовательности их читать):
Код
codeADC = ADC;
juvf
Цитата(Палыч @ Dec 28 2011, 21:19) *
Может быть проблема в этом:

Лучше - положится на транслятор (он знает лучше в какой последовательности их читать):
Код
codeADC = ADC;
Конечно проблема в этом. Слона и не заметил. Переписал обработчик...
Код
ISR(ADC_vect)
{
    TIFR0 = 1;
    codeADC = ADCL;
    codeADC |= (ADCH<<8);
    
}
Всё заработало. А про такой финт "codeADC = ADC;" вообще не знал. Такая запись в ассемблере занимает чуть ли не в 3 раза меньше коду. СПАСИБО за помощь.
Проблема решена.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.