В одной из задач возникла необходимость измерять длительность временного промежутка между повторяющимися событиями в реальном времени. Для этого планирую использоваться таймер с функцией захвата. Однако возникла следующая проблема: длительность измеряемого временного промежутка может быть больше, чем полный счёт таймера от 0 до 65535. Разумное решение — сделать программное расширение таймеру, но тогда возникает другая проблема: момент фиксации времени события (осуществляемый таймером автоматически) и момент чтения этого времени (аппаратной части и программной) отличаются. Между этими двумя моментами времени может произойти переполнение таймера, в результате программная и аппаратная части временного штампа события окажутся рассинхронизированы.
Наверняка, я не первый кто с этой проблемой сталкивался, подскажите, пожалуйста, какие есть варианты решения. Заранее очень благодарен.
B@R5uk, Мои рассуждения: Приоритет CAPTURE выше чем OVERFLOW (все AVRы не просматривал, на mege8 так), т.е 1) если влетели в ОVEFLOW, инкрементируем программный счетчик и выходим из обработчика. 2) если влетели в CAPTURE, читаем ICR, читаем Overflow Flag (флаг переполнения). Если флаг переполнения не стоит, то проблем нет. Если флаг переполнения стоит, то возникает неопределенность о которой Вы говорите (если я правильно понял), но она легко решается: если считанный ICR "болшой", то CAPTURE возникло до переполнения, если "маленький", то после переполнения, которое еще не обработано.
Заголовок сообщения: Re: Длительность периода в реальном времени
Добавлено: Пт мар 24, 2017 22:31:17
Модератор
Карма: 90
Рейтинг сообщений: 1430
Зарегистрирован: Чт мар 18, 2010 23:09:57 Сообщений: 4564 Откуда: Планета Земля
Рейтинг сообщения:0 Медали: 1
viiv, что означает "большой" или "маленький" ? Это "сколько в граммах" ? Единственное решение при неатомарных ситуациях - запрет другим потокам модифицировать данные. В данном случае - это останов таймера на время его чтения. Потеряются некоторые такты, но зато вероятность нарваться на неприятности сводится к нулю. Есть ещё вариант. Поле чтения таймера, прочитать флаг его переполнения. Если он взведён (переполнение было) - сбрасываем его (чтобы не влететь в overflow) и прибавляем к считанному значению 65536.
Использование модульных источников питания открытого типа широко распространено в современных устройствах. Присущие им компактность, гибкость в интеграции и высокая эффективность делают их отличным решением для систем промышленной автоматизации, телекоммуникационного оборудования, медицинской техники, устройств «умного дома» и прочих приложений. Рассмотрим подробнее характеристики и особенности трех самых популярных вариантов AC/DC-преобразователей MW открытого типа, подходящих для применения в промышленных устройствах - серий EPS, EPP и RPS представленных на Meanwell.market.
Насколько нужна точность измерения? А если просто уменьшить частоту таймера? Т.е. те же 65535 будут набираться гораздо дольше, ровно во столько, во сколько будет ниже частота.
_________________ Глупый не задает вопросы. Глупый и так все знает.
viiv, что означает "большой" или "маленький" ? Это "сколько в граммах" ?
В предельном случае сравнить c 0x8000.
Аlex писал(а):
В данном случае - это останов таймера на время его чтения.
останавливать таймер незачем.
Аlex писал(а):
Есть ещё вариант. Поле чтения таймера, прочитать флаг его переполнения. Если он взведён (переполнение было) - сбрасываем его (чтобы не влететь в overflow) и прибавляем к считанному значению 65536.
Я про это и писал, только просто добавть 65536 нельзя, так как при установленном флаге переполнения, это самое переполнение могло возникнуть как до CAPTURE так и после.
Заголовок сообщения: Re: Длительность периода в реальном времени
Добавлено: Пт мар 24, 2017 23:51:46
Модератор
Карма: 90
Рейтинг сообщений: 1430
Зарегистрирован: Чт мар 18, 2010 23:09:57 Сообщений: 4564 Откуда: Планета Земля
Рейтинг сообщения:0 Медали: 1
Немного не допонял проблему в вопросе и поторопился с ответом. Оказывается, используют аппаратный захват. B@R5uk, у Вас проблема надуманная, которой, на самом деле, не существует. Вы говорите о двух взаимоисключающих вещах. Если вызвалось прерывание от события по захвату, а до этого не было прерывания по переполнению - значит переполнения вовсе не было, и можно смело читать захваченные данные и счётчик переполнений (он всё равно не обновится, пока мы не дойдём до обработчика переполнения). Если бы до захвата было переполнение таймера, Вы бы сначала влетели в обработку по переполнению, а потом уже по захвату.
Если бы до захвата было переполнение таймера, Вы бы сначала влетели в обработку по переполнению, а потом уже по захвату.
ИМХО это не верно. 1) прерывания могут быть запрещены, например, работает дгугой обработчик. Если при запрещенных прерываниях произошло два события (И CAPTURE и ОVRFLOW), то при разрешении прерываний вызовется обработчик с бОльшим приоритетом(CAPTURE), не зависимо от того, какое событие было раньше.
Заголовок сообщения: Re: Длительность периода в реальном времени
Добавлено: Сб мар 25, 2017 00:06:49
Модератор
Карма: 90
Рейтинг сообщений: 1430
Зарегистрирован: Чт мар 18, 2010 23:09:57 Сообщений: 4564 Откуда: Планета Земля
Рейтинг сообщения:0 Медали: 1
Если бы у бабки был ... А если упадёт метеорит на МК, то он вообще не сможет ничего обрабатывать Если знаем о такой проблеме, то нужно как то не допускать её возникновения, т.б. - стараться не запрещать в программе прерывания.
ЗЫ: Сравнение с 0x8000 - неудачное решение. Вы предлагаете все значения до 0x8000 считать переполнением таймера ?
Если знаем о такой проблеме, то нужно как то не допускать её возникновения, т.б. - стараться не запрещать в программе прерывания.
Мы же не знаем, что у ТС за задача. Может у него еще что-то работает. Что без прерываний с UART-ом и с другой переферией работать? Да и в AVR не все команды выполняются за 1 такт, есть и 2-х тактовые и трехтактовый, и четырехтактовые. выполнение команды - атомарное, т.е. не может "разорваться" вызовом прерывания. Так что в пределе эти два события (CAPTURE и OVF) могут возникнуть и во премя выполнения одной ассемблерной команды.
Аlex писал(а):
ЗЫ: Сравнение с 0x8000 - неудачное решение. Вы предлагаете все значения до 0x8000 считать переполнением таймера ?
Да, при установленном бите переполнения таймера и считанном ICR<0x8000 считать, что событие CAPTURE произошло после переполнения таймера, которое еще не обработано. О порогах можно подумать, может я чего не учел. Но разделить диапазон пополам пока сажется не таким уж плохим решением.
============== ЗЫ. Уважаемый, Аlex, похоже топик-стартеру данный вопрос не очень-то интересен, так как никакой реакции от него нету. Идея озвучена, информации для размышления ТС есть. Бабушку с метеоритами обсуждать нет никакого желания.
Использовать прерывание при переполнении. Количество_прерываний * 65536 + TCNTx.
Ну, это и называется программное расширение таймера. Со всеми вытекающими проблемами.
AndTer писал(а):
Насколько нужна точность измерения? А если просто уменьшить частоту таймера?
Думал про это. К сожалению, точность фиксирована, а период при любой частоте гарантированно может оказаться длиннее цикла таймера.
Аlex писал(а):
Единственное решение при неатомарных ситуациях - запрет другим потокам модифицировать данные. В данном случае - это останов таймера на время его чтения.
Весьма громкое утверждение. Хотя я тоже думал про остановку. Во-первых, по событию захвата таймер не останавливается, а именно в этот момент происходит чтение аппаратной части временного штампа (младших двух байт). К моменту обработки прерывания (или просто в цикле после проверки соответствующего флага), когда будет осуществляться чтение программной части временного штампа и появится возможность остановки таймера, уже может появиться рассинхрон. Во-вторых, ARV так устроена, что выключение таймера не выключает предделитель, который продолжает считать. В-третьих, отключение таймера приведёт к нарушению самого главного требования задачи — регистрации временных штампов событий в реальном времени.
Остальное почитал, требует осмысления. Я так понял единственная возможность решения проблемы — это положиться на приоритет прерываний?
viiv писал(а):
Может у него еще что-то работает. Что без прерываний с UART-ом и с другой периферией работать?
Работа с USART есть. Вывод в цикле, а ввод придётся делать через прерывания. Цикл слишком длинный, чтобы закончить его обсчёт за время приёма двух байт подряд.
Заголовок сообщения: Re: Длительность периода в реальном времени
Добавлено: Сб мар 25, 2017 11:04:23
Собутыльник Кота
Карма: 29
Рейтинг сообщений: 651
Зарегистрирован: Сб май 14, 2011 21:16:04 Сообщений: 2708 Откуда: г. Чайковский
Рейтинг сообщения:0 Медали: 1
Два прерывания - захват и переполнение.
В обработчике переполнении счетчик переполнений инкрементируется .
В захвате: 1. Сброс счетчика. 2. Если захваченный счет небольшой (например если не установлен старший бит захваченных данных), то проверяется флаг переполнения. Если флаг переполнения установлен, инкрементируется счетчик переполнений. 3. Вычиляете фактическое значение периода (если почему то затрытный расчет, то считается в основной программе). 4. Сброс флаг переполнения и счетчика переполнений.
_________________ Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Z_h_e, сбрасывать счётчик не годится, задержки между появлением события и его обработкой, в которой вы предлагаете проводить сброс, приведут к неконтролируемым добавкам (или вычитаниям) для временных штампов событий. То есть весь смысл слов "в реальном времени" потеряется.
Суммируя то, что обсуждали Аlex и viiv. Возможны следующие варианты развития событий. Вариант А 1) Событие захвата; 2) Обработка события захвата; 3) Событие переполнения; 4) Обработка события переполнения. В этом случае результат получается правильный.
Вариант Б 1) Событие переполнения; 2) Обработка события переполнения; 3) Событие захвата; 4) Обработка события захвата. В этом случае результат получается тоже правильный.
Вариант В 1) Событие захвата; 2) Событие переполнения; 3) Обработка события захвата; 4) Обработка события переполнения. Произошло некоторое наложение, но результат получается правильный.
Вариант Г 1) Событие захвата; 2) Событие переполнения; 3) Обработка события переполнения; 4) Обработка события захвата. Из-за накладки результат получается неправильный. Программная часть временного штампа на единицу больше, чем надо.
Вариант Д 1) Событие переполнения; 2) Событие захвата; 3) Обработка события захвата; 4) Обработка события переполнения. Как и в прошлом варианте результат получается неправильный. Но программная часть временного штампа на единицу меньше, чем надо.
Вариант Е 1) Событие переполнения; 2) Событие захвата; 3) Обработка события переполнения; 4) Обработка события захвата Несмотря на накладку результат получается правильный.
Мне пока не совсем понятно, какие именно из этих вариантов можно исключить, тем более, что мнения участников выше по этому вопросу разошлись. Но в любом случае, в процедуре обработки события захвата необходимо каким-либо образом определять какой именно из вариантов имел место быть, внося при необходимости поправку плюс или минус один к программной части временного штампа.
Жаль, конечно, что проблема не имеет готового решения. Но надеюсь, что правильное решение планомерным подходом получится таки найти. Заранее спасибо всем участвующим за помощь.
Заголовок сообщения: Re: Длительность периода в реальном времени
Добавлено: Вс мар 26, 2017 07:10:06
Модератор
Карма: 90
Рейтинг сообщений: 1430
Зарегистрирован: Чт мар 18, 2010 23:09:57 Сообщений: 4564 Откуда: Планета Земля
Рейтинг сообщения:0 Медали: 1
B@R5uk писал(а):
Вариант Г 1) Событие захвата; 2) Событие переполнения; 3) Обработка события переполнения; 4) Обработка события захвата. Из-за накладки результат получается неправильный. Программная часть временного штампа на единицу больше, чем надо.
Этот вариант исключён. Если событие захвата произойдёт раньше события переполнения, то программа по-любому сначала обработает захват, а потом уже переполнение.
А вот вариант Д:
B@R5uk писал(а):
1) Событие переполнения; 2) Событие захвата;3) Обработка события захвата; 4) Обработка события переполнения. Как и в прошлом варианте результат получается неправильный. Но программная часть временного штампа на единицу меньше, чем надо.
вполне возможен. И ничего с этим не поделаешь.
Берите другой проц, у которого есть, как минимум, 2 приоритета. Тогда, повесив переполнение на старший приоритет, Вы исключите ошибку.
Добавлено after 6 minutes 3 seconds:
Z_h_e писал(а):
но флаг переполнения в обработчике захвата все равно надо также проверять
Нельзя этого делать. Если событие захвата произойдёт до переполнения, то, проверкой на переполнение в событии захвата, вы прибавите лишние 65536 попугаев. Это тоже самое, что предложил viiv - проверять на 0x8000. Но то предложение, конечно же, ещё глупее...
Заголовок сообщения: Re: Длительность периода в реальном времени
Добавлено: Вс мар 26, 2017 07:18:03
Собутыльник Кота
Карма: 29
Рейтинг сообщений: 651
Зарегистрирован: Сб май 14, 2011 21:16:04 Сообщений: 2708 Откуда: г. Чайковский
Рейтинг сообщения:3 Медали: 1
Аlex писал(а):
Нельзя этого делать. Если событие захвата произойдёт до переполнения, то...
Можно и нужно. Обратите внимание на важную составляющую алгоритма - проверка флага, если захваченные данные меньше половины максимума счетчика.
Но скорректировать алгоритм надо, сброс флага переполнения нужно делать не всегда, а только если захваченные данные также меньше половины. Это из-за того что счетчик не надо сбрасывать.
_________________ Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения