к 26 ноге (ADC3) подключил среднюю ногу переменника и результат преобразования пытаюсь вывести на экран
но там все по нолям
вот код
https://dpaste.de/ZYOh/raw
подскажите пожалуйста, может я шото не так настраиваю
С тем, что макросы местами бестолковые, пожалуй, соглашусь. А вот записывать их надо так, чтобы потом не путать с переменными и функциями, а именно - большими буквами START_ADC. Если параметров нет, то и скобки не нужны - зачем придавать сходство сущностям, которые не должны иметь оного по определению.ARV писал(а):.. например, Srart_ADC лучше сделать как Srart_ADC()...
Правильнее, наверное, "...если пользуетесь только WinAVR и больше ничем пользоваться не планируете..."ARV писал(а):3. раз уж вы пользуетесь WinAVR, используйте встроенный макрос _BV(MUX1) вместо 1<<MUX1 - так принято.
сначала так и было, но теперь я стараюсь прописывать все ручками, дабы было понимание что я настраиваюARV писал(а): создается ощущение, что вы сначала создаете шаблоны в CVAVR, а потом пытаетесь их облагородить под WinAVR, в итоге получается всякая ерунда...
так где же черта ?ARV писал(а):увлекаетесь макросами чрезмерно. от этого код становится не понятнее, а непонятнее
странноARV писал(а):2. если уж делаете макрос, который выполняет какую-то функционально осмысленную вещь, то используетй макрос с параметрами, чтобы внешне от функции не отличался. например, Srart_ADC лучше сделать как Srart_ADC()
это принято по какому-то соглашению ?ARV писал(а):3. раз уж вы пользуетесь WinAVR, используйте встроенный макрос _BV(MUX1) вместо 1<<MUX1 - так принято.
условимся что есть некое ТЗ:ARV писал(а):5. при вашем тестовом примере - зачем вообще прерывания от АЦП?! не логичнее ли сделать опросом-ожиданием?
опять, это произошло из-за непонимания сутиARV писал(а):6. в WinAVR встроено определение переменной для результата АЦП ADC, а вы используете ADCW - опять "наследие" CVAVR. это не ошибка, просто бросается в глаза
полностью с вами согласенARV писал(а):Зачем нужна переменная ADC_is_done, когда ее функцию на 100% выполняет флаг ADIF в регистре ADCSRA
ДА......., в этом и была проблемма !ARV писал(а):ADC_is_done у вас не volatile - вот у вас ничего и не делается в программе... судя по всему, главная проблема в этом
С точки зрения компилятора, обработчик прерывания (как частный случай) обычная функция. Переход на нее осуществляется хардварно (в проекте так все обернуто, что функция-обработчик ложится точно по нужному адресу перехода - ну не совсем так конечно, но можно так считать в первом приближении). Так вот, с точки зрения компилятора эта функция не вызывается никогда и он с чистой совестью заоптимизирует ее и все что в ней используется вплоть до полного исключения. Квалификатор volatile служит для указания компилятору, что переменная может изменится без его ведома, практически по воле высших сил. Следовательно, те куски кода где упоминается эта переменная выбрасывать просто так нельзя.FreshMan писал(а): может дадите советт , когда делать приставку volatile?
ее надо лепить кро всему что используется в прерываниях ?
Лепить ко всему, что используется в прерываниях, но объявлено вне их.ее надо лепить кро всему что используется в прерываниях ?
именно с целью не придания сходства с не связанными сущностями я и дал свой совет! глядя на следующий код, скажите мне, какое действо в нем делается:Goodefine писал(а):А вот записывать их надо так, чтобы потом не путать с переменными и функциями, а именно - большими буквами START_ADC. Если параметров нет, то и скобки не нужны - зачем придавать сходство сущностям, которые не должны иметь оного по определению.
Код: Выделить всё
aaa;см.выше - отсутствие такой разницы разве ухудшает восприятие программы? с точки зрения программиста что макрос со скобками, что функция без параметров - это обозначение некоих действий. для компилятора разница есть, для человека - нет.FreshMan писал(а):тогда с первого взгляда и не отличишь что перед тобою, макрос али функцияразве это считается хорошим тоном ?
принято - это не догма, можно писать и так, как вы привыкли. макрос _BV(x) определен ровно так (1<<(x)), и в данном случае как раз и упрощает код. принято у GCC-шных программистов, потому как давно придумали и массово пользуются.FreshMan писал(а):хочу понять почему принято так _BV(MUX1) а не так 1<<MUX1
что для вас правильно? для меня - то, что не отличается от даташита. вы в даташите видели упоминание ADCW? нет, есть только ADC и пара ADCL-ADCH. к чему лишние сущности? если вы покопаетесь в недрах хидеров AVR, то обнаружите, что ADCW есть то же самое, что ADC - ну и что правильно?FreshMan писал(а):в одних я видал что используется ADCW, а в других ADCкакой из этих вариантов правильнее я не знаю, поэтому и выбрал первый попавшийсякак делать правильно ?
в моем случае это учится, учится и еще раз учится !ARV писал(а):ну и что правильно?
вот об этом я был вообще ни сном ни духомARV писал(а):4. зачем в инициализации периферии выводить нули в порты и регистры, которые после сброса и так аппаратно обнуляются?! эта "отрыжка" CVAVR - пустая трата flash
любая запись в переменную какого-то значения - это определенный набор ассемблерных команд. пишите вы в регистр или ОЗУ - роли не играет, все равно команды ассемблера при этом выполняются. а где эти команды хранятся? правильно, во flash. следовательно, на них расходуется эта память. в WinAVR на запись 0 в регистр будет потрачено в среднем 2 команды, т.е. 4 байта fkash.FreshMan писал(а):только вот непонятно почему при этом задействуется флеш ?![]()
я ж лишние переменные не создаю, просто присваиваю регистарм, которые отродясь существуют, нулевые значения
разнясните пожалуйста внятно
Разумеется, в программировании догм быть не может. Пример с ааа не совсем точный, ибо ааа попадает под другие ограничения, а именно - осмысленные имена. Согласитесь, что START_ADC или IS_ADC_CONVERSION однозначно трактуются как макросы, а DISPLAY_BUF_SIZE явно константа. Т.е. наличие выполняемых действий вполне можно указывать самим названием сущности - порою код и комментировать не нужно. Хотя со скобками идея интересная, надо подумать.ARV писал(а): вот почему я дал такой свой совет. не догма - но, по-моему, логично.
Код: Выделить всё
while(ADCSRA & (1<<ADSC));речь не о правильнее должна идти, а о красивееFreshMan писал(а):а в этом случае запись будет правильнойили же правильне через _BV()Код: Выделить всё
while(ADCSRA & (1<<ADSC));
Код: Выделить всё
loop_until_bit_is_clear(ADCSRA, ADSC);то все будет выводиться в порт. Вместо ldi надо lds, а закомментировано лишнее, на мой взгляд...ADCCaddr_OK:
; ldi Temp, (1<<ADEN)|(1<<ADIE)|(1<<ADSC)|(0<<ADATE)|(3<<ADPS0)
; sts ADCSRA, Temp
lds Temp, ADCH
......
Код: Выделить всё
.if @1<0x40
in @0,@1
.else
lds @0,@1
.endif
.endmу меня AtMega2560 оператор out приводит к ошибке при компиляции, а вот с sts нормально компилируется.COKPOWEHEU писал(а):Для ATmegа8 лучше использовать не lds/sts, а простые in/out. А для универсальности лучше завернуть их в макрос