|
|
|
|
picmaniac: с таким расчётом, чтоб его переполнение наступало при отсутствии изменения уровня хотя бы на одном из входов в течение достаточно длительного времени (более длительности самого долгого периода в допустимом диапазоне нормальной работы). При его переполнении и происходит прерывание по тайм-ауту. Так вот, таймер тайм-аута должен быть обнулён, если импульсы на всех входах присутствуют и следуют с достаточно высокой частотой Так и я про тоже. Но ведь таймер - то должен быть "настроен", т. е. он не должен считать от 00000000 до 11111111, а начинать с какого-то начального значения, чтобы время точно выставить. Вот я и говорю, не обнулять его надо, а устанавливать в определенное значение. Разве я не прав? Далее. Почему же нельзя все-таки по фронтам работать? Берем TEMP1 из вышеописанного мной куска программы, заводим еще один регистр, ну допустим, ERROR, делаем IOR между ними и результат записываем в ERROR. В каждом обрабатываемом прерывании делаем эту процедуру и проверяем этот ERROR на наличие 11110000 (можно и на 0 проверять, это даже проще, если немного изменить предыдущую логику, но я привязываюсь к ней, т. к. суть процесса не меняется), и при наличии этого числа обнуляем (устанавливаем) таймер таймаута, после этого рег. ERROR обнуляем. Ну и т. д. В чем конкретно я тут - то ошибаюсь? Что касается моего предложения, не использовать специальный таймер, а проводить прерывания по основному таймеру, и в этих прерываниях производить проверочные процедуры на присутствие сигналов, то, почему так нельзя? Тоже не очень понял.
|
|
|
Zandy: не обнулять его надо, а устанавливать в определенное значение Согласен. Обнуление - частный случай. Почему же нельзя все-таки по фронтам работать? Я и не говорил, что нельзя. Видимо, возможен и такой вариант. Это тоже частный случай. не использовать специальный таймер, а проводить прерывания по основному таймеру, и в этих прерываниях производить проверочные процедуры на присутствие сигналов, то, почему так нельзя? Т.е. поочерёдно опрашивать входы, ждать изменений уровня, затем повторных изменений уровня... и т.д., так? С "тайм-слотами" - интервалами времени на опрос каждого входа. То, что предлагали сначала, я ещё диаграммку широкую рисовал. В принципе, можно сделать и так. Для программиста так даже наверно проще. Только видится мне один недостаток. Допустим, один тайм-слот у нас 125 мс. Четыре входа. Опрос всех входов - 4 тайм-слота, 500 мс. Получается, что за 500 мс мы отслеживаем лишь по одному-единственному периоду на каждом входе. Так? А в случае с прерываниями по изменению уровня можем отследить каждый период на каждом входе, пусть и с небольшой погрешностью иногда из-за отложенных прерываний.
|
|
|
picmaniac: Т.е. поочерёдно опрашивать входы, ждать изменений уровня, затем повторных изменений уровня... и т.д., так? Нет, не так. Завтра скажу, как. У вас тяпница, а у меня "субботница", башка после пива... и не только... уже не варит.  |
|
|
Zandy: не использовать специальный таймер, а проводить прерывания по основному таймеру, и в этих прерываниях производить проверочные процедуры на присутствие сигналов, то, почему так нельзя? Вот что я имел ввиду "в двух словах". Например, в 16F84 нет второго таймера. Что делать? Мы договорились, что время полного цикла работы основного таймера должно превышать самый длинный период измеряемого входного сигнала. Пусть наш основной таймер работает, как работал, трогать его состояние мы не собираемся. А задействуем лишь еще одно прерывание, помимо прерываний от сигналов, которое будет происходить по переполнению основного таймера. Что будем делать в этом прерывании? Базируясь на куске программы, который я приводил ранее, можно продолжить Zandy: Берем TEMP1 из вышеописанного мной куска программы, заводим еще один регистр, ну допустим, ERROR, делаем IOR между ними и результат записываем в ERROR. В каждом обрабатываемом прерывании по сигналу делаем эту процедуру А далее, когда наступает прерывание по основному таймеру, мы организуем пропуск одного прерывания, т. е. будем реагировать на эти прерывания "через раз". Так вот, "через одно" прерывание по переполнению основного таймера, будем просто проверять ERROR на наличие 11110000. Если это так, то все в порядке, все сигналы присутствуют, сбрасываем ERROR и можно работать дальше. А вот если, хотя бы в одном разряде 0, то значит, что по этому каналу длительность периода превысила все мыслимые границы или вообще сигнал отсутствует. В этом случае выполняем соответствующие действия. Почему проверяем "через раз", а не каждый раз? А потому, что входные сигналы могут быть сдвинуты между собой максимум на величину периода, т. е. все входные сигналы, в случае штатной работы, должны обязательно "засветиться" за время, равное удвоенной длительности периода нашего рабочего таймера. Вот именно это я и хотел предложить обладателям менее "мощных" контроллеров. А уж где программа будет проще, это трудно сказать, пока мы не приступим к ее написанию. 
|
|
|
В том, что я написал раньше, есть с одной стороны некоторая "гадость", с другой - перестраховка. Кто заметит, прошу высказаться.  Предлагается малость откорректировать это. Длительность работы основного счетчика таймера надо выбрать с некоторым запасом (самый длинный измеряемый период, плюс еще чуть-чуть. А прерывания обрабатывать не через раз, а каждое. |
|
|
Неплохо бы изобразить всё это на рисунке. Этот архив поможет, если с Visio дружите. |
|
|
Да, что-то я до конца не додумал. Вот рисуночек. Если сигнал отсутствует, то все в порядке, это работает, а вот, если период вышел за пределы, то тут не все в порядке. Работает, но не в каждом прерывании. Т. е. засечь то мы можем, но, что дальше делать, не понятно.  
|
|
|
А вот и мой рисунок (широкий!) для случая с тайм-аутами: http://www.pic16.nm.ru/likbez1/drawing6.gif Красным цветом выделены инкременты регистра таймера тайм-аута. Сразу появляется ещё один вопрос: откуда брать предыдущее значение таймера для расчёта периода, если по этому входу был тайм-аут (или несколько тайм-аутов) ? Будет над чем поразмыслить ещё. Zandy, а в какие моменты на Вашем рисунке опрашиваются входы? И каким образом - поочерёдно или ещё как-либо?
|
|
|
Заглянул узнать, как у вас дела  А у вас тут ещё и конь не валялся!  Чего тут думать-то? Трясти надо! В смысле, программу писать Можно для начала вовсе без тайм-аута... Кстати, о тайм-ауте. Можно обойтись одним таймером и для измерения длительности импульсов и для тайм-аута. Надо разрешить таймерное прерывание, и в нём инкрементировать счётчик, скажем, TIMEOUTS. А при прохождении импульсов по всем каналам (Zandy придумал хороший способ для определения этого события) - сбрасывать TIMEOUTS в ноль. Тайм-аут наступит при достижении переменной TIMEOUTS заданного значения, скажем, 2. Естественно, это не идеальный способ, пропадание сигнала будет определяться с некоторой задержкой, максимум - 2 оборота таймера. Зато он прост и надёжен. |
|
|
AHTOXA, вы предлагаете точно тоже самое, что и я. Я намеренно не стал усложнять свой рисуночек, чтобы было понятнее. Красным показаны прерывания от нашего таймера (не работаю я с визио, русский шрифт не пропечатался). picmaniac: Zandy, а в какие моменты на Вашем рисунке опрашиваются входы? И каким образом - поочерёдно или ещё как-либо? picmaniac, я не понимаю, вы не следите за ходом моих мыслей, я же писал об этом в предыдущих постах. Ну все также. Прерывания по сигналам. Обработка сигналов на наличие положительных фронтов. Наличие положительных фронтов записывается в отдельный регистр ERROR... ну и т. д., я же об этом подробно писал. А что на рисуночке? Сигнал по RB7 вышел из диапазона (зеленый). Длительность его периода больше, чем период счета нашего таймера. На рисуночке видно (я обвел кружочком), когда наступает таймаут, если следовать той логике обработки, которую я приводил ранее. Тут и видны все недостатки. Zandy: Если сигнал на входе отсутствует, то все в порядке, это работает, а вот, если период вышел за пределы, то тут не все в порядке. Работает, но не в каждом прерывании. Т. е. засечь то мы можем, но, что дальше делать, не понятно. АНТОХА мою мысль уловил, но тоже не додумал ее до конца. Теперь об организации. picmaniac, я вашу идею уловил и просек ее давно. Просто я пытаюсь опонировать и предлагаю другие возможные варианты, которые могли бы как-то упростить алгоритм и программу. Видите, я сначала предлагаю, а потом сам же и критикую. Ясно, что продумывать сразу несколько вариантов одновременно достаточно сложно. picmaniac: Сразу появляется ещё один вопрос: откуда брать предыдущее значение таймера для расчёта периода, если по этому входу был тайм-аут (или несколько тайм-аутов) ? Будет над чем поразмыслить ещё. Я что-то не вижу тут особой проблемы. А откуда мы берем предыдущее значение таймера при включении прибора? Я думаю, что постоянное текущее усреднение по 8-и текущим периодам отфильтрует это дело и первое (начальное) значение таймера по истечении некоторого времени уже не будет играть роли. Другое дело, если мы будем иметь на входе "чудной" сигнал. Ну типа, несколько периодов нормальных, потом отсутствие сигнала, потом опять норма и т. д. Но ведь мы не собираемся строить нашу "балалайку", реагирующую на все случаи жизни. Мы и так "перевыполняем" изначальное ТЗ, которое выдал Splav56. |
|
|
|
|