Страница 1 из 2
atmega8 гонит ADC или я косячу?
Добавлено: Пн мар 26, 2012 06:55:45
Qwq
Здравствуйте!
Код: Выделить всё
ADMUX = (1<<REFS0|1<<REFS1|0<<ADLAR);//настройка АЦП
while(1)
{
int n = 0;
int n1 = 0;
//вырезано все лишнее
ADMUX = (0<<MUX0|0<<MUX1|0<<MUX2|0<<MUX3);//выбор канала АЦП
ADCSRA = (1<<ADEN|1<<ADSC|1<<ADPS0|1<<ADPS1|1<<ADPS2);//Запуск АЦП, выбор скорости = 1\128 от скорости проца
_delay_ms(1000); /*задержка 1 секунда*/
n = ADCH;
n1 = ADCL;
//тут еще 10 строк кода, которые все это показывают на LCD дисплейчик
}
Протеус при симуляции делает 1 выборку, потом начинает сыпать ошибками
"result is not written to the ADC register because it has been locked"
Что я делаю не правильно? что может лочить бит АЦП?
Re: atmega8 гонит ADC или я косячу?
Добавлено: Пн мар 26, 2012 07:28:14
pyzhman
||
И сначала нужно читать младший, и только потом старший байт преобразования.
Re: atmega8 гонит ADC или я косячу?
Добавлено: Пн мар 26, 2012 08:04:02
Qwq
О! после чтения сначала ADCL, а потом ADCH стало все ок, а вот если | заменить на || все работать перестало...
Спасибо!
Re: atmega8 гонит ADC или я косячу?
Добавлено: Пн мар 26, 2012 09:25:47
pyzhman
Все верно, поторопился с ||. Это же логическое.

Re: atmega8 гонит ADC или я косячу?
Добавлено: Ср мар 28, 2012 07:23:20
hybroid
И без всяких старших-младших. На сях же пишите

Вот только если прерывания что-то ещё делают в АЦП - надо предвидеть. Да и в вашем случае тоже надо это предвидеть.
UPD:
А вот это тот ещё костыль. Как бы лучше сделать вот так:
Код: Выделить всё
while( ! (ADCSRA&(1<<ADIF)) ) asm("nop");
ADCSRA |= (1<<ADIF);
Последняя строка сбрасывает бит, не смотря на то, что он установлен в 1.
Re: atmega8 гонит ADC или я косячу?
Добавлено: Ср мар 28, 2012 07:55:15
Qwq
hybroid писал(а):И без всяких старших-младших. На сях же пишите

Вот только если прерывания что-то ещё делают в АЦП - надо предвидеть. Да и в вашем случае тоже надо это предвидеть.
UPD:
А вот это тот ещё костыль. Как бы лучше сделать вот так:
Код: Выделить всё
while( ! (ADCSRA&(1<<ADIF)) ) asm("nop");
ADCSRA |= (1<<ADIF);
Последняя строка сбрасывает бит, не смотря на то, что он установлен в 1.
1) мне младший байт вообще не нужен, потому по половинкам....
2) это не костыль это сознательная пауза, она там нужная - проц слишком быстрый...
3) прерывания не нужны, иначе конечно
Если бы хотелось быстродействия, то естественно считывал бы АЦП в прерывании, а так тут всей программы на 5 экранов - надо считать поочередно 3 каналов ацп, и вывести на ЖКИ что у нас с вольтажом у ветряка, солнечной батарейки, SAL и ориентировочное время жизни\зарадки, а когда батарейка полная потянуть за релюху и посадить ветряк на грелку, а солнечную батарейку просто в воздух повесить.
Re: atmega8 гонит ADC или я косячу?
Добавлено: Ср мар 28, 2012 08:01:32
hybroid
Ну и на хрена цитировать простыню сразу после поста? Есть кнопка "ответить".
Пауза должна быть паузой. А это - костыль ожидания конца преобразования. Вот это делается так, как я написал, а не паузой. Почему - поймёте, когда половите глюки из-за вашей "паузы".
Qwq писал(а):1) мне младший байт вообще не нужен, потому по половинкам....
Когда младший не нужен, то считывают только старший, а не по половинкам.
Qwq писал(а):проц слишком быстрый...
Впервые слышу такое про АВРки

Re: atmega8 гонит ADC или я косячу?
Добавлено: Ср мар 28, 2012 08:02:03
Мастер Ломастер
hybroid писал(а):Как бы лучше сделать вот так:
Код: Выделить всё
while( ! (ADCSRA&(1<<ADIF)) ) asm("nop");
ADCSRA |= (1<<ADIF);
Последняя строка сбрасывает бит, не смотря на то, что он установлен в 1.
Как бы лучше сделать вот так:
проще однако
Re: atmega8 гонит ADC или я косячу?
Добавлено: Ср мар 28, 2012 08:06:21
hybroid
_BV() привязывает жёстко к AVR-GCC, который не является единственным компилатором для АВР. Даже по числу вводимых символов с клавиатуры - один хрен

И вообще вы, уважаемый, забыли "!" поставить в условии while, от чего ваш "проще" превратился в полную фигню.
Без nop'а соглашусь, проще, но кому-то нагляднее с ним. К тому же, результат будет один и тот же.
Re: atmega8 гонит ADC или я косячу?
Добавлено: Ср мар 28, 2012 08:07:51
pyzhman
Раз уж пошло ковырятельство, то поучаствую тоже.
Код: Выделить всё
int n = 0;
int n1 = 0;
.
.
.
n = ADCH;
n1 = ADCL;
Нафига?
Re: atmega8 гонит ADC или я косячу?
Добавлено: Ср мар 28, 2012 08:09:32
hybroid
pyzhman писал(а):Нафига?
До сих пор выясняем

Re: atmega8 гонит ADC или я косячу?
Добавлено: Ср мар 28, 2012 08:11:13
pyzhman
О, да тут двойной прикол:
1. Использование типа int для байтовой величины.
2. Обнуление перед чтением.

Re: atmega8 гонит ADC или я косячу?
Добавлено: Ср мар 28, 2012 08:15:57
hybroid
signed int, а не unsigned int. Так что прикол скорее всего тройной. Обнуление перед чтением часто можно увидеть. Как будто переменная объявляется через рандом-генератор

Re: atmega8 гонит ADC или я косячу?
Добавлено: Ср мар 28, 2012 08:18:17
ibiza11
hybroid писал(а): И вообще вы, уважаемый, забыли "!" поставить в условии while, от чего ваш "проще" превратился в полную фигню.
Вы ошибаетесь.
Мастер Ломастер проверяет другой флаг. ADSC сбрасывается по окончании преобразования.
Re: atmega8 гонит ADC или я косячу?
Добавлено: Ср мар 28, 2012 08:23:00
Мастер Ломастер
hybroid писал(а):_BV() привязывает жёстко к AVR-GCC, который не является единственным компилатором для АВР. Даже по числу вводимых символов с клавиатуры - один хрен

И вообще вы, уважаемый, забыли "!" поставить в условии while, от чего ваш "проще" превратился в полную фигню.
Без nop'а соглашусь, проще, но кому-то нагляднее с ним. К тому же, результат будет один и тот же.
извините, но по всем пунктам не соглашусь.
1. _BV() - это всего лишь макрос, который при переносе на другой компилятор определяется в 5 секунд, и не может служить препятствием дл применения. ну а раз уж тут рассматривается код WinAVR, то почему бы не использовать все, что в нем имеется и так?
2. про ! уже ответили
3. про nop - один и тот же результат У ВАС мог получаться только из-за того, что вы допустил ошибку. в вашем случае правильно нужно писать while(...) asm volatile ("nop"); без volatile оптимизатор все NOP-ы убирает, как ненужные, и тогда получается совершенно одинаковый ассемблерный код с while(...); если сделать ПРАВИЛЬНО - код получится РАЗНЫЙ.
Re: atmega8 гонит ADC или я косячу?
Добавлено: Ср мар 28, 2012 08:34:30
hybroid
Чорт, точно. Ну тогда дико извиняюсь, попутал я

Re: atmega8 гонит ADC или я косячу?
Добавлено: Ср мар 28, 2012 10:14:32
Совесть
Мастер Ломастер писал(а):3. про nop - один и тот же результат У ВАС мог получаться только из-за того, что вы допустил ошибку. в вашем случае правильно нужно писать while(...) asm volatile ("nop"); без volatile оптимизатор все NOP-ы убирает, как ненужные, и тогда получается совершенно одинаковый ассемблерный код с while(...); если сделать ПРАВИЛЬНО - код получится РАЗНЫЙ.
Заинтересовало. Попробовал несколько различных вариантов, без volatile. При оптимизации -Os ничего не выкинуло. Какие дополнительные условия необходимы для вашего результата?
Re: atmega8 гонит ADC или я косячу?
Добавлено: Ср мар 28, 2012 10:18:21
hybroid
Версии GCC может. Я вот даже и не в курсе какая у меня. Та, которая в репозитории Debian testing лежит

У меня вроде тоже ничего не выкидывает. Сейчас полезу проверять.
UPD: в рот мне ноги! Действительно, без "nop" меньше на 4 байта. Но и без volatile nop'ы стоят на месте, никто их не выкидывает. -Os есть. gcc version 4.5.3 (GCC)
Re: atmega8 гонит ADC или я косячу?
Добавлено: Ср мар 28, 2012 10:36:25
Мастер Ломастер
чтобы не ломать голову по поводу версии, надо в НУЖНЫХ случаях писать volatile для NOP-ов, а в ненужных - просто их не ставить. в принципе, это и есть правильный подход, когда сам делаешь то, чего хочешь, не надеясь на версии компилятора.
что касается выкидывает или нет - о необходимости volatile перед нопами не раз писалось на форумах, и это реально работает/работало. с определенного момента я перестал заботиться о версиях, стараясь следовать стандарту Си.
P.S. однако, с AVR-GCC надо все-таки держать ухо востро! пришлось пересесть на версию 4.7 после того, как при наличии static перед одной функцией генерировался полностью нерабочий код из-за того, что в main убирался целый кусок совершенно не связанного с этой функцией кода! это был единственный случай, когда версия 20100110 меня подвела, и так сильно!
Re: atmega8 гонит ADC или я косячу?
Добавлено: Ср мар 28, 2012 11:18:47
Совесть
Я уже совсем запутался, как отличить "НУЖНЫЙ" nop от ненужных? и зачем вообще вводить "ненужный" nop в свою программу?