Эта история началась с того, что один мой друг решил собрать дозиметр микрон и столкнулся с трудностями. Самоделка никак не хотела запускаться: то не видела импульсов с детектора, то завышала показания при повышении напряжения аккумулятора. На форуме другу советовали искать проблему в питании детектора. Впрочем, такие советы были в ходу с самого начала обсуждения дозиметра. Связано это с тем, что достоверно померять напряжение на детекторе могут далеко не все радиолюбители.
Особенность этого дозиметра в очень экономичном потреблении энергии. Это достигнуто за счёт адаптивного преобразователя высокого напряжения и алгоритма работы микроконтроллера. Большую часть времени микроконтроллер спит. Из сна он выходит по прерываниям от таймера и внешним прерываниям от датчика или кнопки.
Вот с прерываниями от датчика и связаны многие проблемы этой конструкции. Дело в том, что Atmega8, на которой собран дозиметр, из сна может вывести внешнее прерывание только по низкому уровню. И прерывание будет генерироваться всё время пока на входе низкий уровень. С другой стороны, при выходе из сна МК требует, что бы длительность низкого уровня на входе прерывания была не менее 1 мс, иначе МК проснется но прерывания может и не произойти. Это время завязано на опорную частоту сторожевого таймера и зависит от напряжения питания и температуры.
Таким образом, если импульс с датчика дольше чем время обработки прерывания, то возможны ложные срабатывания и увеличение показаний, потому что подсчет импульсов происходит именно в этом прерывании. Если же импульс слишком короткий, то не будет счёта.
Проблема ложных срабатываний усугубляется адаптацией количества импульсов ключа преобразователя высокого напряжения в зависимости от напряжения. Чем выше напряжение питания, тем меньше импульсов, а значит и их суммарное время. А из-за того, что накачка происходит и в обработчике внешнего прерывания, то с ростом напряжения длительность обработки сокращается. Это приводит к тому, что при повышении напряжения и смене показаний заряда на экране прибор начинает врать.
Есть несколько вариантов устранения недостатков.
Растягивать прерывание. Пожалуй, самый простой способ бороться с ложными срабатываниями. В обработчике прерывания от датчика отслеживать состояние входа и выходить из прерывания только при высоком уровне. Недостаток этого способа очевиден — время нахождения в прерывании может быть велико. Это плохо из-за того, что генерация звука происходит программно внутри прерывания от таймера и может возникнуть ситуация, когда динамик включён слишком долго.
Растягивать прерывание умно. Недостатков первого способа можно избежать, если разрешить все прерывания в обработчике от датчика перед ожиданием завершения импульса. Но и тут есть подводный камень — есть небольшая вероятность переполнения стека при вложенных прерываниях.
Ожидать окончания импульса Суть та же, что и в предыдущих способах, но ожидать не в прерывании, а в основном цикле. Схема примерно такая. В прерывании увеличиваем счётчик импульсов, устанавливаемые флаг "был импульс" и запрещаем прерывание от датчика. В основном цикле вызываем функцию завершения обработки импульса. Если установлен флаг, то функция производит накачку преобразователя и ожидает высокий уровень на входе от датчика. При появлении высокого уровня разрешаются прерывания от датчика и функция завершается. Правильная реализация этого способа требует переделки всех мест, где время обработки может быть больше, чем интервал между двумя сработками датчика при максимальном уровне радиации. Это сканирование кнопок и звуковая сигнализация, где используются программные задержки. Так же необходим анализ времени обновления экрана. В итоге, реализация может оказаться слишком сложной и породить трудности для расширения возможностей прибора.
Аппаратный способ. Добавить в схему D-триггер с RS входами (например CD4013), завести сигнал с датчика ему на тактовый вход, при этом на входах R и D должен быть ноль. Один выход МК соединить с входом S триггера. Импульс датчика защелкивает в триггере ноль, МК просыпается и в прерывании устанавливает триггер в единицу. 100% надёжность и отсутствие осечек и для коротких и для длинных импульсов.