Глава 14 Проба пера: настольные часы

Вы никогда не задумывались, почему на обычных часах стрелки идут слева направо? Вот если бы солнечные, а затем и механические часы были изобретены в Южном полушарии, все было бы наоборот.

Сетевой Журнал Русского Ословодства

Сконструировать свои первые настольные часы «для дома, для семьи» меня заставила судьба. ЖК-индикаторы в работающих от сети стационарных конструкциях я полагаю неуместными — они «слепые» даже днем, а надо, чтобы часы было видно и ночью. Между тем, пытаясь в конце 1990-х приобрести настольные часы в связи с переездом на новую квартиру, я попал в какой-то неудачный момент, когда во всей Москве не было часов со светящимися индикаторами: старинные советские изделия, в которых малюсенькие голубенькие циферки были еле видны за густой сеткой анода, уже исчезли из продажи, а импортные на светодиодах, как говорится, «не завезли». В результате пришлось делать самому такие, какие нравится.

И хорошо, что я их сделал, потому что то, что, наконец, появилось в продаже позднее, проигрывает моей самодельной конструкции, по крайней мере, по двум статьям: по точности хода и цвету свечения индикаторов (ядовито-красный без какой-либо возможности выбора). Правда, фирменные конструкции несколько меньше размерами и обладают функциями будильника, но последние мне без надобности (никогда не пользовался будильниками), а реализовать их при необходимости несложно. Так что, как видите, часы конструировать самостоятельно стоит.

Отдельный вопрос — на какой же именно элементной базе все это делать? Во-первых, существуют, естественно, специальные микросхемы для часов.

Начал я именно с экспериментов с такими схемами (отечественного выпуска), и даже получил вполне работоспособную конструкцию. Но мне очень не понравилась их негибкость и приспособленность под определенную разновидность индикаторов, отчего пришлось «упражняться» со схемами усиления и преобразования уровней. Конструкция получилась довольно громоздкой — зачем тогда вообще специальная микросхема?

Потому первые свои законченные часы я сконструировал на универсальном микроконтроллере «в лоб», заставив МК посекундно «тикать» таймером и управлять индикаторами. Это была отличная практика написания программ для МК, и, как сейчас вижу, никаких принципиальных ошибок я не наделал. Хотя я потом создал еще пару конструкций, но и эти, самые первые часы безотказно работают уже вот без малого девятый год. Именно такую, не очень сложную для понимания, конструкцию мы и разберем в этой главе.

Заметки на полях

Предваряя темы в следующих главах, стоит отметить, что на самом деле — для массового производства — так часы, конечно, не делают. В данной конструкции, например, затруднительно воспроизвести календарь— и потому, что его алгоритм весьма громоздок (и в нем легко наделать скрытых ошибок), и потому, что он требует значительно больше индикаторов. Притом цифровыми семисегментными тут, вообще говоря, не обойдешься (день недели не удастся показать). Функции будильника также заметно усложнят схему. Наконец, — и это самое важное, — такие часы сами по себе будут работать неплохо, но если заставить микроконтроллер делать что-то еще полезное, он может попросту не справиться: начать сбоить в отсчете времени, что для часов недопустимо. К тому же такие часы практически невозможно использовать с батарейным питанием, в резервном режиме они могут идти в лучшем случае пару недель.

По этим причинам в более серьезных устройствах (например, когда в дальнейшем мы попробуем объединить часы с различными датчиками) «велосипедов» лучше не изобретать, а выбрать одну из широко распространенных неспециализированных микросхем часов, называемых еще RTC (Real Time Clock), которые включают календарь и функции будильника (а иногда и нескольких), таймера, могут выдавать во внешний мир определенную частоту, потребляют очень мало (типичная величина — 0,8 мкА), иногда обладают встроенным прямо в чип часовым кварцем (и даже с возможностью подстройки). Еще один плюс такой конструкции— часовые кварцы 32 768 Гц, как правило, точнее обычных, тех, что служат для тактирования МК. Выпускаются RTC с самыми разнообразными интерфейсами: от параллельного до I2С. Именно такие микросхемы применяются, например, в компьютерах. Особенно преуспели в этом деле две фирмы: Dallas (он же MAXIM) и бывшая Seiko (ныне Epson). Далее мы разберем конструкции на основе таких микросхем.

Ну а теперь перейдем непосредственно к конструкции простейших часов, и начнем с выбора подходящего для этой цели МК.

Выбор микроконтроллера и общее построение схемы

Для выбора МК из предлагаемых фирмой Atmel просто подсчитаем, сколько нам требуется выводов. Во-первых, надо управлять четырьмя разрядами индикации (ЧЧ: ММ). Это мы будем делать в режиме динамической индикации, когда в каждый отдельный момент времени напряжение питания подается только на один разряд индикаторов. В это же время на сегменты, которые все соединены между собой параллельно, подается код, соответствующий именно этому разряду. В следующем такте код меняется, а напряжение подается на следующий разряд, и так далее. При четырех разрядах непосредственное управление предполагает 7 х 4 = 28 задействованных выводов, а динамическое— всего 7 + 4 = 11. Чтобы мигание было незаметно для глаза, полный цикл смены разрядов должен повторяться с частотой не менее 70—100 Гц.

Затем нам надо засвечивать разделительный символ — в часах это традиционно двоеточие. Его, конечно, можно засветить постоянно, но лучше, когда оно мигает с не слишком высокой частотой (иногда можно увидеть конструкции, где разделительное двоеточие мигает быстро-быстро — это, конечно, недоработка, оно должно показывать недостающие на дисплее секунды). Наконец, нам надо часы устанавливать. Для этого минимально необходимо две кнопки (включение режима установки и собственно установка). Итого получилось по минимуму 14 выводов.

По тем временам я остановился на МК AT90S2313 — он выпускается в 20-выводном корпусе (см. рис. 12.1 вверху), в котором минимум 5 выводов должно быть занято под системные нужды (два питания, Reset[13] и два вывода для подключения кварца). Итого нам остается на все про все 15 выводов, что нас устраивает. Мы даже вроде бы получаем один резервный вывод, но далее увидим, что на самом деле под все желательные дополнительные функции выводов нам будет не хватать и придется изворачиваться (сейчас я бы, скорее всего, остановился на ATmega8, у которого 28 выводов корпуса, чтобы не экономить, но для изучения особенностей AVR дефицит даже полезнее). Естественно, если вы захотите повторить схему, и не достанете 2313 Classic, то придется заменить его на ATtuny2313, соответствующим образом установив fuse-бит совместимости (см. главу 13). Так как корпус у него тот же самый, то конструкция ничем отличаться не будет.

Теперь общая схема. Выбираем индикаторы большого размера (высота цифр — 1" или 25,4 мм), с общим анодом, т. е. типа SA10, если брать продукцию Kingbright. Лично я предпочитаю желтого свечения (например, SC10-21Y), но это не имеет значения. Так как падение напряжения у них может достигать 4 В, то от того же источника, что требует МК (5 В), питать их нельзя.

Следовательно нам потребуется два напряжения питания: стабилизированное +5 В и нестабилизированное (пусть будет +12 В). Управлять разрядами индикаторов мы будем от транзисторных ключей с преобразованием уровня (когда на выходе МК уровень +5 В, ключ подает +12 В на анод индикатора), а сегменты от простых транзисторных ключей — при уровне +5 В вывод сегмента коммутируется на «землю» (так как питание индикаторов повышенное, то, к сожалению, управлять прямо от выводов процессора не получится). В обоих случаях управление получается в положительной логике: включенному индикатору и сегменту соответствует логическая единица (что совершенно не принципиально, но удобно для простоты понимания работы схемы). Резисторы в управлении сегментами примем равными 470 Ом, тогда пиковый ток через сегмент составит примерно 20 мА, а средний — 5 мА (при динамическом управлении 4-мя разрядами). Всех «восьмерок» у нас быть не может, максимальное число одновременно горящих разрядов равно 24 («20:08»), потому общее максимальное потребление схемы составит 24 х 5 = 120 мА, плюс -10 мА схема управления, итого 130 мА.

Теперь обязательно подумаем о том, чтобы часы продолжали идти при сбоях в электрической сети. Нет ничего ужасней бытового прибора, который не может сохранить установки даже при секундном пропадании напряжения питания, вероятно, вы не раз с такими мучились. Конструкторов, делающих музыкальные центры, магнитофоны, микроволновые печи и электроплиты, в которых часы при малейшем сбое в подаче электроэнергии приходится устанавливать заново, следует расстреливать без суда и следствия.

Режим энергосбережения с глубоким «засыпанием» МК не подходит, поскольку тогда все «замирает» и его применение обессмысливается, ведь нам нужно, чтобы часы не просто сохраняли значение времени, а продолжали идти и при отключении от сети. При питании в пределах 4–5 В МК типа 2313 потребляет около 5 мА, так что можно рассчитывать на непрерывную работу от щелочной («алкалайновой») батарейки типа АА с емкостью порядка 2 Ач в течение не менее 2–3 недель. Для обеспечения работы понадобятся три таких элемента, соединенных последовательно, тогда их общее напряжение составит 4,5 В.

Заметки на полях

В устройствах на специализированных микросхемах RTC можно использовать режимы энергосбережения МК, и дело обстоит значительно лучше: часы идут отдельно до тех пор, пока есть хоть какое-то питание (типичное минимально допустимое значение для RTC — 2 В). В результате при грамотном проектировании можно обеспечить время работы от батарейки в сотни раз большее, чем у нас. Но мы все же пока ограничимся простейшим вариантом — настольные часы и не предназначены для работы в автономном режиме, а для того, чтобы перенести их из комнаты в комнату или «пережить» отключение электричества на пару часов, возможностей нашей системы вполне хватит.

Для обеспечения такого режима нам понадобится монитор питания — схема, которая отслеживает наличие входного напряжения, и переключатель с сетевого питания на батарейки. Чтобы сделать схему совсем «юзабельной», добавим также небольшой узел для сигнализации о необходимости замены резервной батарейки — пусть это будет наше ноу-хау, т. к. в подобных сетевых приборах такого почти ни у кого нет. Хотя есть специальные микросхемы, которые «мониторят» питание, и мы будем их в дальнейшем использовать, здесь в целях максимального упрощения схемы мы без них обойдемся. Схему такого узла удобно реализовать, «не отходя от процессора», на встроенном компараторе. Но тогда нужно задействовать аж 18 выводов (12 под индикацию, 2 кнопки, 2 входа компаратора, 1 для его выхода и еще 1 для монитора питания), а ставить процессор большего размера только для этой цели не хочется. И еще больше не хочется добавлять какие-то внешние схемы — все только потому, что мы захотели контролировать батарейку, которая, может быть, сядет этак лет через пять?

Поэтому мы поступим так: задействуем один из входов компаратора также и под вторую кнопку, как обычный вывод порта. А на второй вход компаратора «повесим» дополнительно функцию монитора— сигнализировать о пропадании внешнего питания. Остается придумать, как обеспечить сигнализацию разряда батареи — тут мы сделаем просто: пусть разделительный символ (двоеточие) мигает, когда все нормально, а когда батарея разряжена — горит все время. Таким образом мы получим наиболее экономичную схему с минимумом внешних элементов.

Теперь поглядим на схему разводки выводов AT90S2313 (рис. 14.1) и выберем, что и к чему мы будем коммутировать.

Рис. 14.1. Разводка выводов МК AT90S2313 (функции показаны применительно к нашей задаче)

Ко входу внешнего прерывания INT1 (7) удобно подключить кнопку, которая будет вводить часы в режим установки. От порта D (портов А и С в этом микроконтроллере нет) осталось шесть разрядов, четыре из которых мы задействуем под управление разрядами индикаторов: PD0 (2), PD1 (3), PD2 (6) и PD4 (8). Из восьми выводов порта В два заняты под входы компаратора AIN+ (выв. 12 — к нему мы подсоединим опорный источник для контроля батареи и также с него будем снимать информацию о состоянии питающего напряжения и второй кнопки) и AIN- (выв. 13 — к нему подключим батарейку). Для управления миганием разделительного двоеточия удобно использовать вывод ОС1 (15), который управляется автоматически от таймера (см. главу 12). Под управление сегментами мы задействуем оставшиеся выводы: PD5 (9), PD6 (11), РВ2 (14) и РВ4—РВ7 (16–19). То, что выводы для управления индикаторами расположены не по порядку — это, конечно, не здорово, нам фактически придется управлять каждым разрядом по отдельности, но обойдемся.

Схема

Вот, собственно, и все предварительные наметки, можно рисовать схему платы управления (рис. 14.2). Схема проста, правда, некоторую громоздкость ей придают ключи управления индикаторами, однако все равно ее можно без труда уместить на плату примерно 70x100 мм, а при некоторых усилиях — и на меньшую.

Рис. 14.2. Схема часов на МК AT90S2313 (плата управления)

Игольчатый разъем XI типа IDС с 10 контактами— программирующий (в главе 13 мы договаривались, что я буду разводить его в соответствии с 10-контактным ISP-программатором, там же подобный разъем описан подробнее, см. рис. 13.4). Все остальные внешние соединения, кроме питания, — через такой же разъем, но с 16 контактами, два из которых— «земля» и питание.

Подробности

Так как игольчатые разъемы типа IDС с шагом 2,54 мм встречаются в практике изготовления микроэлектронных устройств довольно часто, то стоит разобраться в их маркировке. Начнем с того, что наименование IDC в случае штыревых разъемов для установки на плату относится только к разъемам в кожухе с ключом (именно такие используются для подсоединения жесткого диска в ПК). Бескорпусные подобные разъемы носят название PLD для двухрядных (или PLS для однорядных) типов и более удобны в радиолюбительской практике, т. к. длинные разъемы легко «ломаются» в нужном месте, обеспечивая необходимое число выводов (правда, при этом приходится как-то обозначать на плате первый вывод, чтобы не перепутать ориентацию при включении, см. рис. 13.4). Разметка на плате для обоих типов разъемов (с кожухом и без) одинакова, т. к. все равно приходится учитывать место, которое займет кабельная розетка при ее подсоединении, и мы в этой книге для определенности остановимся на IDC-типе. Разумеется, розетка для установки на плоский кабель (с использованием соответствующего инструмента), может иметь только фиксированное число контактов (из ряда 6, 10, 14, 16, 20, 22, 24, 26, 30, 34, 36, 40, 44, 50, 60…), что нужно учитывать при проектировании.

Цифра после обозначения разъема (IDC-10 или PLD-10), естественно, обозначает число контактов разъема, а следующая буква символизирует его конфигурацию: М (male, «папа») для штыревой части, и F (female, «мама») — для гнездовой. Далее может следовать еще одна буква, которая обозначает ориентацию: S для прямых выводов (разъем перпендикулярен плате), R для повернутых под углом 90° (разъем параллелен плате). Таким образом, приведенное на схеме рис. 14.2 обозначение IDC-10MS означает штыревой («папа») разъем в кожухе с ключом, с 10 прямыми выводами. Соответствующая этому разъему кабельная часть обозначится, как IDC-10F. Бескорпусные PLD-разъемы бывают, естественно, только штыревые, потому для них буквы М и F не указываются (а повернутые под углом 90° дополняются буквой R).

Обратите внимание, что программирующие выводы (кроме Reset) здесь работают в двояком режиме. В нормальном режиме эти выводы работают как выходы на достаточно низкоомную (5,1 кОм) нагрузку. Не помешает ли это процессу программирования? Нет, не помешает— такая нагрузка для программатора вполне приемлема. Более того, «чистые» (нигде не задействованные) выводы программирования все равно следует нагружать «подтягивающими» резисторами, иначе не исключены сбои (об этом мы говорили в главе 12). Здесь же роль гасящей помехи нагрузки играют базовые резисторы ключей управления транзисторами, и дополнительные меры не требуются.

Плату индикации делаем отдельно (рис. 14.3). На ней мы располагаем четыре индикатора и две управляющих кнопки (о них далее), а также в точности такой же разъем IDC-16, как и на плате контроллера, причем он должен находиться на стороне платы, противоположной индикаторам. Разводка у него также должна быть идентичной. Эти разъемы мы соединим плоским кабелем.

Рис. 14.3. Схема часов на МК АТ90S2313 (плата индикации)

Изготовить такой плоский кабель с разъемами IDC-16F самостоятельно без специального инструмента практически невозможно, потому либо придется такой инструмент приобрести, либо попросить вам установить разъемы на кабель в любой фирме, которая занимается сборкой и ремонтом компьютеров. Можно употребить и готовый кабель даже с большим числом линий, если на плате установить разъемы PLD (т. е. при отсутствии кожуха). Это решение не очень красивое, т. к. при этом кабельная часть разъема будет выходить за пределы ответной на плате, и это нужно предусмотреть в разводке, иначе большой разъем может во что-нибудь упереться.

Разберем немного работу схемы. При включении питания цепочка 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_х) я предлагаю вам разобраться самостоятельно. Единственный вопрос, который у вас здесь может возникнуть— почему не применить удобный способ непосредственного задания маски рисунков цифр через загрузку констант командой lpm, как я писал в главе 13 — вместо многочисленных «тупых» процедур отдельно для каждой цифры? Дело в том, что маску удобно использовать, если у вас выводы управления разрядами идут подряд (к примеру, когда биты PortD 0–7 соответствуют битам маски 0–7). Тогда маску достаточно «приложить» к регистру порта, и программа резко сокращается. А здесь это сделать нельзя, т. к. «перестраивание» маски под выводы различных портов займет не меньше места, чем простая и понятная прямая установка выводов.

Процедура установки часов работает следующим образом. При коротком нажатии на Кн1 возникает прерывание INT1 (процедура по метке INTT1), в котором первым делом проверяется, есть ли сетевое питание (бит 1 регистра Flag, см. далее), иначе и сама установка не требуется. Далее, как обычно, запрещается само прерывание INT1 во избежание дребезга. Разрешается оно в прерывании Timer 1 (см. начало текста процедуры TIM1), которое, как мы уже знаем, происходит каждую секунду. Таким образом время нечувствительности, в течение которого можно отпустить кнопку без последствий (без перескока на произвольный разряд), составляет случайную величину от 0 до 1 с. На самом это не совсем верное решение, и сделано так только для простоты — следовало бы пропустить одну секунду, и только потом разрешать, иначе вероятность дребезга все-таки остается большой.

Далее в прерывании INT1 устанавливается отдельный счетчик разрядов set_up, который будет считать от 1 до 4 (если он больше, то выходим из режима установки), и признак режима установки (бит 0 регистра Flag). Если этот признак установлен, то разряд, соответствующий установленному номеру в счетчике set_up, будет мигать. Это достигается с помощью вспомогательного счетчика count (см. процедуру TIM1 по метке CONT_1). В этом же месте программы отслеживается состояние Кн2: если она нажата и удерживается, то каждую секунду происходит увеличение значения выбранного разряда на единицу, в тех пределах, в которых это допускается (для единиц минут — от 0 до 9, для десятков минут — от 0 до 5, для десятков часов — от 0 до 2, причем предел единиц часов зависит от значения десятков), далее значение опять обращается в ноль. Отпустив кнопку Кн2, вы фиксируете установленное значение, а нажав кратковременно на Кн1, переходите к следующему разряду. После прохождения всех разрядов, при последнем (пятом) нажатии Кн1, режим установки отменяется, т. е. бит 0 регистра Flag сбрасывается (см. процедуру по прерыванию INT1).

Немаловажная особенность этой конструкции — то, что во время установки счет времени прекращается (команды rjmp END_TIM1 в процедуре TIM1, это было сделано по неопытности, на самом деле там можно было поставить просто reti, но для наглядности я ничего менять не стал), а при выходе из режима установки счетчик секунд устанавливается в состояние 59 (команда ldi sek, 59), т. е. счет сразу же начинается с новой минуты. Окончание установки — довольно важный момент, который можно организовать по-разному, но данный способ самый удобный, т. к. вам достаточно дождаться окончания текущей минуты по образцовым часам, и в этот момент сделать последнее нажатие, выйдя из режима установки, чтобы довольно точно синхронизировать время. Сравните, например, как неудачно выполнена ручная установка часов в Windows, где часы продолжают идти и во время установки. А если бы мы обнуляли счетчик секунд, вместо его установки в максимальное значение, то нам пришлось каждый раз устанавливать число минут на единицу большее, что неудобно.

Теперь об обеспечении режима автономной работы. Программа контроллера в непрерывном цикле опрашивает значение логического уровня на выводе номер 12 PinB,0, он же AIN+ (3,9 В эквивалентно логической единице), и когда оно становится равным нулю, принимает меры к снижению потребления, в первую очередь за счет отключения внешних портов (см. процедуру Disable). Как только внешнее питание восстанавливается, автоматически возобновляется нормальный режим работы (Restore).

При перебрасывании компаратора в любою сторону происходит прерывание ACOMPI. В нем вывод 15 (ОС1) отключается от таймера Timer 1, и устанавливается навсегда в логическую единицу, если состояние компаратора есть логическая единица (когда истощается или отключается батарейка). Тогда двоеточие горит постоянно. И наоборот, вывод этот опять подключается к автоматическому миганию, когда компаратор перебрасывается обратно в ноль.

Детали и конструкция

Для блока питания используем «внутренности» блока со встроенной вилкой, с номинальным напряжением питания 10 В и током не менее 500 мА (такие продаются для некоторых игровых консолей). Напряжение на холостом ходу у него будет составлять примерно 13–14 В, под нагрузкой 130 мА оно сядет как раз примерно до 11–12 В.

В качестве кнопок Кн1 и Кн2 с легким нажатием удобны обычные микропереключатели (известные в отечественном варианте под названием МП-1), но со специальной металлической лапкой-рычагом, которая предназначена для того, чтобы уменьшить усилие нажатия и увеличить его зону (вообще-то такие кнопки предназначены для применения в качестве концевых выключателей). Подойдут импортные кнопки типа SM5 (рис. 14.4). Тогда нам не придется портить внешний вид фальшпанели кнопками или устанавливать их где-то сзади, а можно поставить их прямо на плату индикаторов и просверлить в дымчатом оргстекле напротив них маленькие отверстия, через которые кнопку можно нажимать зубочисткой или другим острым предметом. Чтобы отверстие в оргстекле выглядело «фирменно», сверлить следует осторожно, на малых оборотах, затем вручную сверлом или зенковкой сделать аккуратную фаску с лицевой стороны и обработать отверстие маслом, чтобы оно не белело. Подобное решение еще хорошо тем, что случайное нажатие кнопок — беда почти всех бытовых электронных устройств — совершенно исключено.

Рис. 14.4. Кнопка SM5 с лапкой-рычагом

После изготовления платы индикации сначала следует установить с обратной стороны разъем, а затем «обдуть» лицевую часть платы черной автомобильной эмалью из баллончика, не слишком густо (достаточно одного слоя), чтобы краска не затекла в отверстия. Потом на черную плату уже монтируются индикаторы, светодиоды разделительной точки и кнопки. Светодиоды нужно выбирать, естественно, того же цвета, что и индикаторы. Имейте в виду, что сама по себе характеристика «желтый» или «зеленый» еще ни о чем не говорит, только в табл. 3.1, два зеленых цвета и три красных, а у разных изделий различных фирм их может быть еще больше. И чтобы разница не бросалась в глаза, приготовьтесь к тому, что покупать придется несколько разновидностей и подбирать их оттенок.

Под индикаторы указанного типоразмера 1" подойдут светодиоды диаметром 3 мм, обычные 5-миллиметровые будут слишком выделяться, а под меньшие индикаторы потребуются светодиоды с еще меньшим диаметром. «Суперяркие» светодиоды сюда решительно не годятся. Светодиод при этом желательно иметь с диффузным рассеиванием, чтобы его было одинаково видно со всех углов зрения. Так что вопрос подбора LED может оказаться непростым — в упомянутой конструкции мне так и не удалось сначала подобрать «диффузный» тип, удовлетворяющий всем перечисленным требованиям (они оказались чересчур «лимонного» оттенка), и пришлось устанавливать светодиоды в прозрачном корпусе. Для каждого типа светодиодов придется подобрать резистор R34 (см. рис. 14.2) согласно необходимой яркости (для прозрачных номинал его будет больше, для диффузных— меньше). Устанавливать эту пару диодов следует не прямо друг над другом, а с некоторым наклоном, соответственно наклону цифры индикатора. Неплохо будут также выглядеть прямоугольные (5x2 мм) светодиоды, также под наклоном, только их боковые грани придется закрасить густой черной краской или аккуратно обернуть их качественной липкой лентой.

Я останавливаюсь на всех этих подробностях потому, что они имеют решающее значение для того, будет ли ваша конструкция выглядеть фирменно, или напоминать продукт творчества членов кружка юных техников из деревни Гадюкино. Затрачивать столько сил и средств на конструирование и пренебречь при этом нюансами внешнего вида просто не имеет смысла — если вы, конечно, конструируете бытовой прибор, а не утилитарную схему для рабочих нужд. Но и в последнем случае гораздо приятнее брать в руки аккуратную и удобную в работе конструкцию, а не «голую» плату с болтающимися проводами.

Когда мы соединим платы управления и индикации кабелем и подключим питание, схема заработать сразу не может, потому что нужно запрограммировать МК. Для этого вы должны подключить к разъему XI программатор и загрузить hex-файл с программой. Часы должны «затикать» светодиодами и показать все нули на индикаторах. Потом можно браться за установку времени.

Без сомнения, вы легко сможете доделать эту конструкцию, добавив в нее, к примеру, функции будильника. Причем это можно сделать в принципе даже без переделки схемы, если «повесить» функции установки и включения будильника на те же кнопки, разделив их с простой установкой за счет отсчета времени удержания кнопки (т. е. между нажатием и отпусканием). Сложнее, правда, будет обеспечить выход на «пищалку», но ее можно «повесить» на тот же вывод «мигалки» управления разделительными светодиодами, если при срабатывании будильника заполнять включенное состояние мигалки частотой 2 кГц, предназначенной для управления разрядами — например, переключая с этой частотой вывод ОС1 то на вход, то на выход (при этом в обычном режиме «пищалка» будет еле слышно тикать). Но, разумеется, никто вас не заставляет применять именно МК 2313— возьмите модель 8515, где выводов гораздо больше, и все окажется куда проще. Тем более, что в этом случае можно придумать и еще что-то, например, добавить маленькие разряды секундомера в углу передней панели, а будильник дополнить «милицейской» мигалкой, переключая красный и синий светодиоды попеременно.