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

Обсуждаем контроллеры компании Atmel.
Ответить
Друг Кота
Аватара пользователя
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Сообщение FreshMan »

юзаю атмега8а
к 26 ноге (ADC3) подключил среднюю ногу переменника и результат преобразования пытаюсь вывести на экран
но там все по нолям
вот код
https://dpaste.de/ZYOh/raw
подскажите пожалуйста, может я шото не так настраиваю
Tell Me The Truth
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18783
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение 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 - вот у вас ничего и не делается в программе... судя по всему, главная проблема в этом :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Держит паяльник хвостом
Аватара пользователя
Сообщения: 906
Зарегистрирован: Ср апр 16, 2008 13:22:54
Откуда: Приднестровье, Тирасполь

Сообщение Goodefine »

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

С остальным согласен :beer:
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
Друг Кота
Аватара пользователя
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Сообщение 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?
ее надо лепить кро всему что используется в прерываниях ?
Tell Me The Truth
Реклама
Эиком - электронные компоненты и радиодетали
Держит паяльник хвостом
Аватара пользователя
Сообщения: 906
Зарегистрирован: Ср апр 16, 2008 13:22:54
Откуда: Приднестровье, Тирасполь

Сообщение Goodefine »

FreshMan писал(а): может дадите советт , когда делать приставку volatile?
ее надо лепить кро всему что используется в прерываниях ?
С точки зрения компилятора, обработчик прерывания (как частный случай) обычная функция. Переход на нее осуществляется хардварно (в проекте так все обернуто, что функция-обработчик ложится точно по нужному адресу перехода - ну не совсем так конечно, но можно так считать в первом приближении). Так вот, с точки зрения компилятора эта функция не вызывается никогда и он с чистой совестью заоптимизирует ее и все что в ней используется вплоть до полного исключения. Квалификатор volatile служит для указания компилятору, что переменная может изменится без его ведома, практически по воле высших сил. Следовательно, те куски кода где упоминается эта переменная выбрасывать просто так нельзя.
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Сообщение ИС-пытатель »

ее надо лепить кро всему что используется в прерываниях ?
Лепить ко всему, что используется в прерываниях, но объявлено вне их.
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18783
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение 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 - ну и что правильно? ;)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Сообщение FreshMan »

ARV писал(а):ну и что правильно?
в моем случае это учится, учится и еще раз учится !
програмирование - это ремесло, а ремеслу можна учится всю жизнь
ARV писал(а):4. зачем в инициализации периферии выводить нули в порты и регистры, которые после сброса и так аппаратно обнуляются?! эта "отрыжка" CVAVR - пустая трата flash
вот об этом я был вообще ни сном ни духом :oops:
спасибо за подсказку !
только вот непонятно почему при этом задействуется флеш ? :dont_know:
я ж лишние переменные не создаю, просто присваиваю регистарм, которые отродясь существуют, нулевые значения
разнясните пожалуйста внятно
Tell Me The Truth
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18783
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

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

Мой уютный бложик... заходите!
Контактная информация:
Держит паяльник хвостом
Аватара пользователя
Сообщения: 906
Зарегистрирован: Ср апр 16, 2008 13:22:54
Откуда: Приднестровье, Тирасполь

Сообщение Goodefine »

ARV писал(а): вот почему я дал такой свой совет. не догма - но, по-моему, логично.
Разумеется, в программировании догм быть не может. Пример с ааа не совсем точный, ибо ааа попадает под другие ограничения, а именно - осмысленные имена. Согласитесь, что START_ADC или IS_ADC_CONVERSION однозначно трактуются как макросы, а DISPLAY_BUF_SIZE явно константа. Т.е. наличие выполняемых действий вполне можно указывать самим названием сущности - порою код и комментировать не нужно. Хотя со скобками идея интересная, надо подумать.
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
Друг Кота
Аватара пользователя
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Сообщение FreshMan »

а в этом случае запись будет правильной

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

while(ADCSRA & (1<<ADSC));
или же правильне через _BV()
Tell Me The Truth
Вымогатель припоя
Аватара пользователя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Сообщение ИС-пытатель »

И так, и так можно
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18783
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение 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);
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Сообщение FreshMan »

вот так https://dpaste.de/3u2j уже на пародию не смахивает ? :))
Tell Me The Truth
Друг Кота
Аватара пользователя
Сообщения: 6337
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Сообщение Jack_A »

Ссылка битая это, а не пародия.
Родился
Сообщения: 18
Зарегистрирован: Пт май 20, 2011 19:32:49

Сообщение Mishkatoptyshka »

Всем доброго вечера.

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

еще не понятно когда можно значение ацп считывать и где. если ацп работает постоянно, значит я могу в любой момент прочитать значение ADC ?? или это делается только из прерывания??
в общем только начал изучать аврки и ассемблер. попинайте в нужном направлении =))
файлы проекта в студио и протеусе
Вложения
ATMEGA2560.rar
(14.58 КБ) 151 скачивание
AssemblerApplication4.rar
(88.01 КБ) 143 скачивания
Родился
Сообщения: 18
Зарегистрирован: Пт май 20, 2011 19:32:49

Сообщение Mishkatoptyshka »

тема еще актуальна, помогите плиз.
Держит паяльник хвостом
Сообщения: 963
Зарегистрирован: Чт апр 03, 2014 23:16:55
Откуда: Россия

Сообщение 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, а закомментировано лишнее, на мой взгляд...
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Сообщение COKPOWEHEU »

Для ATmegа8 лучше использовать не lds/sts, а простые in/out. А для универсальности лучше завернуть их в макрос, примерно так

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

.if @1<0x40
in @0,@1
.else
lds @0,@1
.endif
.endm
Родился
Сообщения: 18
Зарегистрирован: Пт май 20, 2011 19:32:49

Сообщение Mishkatoptyshka »

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

Вернуться в «AVR»