реклама на сайте
подробности

 
 
> Atmega168 и АЦП
juvf
сообщение Dec 28 2011, 14:48
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Не могу запустить ни как АЦП. Настроил запуск по таймеру, выбрал нужный канал, нужную опору. настроил вектор прерывания от АЦП (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++;
}

запустил без остановки, в результате значения на экране обновляются, т.е. в прерывание попадаю, вывод на экран работает нормально.

Сообщение отредактировал juvf - Dec 28 2011, 14:49
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 2)
Палыч
сообщение Dec 28 2011, 15:19
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Может быть проблема в этом:
Цитата
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;
Go to the top of the page
 
+Quote Post
juvf
сообщение Dec 28 2011, 16:31
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(Палыч @ Dec 28 2011, 21:19) *
Может быть проблема в этом:

Лучше - положится на транслятор (он знает лучше в какой последовательности их читать):
Код
codeADC = ADC;
Конечно проблема в этом. Слона и не заметил. Переписал обработчик...
Код
ISR(ADC_vect)
{
    TIFR0 = 1;
    codeADC = ADCL;
    codeADC |= (ADCH<<8);
    
}
Всё заработало. А про такой финт "codeADC = ADC;" вообще не знал. Такая запись в ассемблере занимает чуть ли не в 3 раза меньше коду. СПАСИБО за помощь.
Проблема решена.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 24th July 2025 - 04:30
Рейтинг@Mail.ru


Страница сгенерированна за 0.01393 секунд с 7
ELECTRONIX ©2004-2016