Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Параллельная работа таймера и АЦП
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Igoreha027
Пробовал сделать прибор по "грубой" оценке АТХ блоков питания. Идея была такова: при нажатии кнопки прибор отслеживал напряжения и время прихода сигнала Power Good в mS (когда все напряжения установились в 5% коридоре). Время PG фиксировалось и прибор переходил в режим измерения, если напряжения выходили за коридор, то время не мерялось и выдавалось индикация отклонившегося параметра.
Проблема возникла в невозможности параллельной работы таймера-счетчика и АЦП. Время неправильно показывает.
Подскажите как выйти из такой ситуации или где почитать можно.
В примере все файлы.
arttab
открыть проек оркада не смог.
у меня в большинстве устройств на атмеле работают и ацп и таймер. Интервалы измерений привязанны к временным интервалам,
Пример: наждые 2 мсек. запускаетися ацп. по окончанию преобразования идет обработка результата измерения. Время преобразования меньше 2 мсек.
KRS
Цитата(Igoreha027 @ Apr 9 2007, 12:42) *
Пробовал сделать прибор по "грубой" оценке АТХ блоков питания. Идея была такова: при нажатии кнопки прибор отслеживал напряжения и время прихода сигнала Power Good в mS (когда все напряжения установились в 5% коридоре). Время PG фиксировалось и прибор переходил в режим измерения, если напряжения выходили за коридор, то время не мерялось и выдавалось индикация отклонившегося параметра.
Проблема возникла в невозможности параллельной работы таймера-счетчика и АЦП. Время неправильно показывает.
Подскажите как выйти из такой ситуации или где почитать можно.
В примере все файлы.


Судя по беглому просмотру С файла у вас функции вывода на LCD и ... вызываются и из таймерного прерывания! Они во первых могут конфликтовать с вызовами из основной программы, во вторых это очень долгая операция ее нельзя из обработчика вызывать.
gormih
Небольшой совет:

Счетчик времени привязывать не к таймеру, а к прерыванию АЦП.

Зная частоту дискретизации можно легко посчитать промежуток времени :-)
Igoreha027
Цитата(arttab @ Apr 9 2007, 14:36) *
открыть проек оркада не смог.
у меня в большинстве устройств на атмеле работают и ацп и таймер. Интервалы измерений привязанны к временным интервалам,
Пример: наждые 2 мсек. запускаетися ацп. по окончанию преобразования идет обработка результата измерения. Время преобразования меньше 2 мсек.


Проект не в оркаде, а в Протеусе. У меня шесть каналов АЦП и точность показаний времени до 1 mS, так что 2х6=12 mS это уже не то
=GM=
Цитата(Igoreha027 @ Apr 9 2007, 12:25) *
Проект не в оркаде, а в Протеусе. У меня шесть каналов АЦП и точность показаний времени до 1 mS, так что 2х6=12 mS это уже не то

Действительно, стоит переделать прерывание от таймера. Поставьте в нём прежде всего запуск преобразования АЦП, потом подсчет вашего времени s, проверка и установка флага, что преобразование началось и никакой п/п show(). В основной программе надо подождать установленного флага, обработать соответствующий канал и сбросить флаг. Преимуществом такого подхода будет то, что вызов АЦП будет происходить на регулярной основе (2 мс или сколько вам там надо), не зависящей от времени выполнения подветвей вашей основной программы.

Вместо конструкции for и if поставьте switch, будет ещё компактнее.
gormih
Цитата(=GM= @ Apr 9 2007, 22:55) *
Действительно, стоит переделать прерывание от таймера. Поставьте в нём прежде всего запуск преобразования АЦП, потом подсчет вашего времени s, проверка и установка флага, что преобразование началось и никакой п/п show(). В основной программе надо подождать установленного флага, обработать соответствующий канал и сбросить флаг. Преимуществом такого подхода будет то, что вызов АЦП будет происходить на регулярной основе (2 мс или сколько вам там надо), не зависящей от времени выполнения подветвей вашей основной программы.

Вместо конструкции for и if поставьте switch, будет ещё компактнее.




Если грамотно организовать ADCRun - никакой таймер не нужен впринципе. То, что много каналов ничего не решает - время переключения на канал и время оцифровки текущего канала постоянно, следовательно прерывания АЦП возникают через равные промежутки времени. Чем не таймер? Тем более, что в атмеге ниже определнной скорости оцифровки АЦП в режиме постоянного преобразования АЦП добится невозможно, и о медленности данного метода говорить не приходится.

Не понятно вообще, зачем делать паралельные процессы там, где они не только не нужны, но и мешают. Таймер понятия не имеет о том, когда АЦП закончило преобразование (если конечно он его не запускает), прерывание АЦП же хорошо знает, когда закончилось преобразование и точнее его вам никто не измерит промежуток времени, как бы вы не старались.
=GM=
Цитата(gormih @ Apr 10 2007, 10:22) *
Если грамотно организовать ADCRun - никакой таймер не нужен в принципе. То, что много каналов ничего не решает - время переключения на канал и время оцифровки текущего канала постоянно, следовательно прерывания АЦП возникают через равные промежутки времени. Чем не таймер? Тем более, что в атмеге ниже определённой скорости оцифровки АЦП в режиме постоянного преобразования АЦП добится невозможно, и о медленности данного метода говорить не приходится.

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

Да, и у автора однократный режим, он переключается с канала на канал и разово запускает АЦП.
gormih
Цитата(=GM= @ Apr 10 2007, 16:08) *
Так не годится. Ну вот вы решили добавить некую функцию, добавили её, а все времена у вас поплыли.




Вы имеете ввиду добавить функцию в прерывание АЦП? В таком случае ставьте ее уже после перезапуска ацп, и ничего не поплывет. Перезапуск АЦП в режиме ADCRUN на сколько я помню в атмеге происходит после считывания старшего байта результата. Вот после этого можете что угодно делать в прерывании, лишь бы время выполнения не превысило время преобразования АЦП :-) То есть первое, что следует сделать в прерывании - считать его значение, дальше заниматься своими делами и ничего не поплывет.
singlskv
Цитата(=GM= @ Apr 10 2007, 16:08) *
Так не годится. Ну вот вы решили добавить некую функцию, добавили её, а все времена у вас поплыли. Кроме того, нет гарантии, что сложные библиотечные функции, не ваши типа printf, будут всегда выполняться за одно и то же время, там может быть много ветвлений с разными временами выполнения. В итоге набежит ошибка. Возможно, в данной задаче такая ошибка не играет роли, хотя автор утверждает, что времена расходятся, но в общем так лучше не делать.

Да, и у автора однократный режим, он переключается с канала на канал и разово запускает АЦП.


Цитата(gormih @ Apr 10 2007, 22:24) *
Вы имеете ввиду добавить функцию в прерывание АЦП? В таком случае ставьте ее уже после перезапуска ацп, и ничего не поплывет. Перезапуск АЦП в режиме ADCRUN на сколько я помню в атмеге происходит после считывания старшего байта результата. Вот после этого можете что угодно делать в прерывании, лишь бы время выполнения не превысило время преобразования АЦП :-) То есть первое, что следует сделать в прерывании - считать его значение, дальше заниматься своими делами и ничего не поплывет.


ADC на AVR (да и не только на нем) штука исключительно синхронная (с MCU),
так что при острой необходимости, нет никаких препятствий для запуска ADC
синхронно с каким-нибудь таймером,
как и нет никаких препятствий для того чтобы воспользоваться ADC как еще одним таймером
при нехватке оных(правда только в режиме переполнения) smile.gif
defunct
Можно по такому алгоритму:

Код
Обработчик прерывания таймера:
1. Если не установлен флажек "АЦП занят" то
     a. установить флажек DummyRead
     b. запустить АЦП для измерения канала0
     c. Установить флажек "АЦП занят"
   Иначе - увеличить счетчик ошибок "time_offset

Обработчик прерывания АЦП

A. Прочитать результат АЦП
B. Если установлен флажек DummyRead - сбросить этот флажек и перезапусить АЦП с текущими настройками MUX'a
  Иначе:
   1. Установить флажек DummyRead
   2. Если это не последний канал, то
         a. Переключить MUX на следующий канал
         b. Запустить АЦП.
      Иначе
         Сбросить флажек "АЦП занят"

   3. "проапдейтить" данные по текущему каналу
Igoreha027
Цитата(=GM= @ Apr 10 2007, 17:08) *
Так не годится. Ну вот вы решили добавить некую функцию, добавили её, а все времена у вас поплыли. Кроме того, нет гарантии, что сложные библиотечные функции, не ваши типа printf, будут всегда выполняться за одно и то же время, там может быть много ветвлений с разными временами выполнения. В итоге набежит ошибка. Возможно, в данной задаче такая ошибка не играет роли, хотя автор утверждает, что времена расходятся, но в общем так лучше не делать.

Да, и у автора однократный режим, он переключается с канала на канал и разово запускает АЦП.


Вы правильно говорите, что времена поплывут.
Просто пробовал уменьшать или увеличить число каналов АЦП, уменьшать или увеличивать время задержки в функции преобразования АЦП или добавлять ещё функции и время тут же менялось. Изменение значений в TCNT0 при моей реализации алгоритма никак на счет таймера не влияет, но это мои ошибки и их я буду решать. Кстати замена for и if на switch и еще пара изменений дало увеличение скорости счета времени в 10 раз...
Благодарю Вас за ответы и оказанную помощь, но всегда готов послушать знающих людей, так что буду ждать еще варианты.
СПАСИБО!
gormih
Цитата(Igoreha027 @ Apr 11 2007, 06:18) *
Вы правильно говорите, что времена поплывут.
Просто пробовал уменьшать или увеличить число каналов АЦП, уменьшать или увеличивать время задержки в функции преобразования АЦП или добавлять ещё функции и время тут же менялось. Изменение значений в TCNT0 при моей реализации алгоритма никак на счет таймера не влияет, но это мои ошибки и их я буду решать. Кстати замена for и if на switch и еще пара изменений дало увеличение скорости счета времени в 10 раз...
Благодарю Вас за ответы и оказанную помощь, но всегда готов послушать знающих людей, так что буду ждать еще варианты.
СПАСИБО!




Еще раз подчеркиваю, что если вы сразу по входу в прерывание переключите канал и перезапустите его - потом будете заниматься своими делами - ничего у Вас не поплывет. Если Вы этого не понимаете - прочтите внимательнее как работает АЦП - оно жестко привязано к clk cpu!!! Поэтому, время возникновения прерывания будет постоянным, независимо от того сколько функций Вы напишете дальше, после перезапуска! И никакой таймер не даст Вам более точной оценки времени полученного результата! Просто потому, что он не знает, когда АЦП завершило преобразование с точностью до одного такта, в то время как прерывание АЦП это абсолютно точно знает!
=GM=
Цитата(Igoreha027 @ Apr 11 2007, 01:18) *
Вы правильно говорите, что времена поплывут.
Просто пробовал уменьшать или увеличить число каналов АЦП, уменьшать или увеличивать время задержки в функции преобразования АЦП или добавлять ещё функции и время тут же менялось. Изменение значений в TCNT0 при моей реализации алгоритма никак на счет таймера не влияет, но это мои ошибки и их я буду решать. Кстати замена for и if на switch и еще пара изменений дало увеличение скорости счета времени в 10 раз...
Благодарю Вас за ответы и оказанную помощь, но всегда готов послушать знающих людей, так что буду ждать еще варианты.
СПАСИБО!

"...увеличение скорости счета ВРЕМЕНИ в 10 раз..." это как? Скорость счёта увеличилась или время счёта?

Если не в лом, приведите окончательный вариант, думаю, его еще раз в 5 можно подсократить(:-).
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.