Всем добрый день! Хочу рассказать о проблеме с которой можно столкнуться, при использовании АЦП контроллеров Mega. (Tiny не проверял. У Mega проверялись контроллеры 2560 и 168). Если вы используете АЦП в автоматическом запуске, то никаких проблем нет. Но у меня появилась необходимость поиграться частотой измерения. Проще всего это реализовать через разовый запуск по таймеру. Итак: Условия возникновения бага:
1) АЦП включен в режим одиночного запуска 2) Запуск АЦП обязательно происходит из прерывания по таймеру 3) Частота срабатывания таймера близка к частоте выдачи результатов АЦП (не путать с частотой работы АЦП). 4) Особенно актуально для компиляторов с языка СИ. Обязательное наличие команд обращения к регистрам указателя стека (PUSH, POP, IN, OUT, STS и др) в обработчике прерывания (ВНИМАНИЕ!!) от таймера. Присутствии этих команд в данном обработчике вызывает баг. без них все работает на ура. (если обработчик написан на ассемблере и никакие регистры не сохраняются, не извлекаются).
ОПИСАНИЕ БАГА: Блокируется АЦП. (результат получается только 1 раз и больше не меняется). Блокируются любые арифметические команды (почему-то тоже выполняются только 1 раз в цикле). Проверялось сложение, вычитание, инкремент, декремент.
Проверялось только для таймера Т0. АЦП с обычным (не дифференциальным входом). У меня частота АЦП была 125 кГц (частота выдачи результата 125000/13 Гц). Частоты таймера, при которых возникал баг от 125000/17 до 125000/12 Гц. Таймер работал в режиме сброс по совпадению. Частота контроллера 1 МГц. Предделитель таймера, контроллера и АЦП /8. При других коэффициентах деления таймера (как в большую так и в меньшую сторону) все работало хорошо. Автоматический режим АЦП тоже работал без проблем.
К конденсаторам источников питания высокой мощности предъявляются высокие требования по качеству и надежности. Пленочные – единственный тип конденсаторов, который может справиться с такой задачей. Компания Hongfa предлагает продукцию, которая подходит для применения практически во всех функциональных узлах типовых AC/DC- или DC/AC-преобразователей. Рассмотрим характеристики и применения плёночных конденсаторов Hongfa для различных решений.
А как насчет скачать последний даташит на МК и почитать раздел ERRAT? (доки doc2445...., doc8271....) Меги серии 48-88-168-328 уж больно ерратистые, причем в достаточно критичных местах...
Вслед за сериями на DIN-рейку DDRH-60/120/240 и на шасси RSDH-150/300 компания MEAN WELL выпустила новые маломощные DC/DC-преобразователи DDRH-15/30/45 со сверхшироким входным напряжением 150…1500 В, и монтажом не только на DIN-рейку, но и печатную плату или винтовым соединением. Все преобразователи семейства DDRH и RSDH работают при температурах -40…80°C и обладают высокой изоляцией 4000 В AC между входом и выходом, что обеспечивает надежную защиту. Они подходят для использования на высоте до 5000 м и сертифицированы по стандарту IEC62109-1 для фотоэлектрических систем. Преобразователи DDRH/RSDH есть в наличии и под заказ.
не работает на железе. Компилятор любой (студия 5,6 , код вижн, имадж крафт, йар). проверялось с разными вариантами оптимизации, в том числе с выключенной оптимизацией. Потом код дизассемблировался, был проанализирован (компилятор все сгенерировал правильно), все лишнее выкинулось, по новой скомпилировалось и путем выборочного закомментирования порций команд и измененения настроек таймера и АЦП были выведены результаты выше. Еррату читал. Там в основном большое потребление в спящем режиме и всякая хрень по мелочи (типа если у кого-то что-то не получается, то сам дурак, не используй эти команды).
Если кому интересен код - смотреть тему "Глюк в прерывании". Там есть. Или наберите свой.
не работает на железе. Компилятор любой (студия 5,6 , код вижн, имадж крафт, йар). проверялось с разными вариантами оптимизации, в том числе с выключенной оптимизацией. Потом код дизассемблировался, был проанализирован (компилятор все сгенерировал правильно), все лишнее выкинулось, по новой скомпилировалось и путем выборочного закомментирования порций команд и измененения настроек таймера и АЦП были выведены результаты выше. Еррату читал. Там в основном большое потребление в спящем режиме и всякая хрень по мелочи (типа если у кого-то что-то не получается, то сам дурак, не используй эти команды).
Если кому интересен код - смотреть тему "Глюк в прерывании". Там есть. Или наберите свой.
Не стоит быть столь категоричным, особо для начинающего! Насчет IDE - пользуюсь AVRstudio 4.19 под ассемблером - другим не владею. МК данных серий применять не приходилось. Опыт работ с ATtiny2313 ( viewtopic.php?f=57&t=84941&hilit=+%D1%83%D0%B1%D0%B8%D0%B9%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9+%D0%BA%D0%BE%D0%B4 ) подсказывает, что может иметь место "алгоритмический ступор" - т.е. потребуется написать программу "с чистого листа" и по возможности более упрощенный и анализируемый алгоритм заложить.
То что у меня мало сообщений на данном форуме еще не показатель моих навыков. А всего лишь показатель моей частоты посещений. И общительности. Захожу только когда не могу решить проблему сам. А пока жду ответов по возможности помогаю другим. Это раз. Ассемблером занимаюсь более 5 лет. Контроллерами AVR более 3-х лет. СИ тоже знаю довольно-таки неплохо. И с логикой у меня все вроде в поряде. Это два. А прежде чем давать рекомендации по переписыванию программы с нуля желательно было хотя бы взглянуть на нее. Там переписывать нечего. всего с десяток-другой команд. Это три. И прежде чем выложить эту тему мной была проделана недельная работа с неоднократной проверкой кода на наличие ошибок. И не только мной самим. Это четыре. Всем удачи! Это пять!
У меня в топике написано что принимается любая критика! Но не будете ли вы столь любезны аргументировать свою точку зрения? Возможно я учту ваши советы при создании следующих уроков?
_________________ Влодение рускай арфаграфией - это как владение кунг-фу: настаящие мастира не преминяют ево бес ниабхадимости
Так как очень любопытно все это, то, ИС-пытатель, к Вам просьба - выложите сюда коротенькую программку из 30 строк (без всяких там ненужных инициализаций нулями из мастера CV, как в соседней теме), которая не работает. Включите отладочное "дергание ножками" при входе/выходе в/из каждое прерывание. Покажите в протеусе временнУю расстановку этих событий и укажите конкретно - "вот это не работает". А то в коде из соседней Вашей темы запуск АЦП по таймеру происходит чаще, чем готовы данные АЦП (прерываний от АЦП нет).
Чуть-чуть поправлю. прерывание от таймера происходит реже. ))) Предделители таймера и АЦП выставлены одинаково (/8). Результат АЦП готов через 13 тактов (согласно Даташиту). А таймер срабатывает через 16 тактов (режим сброс по совпадению. OCRA0 = 15). Причем, пробовалась частота срабатывания таймера как выше частоты готовности результата АЦП, так и ниже. программа работает. Только когда частота приблизительно равна. контроллер блокируется. Я обязательно выложу ход испытаний сегодня вечером. Сначала код на СИ. Потом код на Ассемблере (Нужен для обнаружения появления ошибки при обращении к стеку в прерывании).
Результат АЦП готов через 13 тактов (согласно Даташиту). А таймер срабатывает через 16 тактов (режим сброс по совпадению. OCRA0 = 15).
ЕМНИП, результат АЦП не всегда может быть готов либо через 13 тактов. При первом замере в серии измерений результат будет через 25 тактов, и лишь следующие - через 13. Возможно, ваша программа написана так, что все замеры по сути первые. Я когда в своей программе использовал АЦП, специально делал один замер перед основным циклом.
P.S.
Код:
A normal conversion takes 13 ADC clock cycles. The first conversion after the ADC is switched on (ADEN in ADCSRA is set) takes 25 ADC clock cycles in order to initialize the analog circuitry.
первый замер после включения АЦП 25 тактов. Если Вы АЦП не выключали в промежутках между замерами, то Ваш код избыточен. А у меня в инициализации после включения сразу идут два запуска (на всякий случай). т.е. дальше когда ни тыкни - 13 тактов.
ассемблерный листинг компилятора я смотрел. и там все правильно сгенерировано. более того я уже писал о том, что я этот листинг смотрел.
Кстати, хотя это, вероятно, не относится к данной ситуации. Есть ещё один момент (по ATmega16 помню), что если нужна точность выше 8 бит, то регистры ADCL и ADCH нужно вычитывать в определённой последовательности - сначала ADCL, потом ADCH. Если после ADCL не вычитывать ADCH, то доступ к регистрам данных блокируется.
То есть, нужно либо выравнивать результат (бит ADLAR) влево, и вычитывать только ADCH (8бит точность), либо вычитывать ADCL-ADCH, и именно в этой последовательности.
блокируются не для чтения. блокируются для записи. и не оба, а только верхний. Но это не оно. потому что если изменить частоту таймера - все работает. В общем, вечером выложу исходники с пояснениями где что не работает и как обнаружить.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения