Часы с цифровой подстройкой хода.

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

Для управления часами используются 3 кнопки - кнопка выбора режима "mode"; кнопка выбора объекта коррекции "choice"; кнопка изменения объекта коррекции "set".При включении часы находятся в режиме отображения текущего времени (Часы - минуты - секунды). При нажатии на кнопку "mode", часы циклически переходят в режим установки времени, в режим установки будильника и в режим корректировки хода. В режиме установки времени сначала мигают секунды, и если нажать на кнопку "set", то произойдет их обнуление. Если же 1 раз нажать на кнопку "choice", то станут мигать минуты. В этом режиме, при нажатии на кнопку "set" происходит циклическое инкрементирование минут. Если в режиме установки времени 2 раза нажать на кнопку "choice", то появится возможность корректировки часов. При дальнейшем нажатии на кнопку "choice", снова начнут мигать секунды и т.д. В режиме установки будильника, время срабатывания будильника устанавливается точно также, как и в режиме установки времени. Если не мигают ни часы, ни секунды, то нажатием кнопки "set" можно включить или выключить будильник. Если на индикаторе отражается символ "Р", значит будильник включен. В режиме корректировки хода задается количество секунд, на которое часы "убежали" или "отстали" за 1 час. То есть, если за 1 час часы отстали на 2 секунды, то значение калибровочного коэффициента равно 2, а если часы убежали на 3 секунды, то калибровочный коэффициент равен -3. При нажатии на кнопку "set" происходит инкрементирование калибровочного коэффициента, а его максимальное значение равно 30. После 30 калибровочный коэффициент снова сбрасывается в 0, а затем происходит его уменьшение до -30, после чего он снова становится равным нулю.

Принципиальная электрическая схема

Часы основаны на микроконтроллере PIC16F876. В качестве индикатора используется 10-разрядный жк-индикатор с контроллером HT1611. Питание данного индикатора подается на вторую слева (GND) и на крайнюю правую клеммы (+1,5В). Вывод HK (пятая клемма) следует соединить с общим проводом. (Более подробную информацию о данном индикаторе, а также и заказать его, вы можете на сайте фирмы "Телесистемы" - www.telesys.ru.) Питание на индикатор можно подать так, как показано на схеме, т.е. с помощью стабилитрона из 5В получить 1.5В. Однако, такой стабилитрон оказался достаточной редкостью, поэтому вместо него вполне подойдет светодиод (прямое включение, разумеется). Частота кварцевого резонатора рана 9 МГц, поэтому микроконтроллер работает в режиме обычного резонатора (XT).

Блок-схема программы

Рассмотрим работу устройства согласно блок-схеме. Как уже говорилось выше, данная программа - только программа прерываний, т.е. основной программой может быть что угодно. При нажатии одной из кнопок происходит прерывание по порту В, и выполняется соответствующая подпрограмма прерываний. Таймер 2 служит для реализации сигнала будильника. При его переполнении происходит инвертирование сигнала на выводе №13, что и является причиной звучания динамика. Для отсчета времени используется таймер 1. При его переполнении происходит инкрементирование специального регистра REG, при достижении которым определенного числа, текущее время инкрементируется на 1 секунду. После этого происходит подстройка хода часов, в соответствии с введенным коэффициентом. Если включен будильник, то происходит проверка на соответствие текущего времени со временем срабатывания будильника, и если время совпадает, то подается звуковой сигнал. Рассмотрим работу устройства согласно программе в файле clock.asm. В начале программы разрешаются прерывания от PORTB и таймеров 1 и 2, но таймер 2 выключен. Интервал времени в 1 секунду получается следующим образом: Частота тактового генератора = 9МГц. Частота командных циклов = 9/4=2,25МГц, следовательно, за 1 секунду пройдет 2250000 командных циклов. Программа построена таким образом, что при переполнении таймера 1, происходит инкрементирование регистра REG (который состоит из двух регистров REG1 и REG2), а после достижения регистром REG определенного значения, происходит увеличение текущего времени на 1 секунду, т.е. Nt*Nreg=2250000, где Nt - количество циклов до переполнения таймера 1, а Nreg - количество переполнений таймера 1, которое хранится в регистре REG. В данном случае, Nt=3600 (H'0E10'), а Nreg=625. Для этого в таймер 1 надо предварительно записать число H'FFFF'-H'0E10'=H'F1EF'. Однако, следует еще учесть командные циклы, которые пройдут до предварительной записи числа в таймер 1, поэтому записываемое число будет равно H'F1FB'. После того как прошли 2250000 командных цикла происходит прерывание по таймеру 1, т.е. переход на метку "PRER_T1". После этого считываются значения из регистров "T1H" и "T1L" и записываются в регистры таймера 1. Затем инкрементируется регистр "REG". Если он =D'312', следовательно прошло полсекунды, и вызывается п/п "моргания" ("FL_LCD"). Если регистр "REG"=D'625', значит прошла 1 секунда, иначе выход из п/п прерываний. Потом регистр "REG" обнуляется, а в регистры "T1H" и "T1L" записывается начальное значение, а после этого добавляется значение из регистра "CALIBR". Калибровка хода часов получается следующим образом: К предварительно-записываемому числу в таймер 1 прибавляется (или, а зависимости от флага "MINES", отнимается) число из регистра калибровки "CALIBR". Так как в часе 3600 секунд, то получается, что число в регистре "CALIBR" соответствует количеству секунд, на которое часы будут "убегать" или "опаздывать" за час.После этого происходит инкрементирование единиц секунд. Если единицы секунд становятся равными 10 (правый полубайт регистра "SEC"), то они обнуляются и инкрементируются десятки. Если десятки секунд равняются 60, то они тоже обнуляются и инкрементируются единицы минут и т.д. вплоть до десятков часов. После инкрементирования времени на 1 секунду, новое значение следует вывести на индикацию (п/п "LCD_TIME"), однако, если в текущем режиме этого делать не надо (например, режим калибровки или будильника) тогда устанавливается флаг "NOLCD". При этом флаге п/п "LCD_TIME" не работает. Если установлен флаг будульника "RING", то после инкрементирования времени вызывается п/п будильника "ALARM".В ней проверяется соответствие времени будильника и текущего времени. Если эти времена равны, то происходит инвертирование бита включения таймера 2. Т.е.если он включен, то он выключается и наоборот. И так происходит 1 минуту. При переполнении таймера 2 происходит инвертирование сигнала на входе динамика, вследствии чего формируется звуковой сигнал (п/п "ZVUK"). Для того, чтобы во время изменения значений изменяемый объект мигал (секунды, минуты или часы) применяется п/п "FL_LCD". Эта программа вызывается каждый раз, когда значение в регистре REG= H'01,38'=D'312'. Если вводится новое значение, т.е. нажата кнопка "set", то мигать не надо. В начале этой п/п выясняется что должно мигать: текущее время или будильник. Если установлен флаг "FLASH", значит должно мигать текущее время, если флаг "FLASHR" - то будильник. Если должно мигать время, то в регистре CH_R выясняется что конкретно (CH_R =1- коррекция секунд, 2-минут, 3-часов) и соответствующие регистры сбрасываются в 0, и на индикаторе они не отражаются. Затем при прибавлении секунды время отображается полностью, и таким образом происходит мигание объекта коррекции. Если же мигать должен будильник, то предварительно перед "гашением" на дисплей выводится значение будильника, а только потом соответствующие регистры сбрасываются в 0 (регистры, в которых находятся значения часов и минут времени и часов и минут будильника одинаковые). При нажатии на кнопку "mode" происходит прерывание по порту В и вызывается программа "P_MODE". В начале программы инкрементируется регистр "MODE_R". Если этот регистр =1, то вход в режим установки текущего времени и активизируется флаг мигания текущего времени "FLASH". Если регистр "MODE_R"=2, то вызывается п/п отображения будильника. Если регистр "MODE_R"=3, то вызывается п/п калибровки "CALIB". В этой программе значение регистра "CALIBR" преобразуется в bcd и выводится на индикацию. Если же регистр "MODE_R"=4, то он обнуляется и часы входят в режим отображения времени. При нажатии на кнопку "choice" происходит прерывание по порту В и вызывается программа "P_CHOICE". В этой подпрограмме инкрементируется регистр "CH_R". Если идет установка текущего времени, то он начинает инкрементироваться с секунд ("CH_R"=1, метка - "C0"), а если будильника, то с минут ("CH_R"=2, метка - "C10"), ). Если после инкрементирования значение регистра "CH_R">3, то он становится равным 1 (коррекция времени) или 2 (коррекция будильника). При нажатии на кнопку "set" происходит прерывание по порту В и вызывается подпрограмма "P_SET". В начале программы определяется что надо изменять: текущее время ("MODE_R"=1); будильник ("MODE_R"=2); калибровочный коэффициент ("MODE_R"=3) и в соответствие с регистром "MODE_R" осуществляется переход на определенное место п/п "P_SET". Если "MODE_R"=1, то счетчик команд переходит на метку SET1. Затем определяется что конкретно надо корректировать: Если регистр "CH_R"=1, то происходит обнуление секунд. Если "CH_R"=2, то происходит инкрементирование единиц минут. Если единицы минут становятся равными 10, то они обнуляются и инкрементируются десятки. Если десятки минут равняются 60, то они тоже обнуляются. Если "CH_R"=3, то происходит инкрементирование единиц часов. Если единицы часов становятся равными 10, то они обнуляются и инкрементируются десятки. Если десятки часов равняются 60, то они тоже обнуляются. После этого, новое значение времени выводится на индикацию. Тоже самое происходит и при установки времени срабатывания будильника ("MODE_R"=2, метка-"SET10"). Если "MODE_R"=3, то после нажатия кнопки "set" происходит инкрементирование регистра "CALIBR". Если "CALIBR"<30, то выводится новое значение коэффициента калибровки и выход из п/п. Если же "CALIBR"=31, то этот регистр обнуляется и инвертируется флаг "MINES".

В данном архиве (digit_clock.rar) находятся: clock.hex - файл-прошивка для микроконтроллера; clock.asm - файл программы MpLab с подробнейшими комментариями; clock.sch и clock.pcb - соответственно принципиальная схема и печатная плата в формате ACCEL EDA.

Назад