дке, иначе большой разъем может во что-нибудь упереться.
Разберем немного работу схемы. При включении питания цепочка R1C1 формирует надежный сигнал Reset. Напомню (см. главу 12), что ставить эту цепочку необязательно— производитель МК гарантирует нормальный Reset и без каких-либо внешних элементов, однако для лучшей защиты от помех это не повредит, ведь часы у нас должны работать по идее годами в круглосуточном режиме. После установления питания диод VD2 «запрет» батарею, которая имеет напряжение заведомо ниже, чем на выходе стабилизатора. Оба диода с переходом Шоттки, падение напряжения на них не превышает 0,2–0,4 В.
Теперь разберемся с нашими компараторными «примочками». В нормальном режиме кнопка Кн2 разомкнута и на работу схемы не влияет. Напряжение батареи фактически напрямую (делитель R4/R5 делит сигнал в отношении 300/301 и эта ошибка не имеет значения) попадает на инвертирующий вход компаратора. Это напряжение сравнивается с напряжением на стабилитроне VD3, равном примерно 3,9 В (стабилитрон обязательно должен быть маломощный, типа КС139Г в стеклянном корпусе, или соответствующий импортный, в другом случае сопротивление резистора R35 надо снизить примерно в два-три раза). Когда напряжение батареи упадет ниже этого уровня (выбранного с некоторым запасом, поскольку при 3 В МК еще может нормально работать, но часть напряжения батареи упадет на диоде VD2, кроме того, следует учитывать, смена батарейки может произойти не сразу), то компаратор перебросится в состояние логической единицы по выходу.
Программа (см. далее) это зарегистрирует и разделительная точка (пара светодиодов VD1 и VD2, рис. 14.3) перестанет мигать и будет гореть постоянно. Восстановление произойдет сразу, как только батарею сменят на свежую. Та же реакция будет, если просто отключить батарею тумблером «Бат» (S1 на рис. 14.2) или удалить ее. Для того, чтобы в этих случаях вход компаратора не оказывался «висящим в воздухе», и предназначен резистор R5. Ток через него настолько мал (около 1,5 мкА), что на разряд батареи это не оказывает влияния. С8 защищает вход от наведенных на этом резисторе помех.
При пропадании внешнего питания диод VD1 запирается, a VD2 открывается и напряжение батареи поступает на питание МК. Резистор R6 вместе с развязывающим конденсатором С2 предназначены для большей устойчивости работы МК в момент перепада напряжений при переключении питания, для той же цели служит конденсатор С7, установленный параллельно кнопке Кн1 (иначе при перепадах напряжения может спонтанно возникать прерывание, и часы войдут в режим установки, о котором см. далее). Одновременно с переключением питания становится равным нулю напряжение на стабилитроне, а т. к. при этом стабилитрон представляет собой обрыв в цепи, то установлен резистор R36, который служит тем же целям, что и R5. Компаратор работать перестает (точнее, он всегда будет показывать «нормальную» батарею), но нас это не волнует, т. к. индикации все равно нет. Тумблер «Бат» нужен для отключения батареи в случае, если вы хотите остановить часы надолго, а вот тумблер для включения сетевого питания тут совершенно не требуется (разве что на время отладки).
Полный текст программы часов приведен в Приложении 5 (раздел «Программа для часов», листинг П5.1). Все подробности даны в виде комментариев к тексту программы, здесь мы разберем только общее построение и принцип работы.
При включении питания процессора все регистры обнулены, программа начинает работу с команды по метке RESET. Здесь она устанавливает соответствующие порты на выход (все, кроме двух входов компаратора и входа кнопки Кн1), затем делает нужные установки для таймеров и разрешает соответствующие прерывания.
Timer 0 у нас будет по событию переполнения управлять разрядами в режиме динамической индикации. При заданной частоте на входе Timer 0, равной 1/8 от тактовой (4 МГц), частота управления разрядами получится равной 4 МГц/8 = 500 кГц/256 (емкость счетчика), т. е. чуть меньше 2 кГц, а сами разряды (4 шт.) будут изменяться с частотой почти 500 Гц, что однозначно превышает порог заметности мигания.
Заметки на полях
Заметим, что при проектировании питания подобных устройств следует учитывать еще одно обстоятельство: в динамическом режиме для питания индикаторов пульсирующее напряжение использовать нельзя (как в схеме со статической индикацией вроде термометра из главы 10), т. к. обязательно возникнут биения между частотами питающего напряжения и переключения разрядов, и яркость свечения будет пульсировать. Потому напряжение +12 В необязательно должно быть стабилизированным, но совершенно необходим сглаживающий фильтр (некоторая неизбежно возникающая — см. главу 4 — величина пульсаций, конечно, может присутствовать). На самом деле в данной конструкции это условие соблюдается автоматически, т. к. те же +12 В подаются и на вход стабилизатора +5 В, но в дальнейшем мы встретим конструкции, в которых питание индикаторов осуществляется от отдельной обмотки трансформатора, и там об этом забывать не следует.
16-разрядный Timer 1 у нас будет управлять собственно отсчетом времени по прерыванию сравнения. Для этого в регистры сравнения загружается число 62 500, а предварительный коэффициент деления задается равным 1/64, тогда прерывание таймера будет возникать с частотой 4 МГц /64/62500 = 1 Гц. На практике число для сравнения подгоняется под конкретный кварц, и обычно оказывается почему-то меньше теоретической величины 62 500 (так, в моем случае оно было равно 62 486).
Подробности
Как быстро подобрать коэффициент деления? Можно воспользоваться высокоточным частотомером (мультиметры, позволяющие измерять частоту, не подойдут решительно, а большинство радиолюбительских частотомеров пригодны лишь для ориентировочной прикидки) для измерения длительности секундного импульса на выводе ОС1. При отсутствии такого прибора следует воспользоваться следующим приемом: установить часы с каким-то определенным коэффициентом (скажем, с теоретическим значением 62 500), например, по компьютерному времени, которое несложно выставить через Интернет очень точно. Так как небольшая ошибка все равно может сохраниться (см. далее процедуру установки), то после установки отметьте точную разницу в секундах между моментом смены показаний минут нашей конструкции и компьютерных часов, и запишите ее. Потом выдержите часы достаточно длительный промежуток времени (чем длиннее, тем точнее), в течение которого они не должны «сбоить» с необходимостью переустановки времени. Снова точно установите компьютерное время и опять запишите разницу в момент смены минут.
Таким образом вы получите величину ухода часов. Пусть, например, она составляет 200 с месяц в сторону отставания. Это значит, что у нас секундный интервал длиннее необходимого на 200/2592000 = 7,7 10-5 часть, т. е. на 77 мкс (число 2 592 000 есть число секунд за 30 дней, проверьте). Эту же величину мы можем получить и с помощью частотомера. Настолько следует повысить частоту «тиков» таймера, для чего нужно уменьшить наш коэффициент деления на величину 62500∙7,7∙10-5 = 5, т. е. в регистры таймера необходимо записать число 62 495. Отметьте, что, несмотря на кажущуюся достаточно высокую величину коэффициента деления 62 500, изменение его всего на единицу изменит ход часов на целых 40 секунд в месяц, т. е. более чем на секунду в сутки — это является следствием использования 16-разрядных счетчиков-таймеров, и крупнейшим недостатком применения МК для отсчета времени. Далее мы увидим, что для более тонкой подстройки нам придется изощряться, придумывая всякие хитрости (см. главу 19).
Кроме этого, в процедуре инициализации разрешается прерывание от кнопки Кн1 (INT1). Для кнопки Кн2 (объединенной с одним из входов компаратора) отдельного прерывания не требуется, ее состояние отслеживается непосредственно в процессе установки (см. далее). По окончании установок разрешаются прерывания (команда sei), и далее программа переходит к выполнению бесконечного цикла, во время которого производится мониторинг состояния определенных узлов.
Основная логика работы часов следующая. Каждую секунду, когда происходит прерывание Timer 1, счетчик секунд sek увеличивается на единицу (см. процедуру обработки прерывания TIM1 по метке mtime). Если его значение не равно 60, то больше ничего не происходит, если равно, то регистр sek обнуляется, и далее по цепочке обновляются значения текущего времени, хранящиеся в регистрах emin, dmin, ehh и dhh (см. их определения в начале программы).
Прерывание по переполнению Timer 0 для управления разрядами происходит независимо от прерывания Timer 1 и использует установленные в последнем значения часов. По Timer 0 обнуляются все выходы всех портов, управляющие индикацией, затем проверяется значение счетчика POS, отсчитывающего последовательные номера разрядов (от 0 до 3). Чтобы не тратить время на всякие проверки и обнуления, для организации счетчика до четырех здесь учитывается тот факт, что число 4 совпадает с числом комбинаций первых двух бит. Тогда для последовательного непрерывного счета (0–1-2-3–0–1…) достаточно каждый раз увеличивать счетчик на единицу (см. команду inc pos в конце процедуры), а в начале ее лишь обнулять старшие шесть бит (команда andi pos, 3). Далее в зависимости от значения счетчика (cpi POS….) устанавливаем питание нужного индикатора (sbi PortD,) и вызываем процедуру установки маски сегментов SET_SEG, причем устанавливаемая маска определяется значением данного разряда в часах.
В процедуре SEG_SET и собственно процедурах установки маски (OUT_х) я предлагаю вам разобраться самостоятельно. Единственный вопрос, который у вас здесь может возникнуть— почему не применить удобный способ непосредственного задания маски рисунков цифр через загрузку констант командой