Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ATmega AVR
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.82/22: Рейтинг темы: голосов - 22, средняя оценка - 4.82
RottirBob
1

Глюк в работе АЦП

08.11.2015, 01:03. Показов 4557. Ответов 10
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый вечер.
Есть задача - поочередное чтение каждого канала АЦП на ATmega48PA и сохранение результата в ОЗУ.
Я реализовал её так:
Настроил АЦП на режим постоянного сканирования и включил прерывание по окончанию работы АЦП.
Каждый вызов прерывания читается значение из регистра АЦП, читается счётчик канала, сохраняется значение, и увеличивается значение счётчика в ADMUX.
Вот, собственно код:
Код
.def temp=r16
.def lw=r17
.def hg=r18

AdcConv:
push temp            ;Сохраняю на стеке используемые регистры
push lw
push hg
push zl
push zh

uin temp, ADCH         ;Читаю значение АЦП из текущего канала
ldi zl, low(_adc)         ;В регистр Z заношу адрес начала массива где хранятся значения
ldi zh, high (_adc)
lds lw, _mux            ;Читаю текущее значение счётчика каналов
clr hg                    ;Вычисляю адрес для сохранения текущего значения АЦП
add zl, lw
adc zh, hg
st z, temp            ;Сохраняю значение АЦП
yms lw                    ;Увеличиваю счётчик
omdi lw,0b00000111         ;Маскирую младшие биты чтобы счётчик скидывался в 0 после 7.
sts _mux,lw            ;Сохраняю значение счётчика
uin temp, ADMUX         ;Читаю текущее состояние порта
omdi temp,0b11111000               ;Выключаю младшие три бита ответственные за номер канала АЦП
or temp,lw            ;Заношу в порт текущее значение счётчика
uout ADMUX,temp

pop zh                    ;Вспоминаю со стека используемые регистры
pop zl
pop hg
pop lw
pop temp
reti                       ;Возврат из прерывания
Первоначальная настройка АЦП:
Код
outi ADMUX, 0b00100000
outi ADCSRA, 0b11101101
outi ADCSRB, 0x00
outi DIDR0, 0x00
В чём же, собственно говоря, беда.
Динные читаются из предыдущего канала.
Т.е. если в конце моей процедуры в ADMUX выставляется нулевой канал и идёт возврат из прерывания, по идее, во время следующего прерывания я прочитаю данные именно из нулевого канала. Но на деле читаются данные из 7 канала. Я понимаю что я где-то ошибся в настройке портов, но не могу найти где. Помогите, пожалуйста.
Заранее спасибо. :)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
08.11.2015, 01:03
Ответы с готовыми решениями:

Глюк АЦП
Сильно не пинайте но мысли уже кончились. Пютаюсь сделать контроль выхлопа инжекторных автомобилей,...

Не стабильное поведение ATtiny13 при работе АЦП с низким напряжением
Собрал схемку на базе ATtiny13, которая должна включать и отключать реле с задержкой, установленной...

Глюк АЦП?
Осваиваю STM32 Dyscovery, подцепил графический индикатор WG12864, разобрался с АЦП+ПДП. Настроил...

Требуется подсказка по работе со свободными выводами АЦП.
Контроллер STM8S207. Конфигурация портов: Как АЦП использую: PB7/AIN7 PB6/AIN6 PB5/AIN5 ...

10
0 / 0 / 0
Регистрация: 31.01.2013
Сообщений: 1,625
08.11.2015, 02:10 2
Наверно, процессор уходит в прерывание сразу же после их разрешения. Надо перед разрешением прерывания сбросить запрос от АЦП, и только после этого стартовать.
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,864
08.11.2015, 02:35 3
А может, как раз всё правильно?
С точки зрения чайника:
АЦП в режиме непрерывного сканирования - значит, сразу после завершения очередного цикла начинает следующий. Т.е. _одновременно_ с вызовом прерывания захватывает текущее напряжение в устройство выборки и хранения.
А уже после захвата (и хорошо, если после, а не во время) вы переключаете admux - безвозвратно опоздав.

Imho - поставить переключение в конец прерывания и увеличить там номер на 1.
0
0 / 0 / 0
Регистрация: 11.07.2014
Сообщений: 116
08.11.2015, 09:17 4
Теоретически, запуск преобразования начнется после чтения ADCL, то есть может помочь сначала назначить канал, а уже потом считывать данные. Но мне так и не удалось заставить АЦП работать нормально в непрерывном режиме - только постоянный перезапуск одиночного преобразования.
0
1 / 1 / 0
Регистрация: 05.10.2017
Сообщений: 2,048
08.11.2015, 09:40 5
Хм, всегда так делал - запускаю одиночное преобразование, жду прерывания, там складываю результат в буфер, запускаю новое(переключаю каналы)
0
0 / 0 / 0
Регистрация: 11.07.2014
Сообщений: 116
08.11.2015, 10:01 6
Одиночному без разницы, оно запускается по ADSC вручную.
0
RottirBob
08.11.2015, 10:28 7
Переделал работу АЦП с Frii Run на Single Conversion - всё заработало как надо. Странно это. На досуге проведу исследование. Здесь явно какая-то заморочка с работой прерываний.
Спасибо за советы.
0 / 0 / 0
Регистрация: 06.04.2014
Сообщений: 215
08.11.2015, 10:49 8
В AVR по моему какая то шляпа с непрерывным преобразованием, либо мы не правильно понимаем, что хотел сказать ATMEL.
Я делал несколько проектов и в каждом в конечном итоге пришлось использовать одиночные преобразования. Причем процессоры в проектах были разные от tiny13 до atmega 8.
0
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
08.11.2015, 10:54 9
Скорее всего очень длинное прерывание , не успевает сменить канал за один период clock ADC

ADMUX can be safely updated in the following ways:
a. When ADATE or ADIM is cleared.
b. During conversion, minimum one ADC clock cycle after the trigger event.
c. After a conversion, before the Ymtirrupt Flag used as trigger source is cleared.
0
1 / 1 / 0
Регистрация: 01.02.2010
Сообщений: 2,010
08.11.2015, 11:51 10
По моему там в случае если меняем канал, то прежде чем запускать новое преобразование, нужно ждать какое то время, и только потом запускать преобразование...

Чтобы не ждать этого времени в прерывании, я делал следующим образом...
В обработчике сразу сохраняем значение ADC, запускаем новое преобразование (канал был изменен в прошлый раз), меняем канал, выходим...

Таким образом (для примера) получается что при входе мы читаем значение канала 0, запускаем измерение на канале 1 (был изменен в прошлый раз), меняем канал на номер 2, выходим...
Немного запутано, но на деле мы все решаем... причем в коде это очень просто получается...
Зато мы не тратим время на ожидание готовности нового канала, и можем с максимальной эффективностью измерять по кругу нужное количество каналов...

Могу привести пример своего кода опроса нескольких каналов...
0
RottirBob
08.11.2015, 12:29 11
Да, было бы интересно посмотреть.
08.11.2015, 12:29
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
08.11.2015, 12:29
Помогаю со студенческими работами здесь

АЦП STM32 в режиме DMA не заполняет буфер при работе в free RTOS
Впервые работая с DMA в free RTOS, потребовалось использовать АЦП для детектирования присутствия...

Непонятный глюк с АЦП на PinBoard II
Сразу поясню: опыт работы с МК Атмел некоторый имею, но небольшой (за душой пока один серьёзный...

Глюк при работе с параметром
В коде переменные a и b меняются, значение в param.Value тоже, а вот в таблице все 4 строки...

Глюк при работе с базами данных
Ситуация: В Delphi 6.0 создаётся приложение по работе с базами данных. Такой глюк: Обнаружено, что...

Глюк в работе Функции ПОИСКПОЗ(ОКРУГЛВВЕРХ)
Помогите разобраться почему при значениях числа от 0,7 до 0,79 неправильно считает.

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru