Страница 1 из 2

не запускается АЦП

Добавлено: Ср май 07, 2014 20:49:32
FreshMan
юзаю атмега8а
к 26 ноге (ADC3) подключил среднюю ногу переменника и результат преобразования пытаюсь вывести на экран
но там все по нолям
вот код
https://dpaste.de/ZYOh/raw
подскажите пожалуйста, может я шото не так настраиваю

Re: не запускается АЦП

Добавлено: Ср май 07, 2014 21:06:07
ARV
к сожалению, код у вас очень путаный. создается ощущение, что вы сначала создаете шаблоны в CVAVR, а потом пытаетесь их облагородить под WinAVR, в итоге получается всякая ерунда...

вот что мне не понравилось в вашем коде:

1. увлекаетесь макросами чрезмерно. от этого код становится не понятнее, а непонятнее :)))
2. если уж делаете макрос, который выполняет какую-то функционально осмысленную вещь, то используетй макрос с параметрами, чтобы внешне от функции не отличался. например, Srart_ADC лучше сделать как Srart_ADC()
3. раз уж вы пользуетесь WinAVR, используйте встроенный макрос _BV(MUX1) вместо 1<<MUX1 - так принято.
4. зачем в инициализации периферии выводить нули в порты и регистры, которые после сброса и так аппаратно обнуляются?! эта "отрыжка" CVAVR - пустая трата flash
5. при вашем тестовом примере - зачем вообще прерывания от АЦП?! не логичнее ли сделать опросом-ожиданием?
6. в WinAVR встроено определение переменной для результата АЦП ADC, а вы используете ADCW - опять "наследие" CVAVR. это не ошибка, просто бросается в глаза
7. Зачем нужна переменная ADC_is_done, когда ее функцию на 100% выполняет флаг ADIF в регистре ADCSRA - откажитесь от прерывания и ждите установки этого флага - вы делаете точно то же самое, но через одно место... тем более, что ADC_is_done у вас не volatile - вот у вас ничего и не делается в программе... судя по всему, главная проблема в этом :)))

Re: не запускается АЦП

Добавлено: Ср май 07, 2014 22:38:22
Goodefine
ARV писал(а):.. например, Srart_ADC лучше сделать как Srart_ADC()...
С тем, что макросы местами бестолковые, пожалуй, соглашусь. А вот записывать их надо так, чтобы потом не путать с переменными и функциями, а именно - большими буквами START_ADC. Если параметров нет, то и скобки не нужны - зачем придавать сходство сущностям, которые не должны иметь оного по определению.
ARV писал(а):3. раз уж вы пользуетесь WinAVR, используйте встроенный макрос _BV(MUX1) вместо 1<<MUX1 - так принято.
Правильнее, наверное, "...если пользуетесь только WinAVR и больше ничем пользоваться не планируете..."

С остальным согласен :beer:

Re: не запускается АЦП

Добавлено: Ср май 07, 2014 23:18:01
FreshMan
пишу в eclipse
ARV писал(а): создается ощущение, что вы сначала создаете шаблоны в CVAVR, а потом пытаетесь их облагородить под WinAVR, в итоге получается всякая ерунда...
сначала так и было, но теперь я стараюсь прописывать все ручками, дабы было понимание что я настраиваю
ARV писал(а):увлекаетесь макросами чрезмерно. от этого код становится не понятнее, а непонятнее
так где же черта ?
я как-то читал что макросы напротив прогу призваны сделать боле понятной и читабельной
поэтому и взял сие на вооружение
ARV писал(а):2. если уж делаете макрос, который выполняет какую-то функционально осмысленную вещь, то используетй макрос с параметрами, чтобы внешне от функции не отличался. например, Srart_ADC лучше сделать как Srart_ADC()
странно :roll: тогда с первого взгляда и не отличишь что перед тобою, макрос али функция
разве это считается хорошим тоном ?
ARV писал(а):3. раз уж вы пользуетесь WinAVR, используйте встроенный макрос _BV(MUX1) вместо 1<<MUX1 - так принято.
это принято по какому-то соглашению ?
в свези с чем это связано ?
хочу понять почему принято так _BV(MUX1) а не так 1<<MUX1
ARV писал(а):5. при вашем тестовом примере - зачем вообще прерывания от АЦП?! не логичнее ли сделать опросом-ожиданием?
условимся что есть некое ТЗ:
запускать преобразование раз в секунду
идти по своим делам
после окончания преобразования обработать результат и вывести на экран
ARV писал(а):6. в WinAVR встроено определение переменной для результата АЦП ADC, а вы используете ADCW - опять "наследие" CVAVR. это не ошибка, просто бросается в глаза
опять, это произошло из-за непонимания сути
в одних я видал что используется ADCW, а в других ADC
какой из этих вариантов правильнее я не знаю, поэтому и выбрал первый попавшийся
как делать правильно ?
ARV писал(а):Зачем нужна переменная ADC_is_done, когда ее функцию на 100% выполняет флаг ADIF в регистре ADCSRA
полностью с вами согласен :oops:
ARV писал(а):ADC_is_done у вас не volatile - вот у вас ничего и не делается в программе... судя по всему, главная проблема в этом
ДА......., в этом и была проблемма !
может дадите советт , когда делать приставку volatile?
ее надо лепить кро всему что используется в прерываниях ?

Re: не запускается АЦП

Добавлено: Ср май 07, 2014 23:46:19
Goodefine
FreshMan писал(а): может дадите советт , когда делать приставку volatile?
ее надо лепить кро всему что используется в прерываниях ?
С точки зрения компилятора, обработчик прерывания (как частный случай) обычная функция. Переход на нее осуществляется хардварно (в проекте так все обернуто, что функция-обработчик ложится точно по нужному адресу перехода - ну не совсем так конечно, но можно так считать в первом приближении). Так вот, с точки зрения компилятора эта функция не вызывается никогда и он с чистой совестью заоптимизирует ее и все что в ней используется вплоть до полного исключения. Квалификатор volatile служит для указания компилятору, что переменная может изменится без его ведома, практически по воле высших сил. Следовательно, те куски кода где упоминается эта переменная выбрасывать просто так нельзя.

Re: не запускается АЦП

Добавлено: Чт май 08, 2014 00:01:38
ИС-пытатель
ее надо лепить кро всему что используется в прерываниях ?
Лепить ко всему, что используется в прерываниях, но объявлено вне их.

Re: не запускается АЦП

Добавлено: Чт май 08, 2014 08:42:43
ARV
Goodefine писал(а):А вот записывать их надо так, чтобы потом не путать с переменными и функциями, а именно - большими буквами START_ADC. Если параметров нет, то и скобки не нужны - зачем придавать сходство сущностям, которые не должны иметь оного по определению.
именно с целью не придания сходства с не связанными сущностями я и дал свой совет! глядя на следующий код, скажите мне, какое действо в нем делается: вы согласны, что по этому коду можно сделать минимум 3 принципиально разных по сути предположения:
1. показано обращение к макросу ааа
2. показано ошибочно обращение к переменной ааа
3. показано правильно обращение к волатильной переменной ааа
если я напишу ааа(); то как минимум 2 варианта отпадут, останется один: показано обращение к функции (или к макросу). согласитесь, что этот вариант гораздо безальтернативнее по смыслу, нежели первый?

макрос без скобок, с моей точки зрения, это символ константы или чего-то функционально неизменного, например, сокращения сложной записи разименования указателя на структуру. в этом случае он выполняет свое назначение - делает программу проще для восприятия. макрос со скобками своим видом намекает, что внутри него осуществляется некое действо, по аналогии с функцией, что, кстати, позволяет элементарным образом перейти от макроса со сложным телом к реальной функции. большие или малые буквы в макросе - это слишком неочевидные условности, чтобы с их помощью разделять сущности.

вот почему я дал такой свой совет. не догма - но, по-моему, логично.
FreshMan писал(а):тогда с первого взгляда и не отличишь что перед тобою, макрос али функцияразве это считается хорошим тоном ?
см.выше - отсутствие такой разницы разве ухудшает восприятие программы? с точки зрения программиста что макрос со скобками, что функция без параметров - это обозначение некоих действий. для компилятора разница есть, для человека - нет.

с моей точки зрения скобки символизируют наличие выполняемых действий, отсутстве скобок - признак "псевдонима" чего-то неизменного.
FreshMan писал(а):хочу понять почему принято так _BV(MUX1) а не так 1<<MUX1
принято - это не догма, можно писать и так, как вы привыкли. макрос _BV(x) определен ровно так (1<<(x)), и в данном случае как раз и упрощает код. принято у GCC-шных программистов, потому как давно придумали и массово пользуются.
FreshMan писал(а):в одних я видал что используется ADCW, а в других ADCкакой из этих вариантов правильнее я не знаю, поэтому и выбрал первый попавшийсякак делать правильно ?
что для вас правильно? для меня - то, что не отличается от даташита. вы в даташите видели упоминание ADCW? нет, есть только ADC и пара ADCL-ADCH. к чему лишние сущности? если вы покопаетесь в недрах хидеров AVR, то обнаружите, что ADCW есть то же самое, что ADC - ну и что правильно? ;)

Re: не запускается АЦП

Добавлено: Чт май 08, 2014 10:16:57
FreshMan
ARV писал(а):ну и что правильно?
в моем случае это учится, учится и еще раз учится !
програмирование - это ремесло, а ремеслу можна учится всю жизнь
ARV писал(а):4. зачем в инициализации периферии выводить нули в порты и регистры, которые после сброса и так аппаратно обнуляются?! эта "отрыжка" CVAVR - пустая трата flash
вот об этом я был вообще ни сном ни духом :oops:
спасибо за подсказку !
только вот непонятно почему при этом задействуется флеш ? :dont_know:
я ж лишние переменные не создаю, просто присваиваю регистарм, которые отродясь существуют, нулевые значения
разнясните пожалуйста внятно

Re: не запускается АЦП

Добавлено: Чт май 08, 2014 10:20:10
ARV
FreshMan писал(а):только вот непонятно почему при этом задействуется флеш ? :dont_know:
я ж лишние переменные не создаю, просто присваиваю регистарм, которые отродясь существуют, нулевые значения
разнясните пожалуйста внятно
любая запись в переменную какого-то значения - это определенный набор ассемблерных команд. пишите вы в регистр или ОЗУ - роли не играет, все равно команды ассемблера при этом выполняются. а где эти команды хранятся? правильно, во flash. следовательно, на них расходуется эта память. в WinAVR на запись 0 в регистр будет потрачено в среднем 2 команды, т.е. 4 байта fkash.

Re: не запускается АЦП

Добавлено: Чт май 08, 2014 10:42:26
Goodefine
ARV писал(а): вот почему я дал такой свой совет. не догма - но, по-моему, логично.
Разумеется, в программировании догм быть не может. Пример с ааа не совсем точный, ибо ааа попадает под другие ограничения, а именно - осмысленные имена. Согласитесь, что START_ADC или IS_ADC_CONVERSION однозначно трактуются как макросы, а DISPLAY_BUF_SIZE явно константа. Т.е. наличие выполняемых действий вполне можно указывать самим названием сущности - порою код и комментировать не нужно. Хотя со скобками идея интересная, надо подумать.

Re: не запускается АЦП

Добавлено: Чт май 08, 2014 11:05:07
FreshMan
а в этом случае запись будет правильной

Код: Выделить всё

while(ADCSRA & (1<<ADSC));
или же правильне через _BV()

Re: не запускается АЦП

Добавлено: Чт май 08, 2014 11:09:35
ИС-пытатель
И так, и так можно

Re: не запускается АЦП

Добавлено: Чт май 08, 2014 11:35:59
ARV
FreshMan писал(а):а в этом случае запись будет правильной

Код: Выделить всё

while(ADCSRA & (1<<ADSC));
или же правильне через _BV()
речь не о правильнее должна идти, а о красивее :)

но кроме прочего так же рекомендую ознакомиться со всеми возможностями предопределенных макросов WinAVR, а именно:

bit_is_set(REG,BIT) - проверка, установлен ли бит BIT в регистре REG
bit_is_clear(REG,BIT) - аналогично предыдущему, но проверка на сброшенность бита
loop_until_bit_is_set(REG,BIT) - ожидать, пока установится заданный бит в регистре
loop_until_bit_is_clear(REG,BIT) - ожидать, пока бит сбросится

то есть ваша запись может быть такой:

Код: Выделить всё

loop_until_bit_is_clear(ADCSRA, ADSC);

Re: не запускается АЦП

Добавлено: Пн июл 14, 2014 08:44:07
FreshMan
вот так https://dpaste.de/3u2j уже на пародию не смахивает ? :))

Re: не запускается АЦП

Добавлено: Пн июл 14, 2014 12:09:01
Jack_A
Ссылка битая это, а не пародия.

Re: не запускается АЦП

Добавлено: Пт окт 10, 2014 23:43:44
Mishkatoptyshka
Всем доброго вечера.

помогите с ацп разобраться. не получается запустить его.
пытаюсь заставить что бы ацп работал в режиме непрерывного преобразования. пока ничего не получилось ((

еще не понятно когда можно значение ацп считывать и где. если ацп работает постоянно, значит я могу в любой момент прочитать значение ADC ?? или это делается только из прерывания??
в общем только начал изучать аврки и ассемблер. попинайте в нужном направлении =))
файлы проекта в студио и протеусе

Re: не запускается АЦП

Добавлено: Пн окт 13, 2014 19:29:51
Mishkatoptyshka
тема еще актуальна, помогите плиз.

Re: не запускается АЦП

Добавлено: Вт окт 14, 2014 03:09:17
Rtmip
Здравствуйте. АЦП работает как задумали. Прочитать результат можно из прерывания или по факту установки флага.
Я не знаток asm на avr, но если сделаете так:
ADCCaddr_OK:
; ldi Temp, (1<<ADEN)|(1<<ADIE)|(1<<ADSC)|(0<<ADATE)|(3<<ADPS0)
; sts ADCSRA, Temp
lds Temp, ADCH
......
то все будет выводиться в порт. Вместо ldi надо lds, а закомментировано лишнее, на мой взгляд...

Re: не запускается АЦП

Добавлено: Ср окт 15, 2014 20:44:04
COKPOWEHEU
Для ATmegа8 лучше использовать не lds/sts, а простые in/out. А для универсальности лучше завернуть их в макрос, примерно так

Код: Выделить всё

.if @1<0x40
in @0,@1
.else
lds @0,@1
.endif
.endm

Re: не запускается АЦП

Добавлено: Чт окт 16, 2014 08:43:36
Mishkatoptyshka
COKPOWEHEU писал(а):Для ATmegа8 лучше использовать не lds/sts, а простые in/out. А для универсальности лучше завернуть их в макрос
у меня AtMega2560 оператор out приводит к ошибке при компиляции, а вот с sts нормально компилируется.