Многофункциональные цифровые часы на микроконтроллере Attmega8. Схема и описание. Простые часы на микроконтроллере Сделать часы микроконтроллере
Предлагаю вашему вниманию электронные часы на микроконтроллере . Схема часов очень проста, содержит минимум деталей, доступна для повторения начинающим радиолюбителям.
Конструкция собрана на микроконтроллере и часов реального времени DS1307 . В качестве индикатора текущего времени использован четырехразрядный семисегментный светодиодный индикатор (ультраяркий, голубого цвета свечения, что неплохо смотрится в темное время, и, заодно, часы играют роль ночника). Управление часами происходит двумя кнопками. Благодаря использованию микросхемы часов реального времени DS1307, алгоритм программы получился довольно простым. Общение микроконтроллера с часами реального времени происходит по шине I2C, и организованно программным путем.
Схема часов:
К сожалению, в схеме есть ошибка:
— выводы МК к базам транзисторов нужно подключать:
РВ0 к Т4, РВ1 к Т3, РВ2 к Т2, РВ3 к Т1
или поменять подключение коллекторов транзисторов к разрядам индикатора:
Т1 к DP1 ….. Т4 к DP4
Детали, используемые в схеме часов:
♦ микроконтроллер ATTiny26:
♦ часы реального времени DS1307:
♦ 4-разрядный семисегментный светодиодный индикатор – FYQ-5641UB -21 с общим катодом (ультраяркий, голубого цвета свечения):
♦ кварц 32,768 кГц, с входной емкостью 12,5 пф (можно взять с материнской платы компьютера), от этого кварца зависит точность хода часов:
♦ все транзисторы — NPN-структуры, можно применить любые (КТ3102, КТ315 и их зарубежные аналоги), я применил ВС547С
♦ микросхемный стабилизатор напряжения типа 7805
♦ все резисторы мощностью 0,125 ватт
♦ полярные конденсаторы на рабочее напряжение не ниже напряжения питания
♦ резервное питание DS1307 – 3 вольтовый литиевый элемент CR2032
Для питания часов можно использовать любое ненужное зарядное устройство сотового телефона (в этом случае, если напряжение на выходе зарядного устройства в пределах 5 вольт ± 0,5 вольта, часть схемы — стабилизатор напряжения на микросхеме типа 7805, можно исключить)
Ток потребления устройством составляет — 30 мА.
Батарейку резервного питания часов DS1307 можно и не ставить, но тогда, при пропадании напряжения в сети, текущее время придется устанавливать заново.
Печатная плата устройства не приводится, конструкция была собрана в корпусе от неисправных механических часов. Светодиод (с частотой мигания 1 Гц, от вывода SQW DS1307) служит для разделения часов и минут на индикаторе.
Установки микроконтроллера заводские: тактовая частота — 1МГц, FUSE-биты трогать не надо.
Алгоритм работы часов
(в Algorithm Builder):
1. Установка указателя стека
2. Настройка таймера Т0:
— частота СК/8
— прерывания по переполнению (при такой предустановленной частоте вызов прерывания происходит каждые 2 миллисекунды)
3. Инициализация портов (выводы РА0-6 и РВ0-3 настраиваются на выход, РА7 и РВ6 на вход)
4. Инициализация шины I2C (выводы РВ4 и РВ5)
5. Проверка 7-го бита (СН) нулевого регистра DS1307
6. Глобальное разрешение прерывания
7. Вход в цикл с проверкой нажатия кнопки
При первом включении, или повторном включении при отсутствии резервного питания DS307, происходит переход в первоначальную установку текущего времени. При этом: кнопка S1 – для установки времени, кнопка S2 – переход к следующему разряду. Установленное время – часы и минуты записываются в DS1307 (секунды устанавливаются в ноль), а также вывод SQW/OUT (7-й вывод) настраивается на генерацию прямоугольных импульсов с частотой 1 Гц.
При нажатии кнопки S2 (S4 — в программе) происходит глобальный запрет прерываний, программа переходит в подпрограмму коррекции времени. При этом, кнопками S1 и S2 устанавливаются десятки и единицы минут, затем, с 0 секунд, нажатием кнопки S2 происходит запись уточненного времени в DS1307, разрешение глобального прерывания и возвращение в основную программу.
Часы показали хорошую точность хода, уход времени за месяц — 3 секунды.
Для улучшения точности хода, кварц рекомендуется подключать к DS1307, как указано в даташите:
Программа написана в среде «Algorithm Builder».
Вы можете, на примере программы часов, ознакомиться с алгоритмом общения микроконтроллера с другими устройствами по шине I2C (в алгоритме подробно прокомментирована каждая строчка).
Фотография собранного устройства и печатная плата в формате.lay от читателя сайта Анатолия Пильгук, за что ему огромное спасибо!
В устройстве применены: Транзисторы — СМД ВС847 и ЧИП резисторы
Приложения к статье:
(42,9 KiB, 3 233 hits)
(6,3 KiB, 4 183 hits)
(3,1 KiB, 2 662 hits)
(312,1 KiB, 5 932 hits)
Второй вариант программы часов в АБ (для тех у кого нескачивается верхний)
(11,4 KiB, 1 947 hits)
Недавно спаял схему электронных часов с будильником, выполненных на популярном среди радиолюбителей . В них используется светодиодный индикатор для отображения времени. Мне надоели всевозможные ЖКИ и хочется иметь возможность видеть время из любой точки комнаты в том числе в темноте, а не только прямо с хорошим освещением. Схема содержит минимум деталей и имеет отличную повторяемость.
Схема электронных часов на микроконтроллере
Микроконтроллер является единственной микросхемой, используемой в данном устройстве. Для задания тактовой частоты используется кварцевый резонатор на 4 МГц. Для отображения времени использованы индикаторы красного цвета с общим анодом, каждый индикатор состоит из двух цифр с десятичными точками. Можно применить любые индикаторы с общим анодом, лишь бы каждая цифра имела собственный анод. Чтоб электронные часы были хорошо видны в темноте и с большой дистанции - старайтесь выбрать АЛС-ки чем покрупнее.
Индикация в часах осуществляется динамически. В данный конкретный момент времени отображается лишь одна цифра, что позволяет значительно снизить потребление тока. Аноды каждой цифры управляются микроконтроллером PIC16F628. Сегменты всех четырех цифр соединены вместе и через токоограничивающие резисторы R1 … R8 подключены к выводам порта МК. Поскольку засвечивание индикатора происходит очень быстро, мерцание цифр становится незаметным.
Для настройки минут, часов и будильника - используются кнопки без фиксации. В качестве выхода для сигнала будильника используется вывод 10, а в качестве усилителя - каскад на транзисторах VT1,2. Звукоизлучателем является пьезоэлемент типа ЗП. Для улучшения громкости вместо него можно поставить небольшой динамик. Питаются часы от стабилизированного источника напряжением 5 вольт. В часах реализовано 9 режимов индикации. Переход по режимам осуществляется кнопками "+" и "-". Перед выводом на индикацию самих показаний, на индикаторы выводится короткая подсказка названия режима. Длительность вывода подсказки примерно секунда.
Кнопкой "Коррекция " часы переводятся в режим настроек. При этом кратковременная подсказка выводится на пол секунды, после чего корректируемое значение начинает мигать. Коррекция показаний осуществляется кнопками "+" и "-". При длительном нажатии на кнопку, включается режим автоповтора, с заданной частотой. Все значения, кроме часов, минут и секунд, записываются в память и восстанавливаются после выключения питания. Если в течение нескольких секунд ни одна из кнопок не нажата, то электронные часы переходят в режим отображения времени. Нажатием на кнопку "Вкл/Выкл " включается или выключается будильник, это действие подтверждается коротким звуком. При включенном будильнике светится точка в младшем разряде индикатора. Вот прошивка и рисунок платы часов.
Урок 23
Часть 1
Собираем часы на DS1307 и LED индикаторе
Сегодня мы продолжим нашу работу с микросхемой, являющейся часами реального времени, начатую в , и , и попробуем теперь собрать на ней часы с применением не жидкокристаллического индикатора, а с применение индикатора светодиодного четырёхразрядного работающего по принципу динамической индикации. Всё мы это с вами проходили, индикацию также проходили, подобный индикатор подключали в , поэтому нам будет не так сложно это реализовать.
Но, несмотря на все наши знания урок не обещает быть коротким, а наоборот будет очень обширным, так как сборка часов на таких индикаторах требует решение очень многих дополнительных задач особенно потому, что у нас не 32 знакоместа, как на нашем LCD, а всего 4 и точка или двоеточие. И все показания надо выводить будет в порядке определённой очереди, а также потребует от нас умения организовать изменение показаний (перевода) с помощью кнопок, а может быть вообще с помощью одной только кнопки в рамках использования всего четырех цифр.
Но мы не боимся трудностей, с ними даже интереснее.
Поэтому начнём что-нибудь выдумывать.
Индикатор будет вот такого вот типа, из них именно типа с общим анода
А вот так индикатор выглядит вживую
Судя по клеточкам размером 5 милиметров несложно оценить его размеры.
Вот его вид с обратной стороны
Также у меня есть ещё один индикатор меньшим размером, но по распиновке точь в точь такой же как и предыдущий. То есть я просто вынимаю из макетной платы и вставляю в него другой, и всё работает.
Вот они оба для сравнения
Вот маркировка маленького индикатора
Также мы можем использовать раздельные индикаторы для каждой цифры, подключив их соответствующим образом, результат будет тот же. Данный тип подключения обычно используется, когда требуются часы с большими цифрами и тяжело найти совмещённый индикатор больших размеров. Способ подключения наглядно демонстрируеся в нашей схеме в протеусе, так как я нашёл в протеусе и совмещённый индикатор, но он у меня, почему-то должным образом не заработал (нажмите на картинку для увеличения изображения)
Данную схему мы хорошо помним из урока по . Только там было всего 2 индикатора, поэтому подключим ещё два, также будут использованы ещё два транзисторных ключа, на базу которых пойдут команды через токоограничивающие резистора на 2 килоома от ножек портов PB2 и PB4 . Третью ножку порта B мы пропустим в целях её дальнейшего использования в другом альтернативном качестве, в качестве ножки аппаратного ШИМ для регулировки яркости свечения индикатора.
Создадим проект с именем MyClock1307LED , а код весь в главный модуль возьмём как раз из урока по динамической индикации, из проекта Test08 . В ту пору у нас пока не было модульного программирования и весь полезный код содержался в одном главном модуле.
Для начала соберём наш проект, подключим контроллер и его прошьём и посмотрим для интереса результат работы кода
Мы видим что два правых индикатора у нас нормально работают. Но нам нужно четыре.
Для начала для этого мы добавим ещё две переменные для двух неиспользуемых разрядов
unsigned int i ;
unsigned char R1 =0, R2 =0, R3 =0, R4 =0 ; //цифры разрядов индикатора
Объявим ещё соответствующие данным анодам ножки порта на выход в функции port_ini(), также включая и ножку для ШИМ
DDRB = 0b000111 11;
Также добавим код в функцию ledprint
void ledprint ( unsigned int number )
R1 = number %10;
R2 = number %100/10;
R3 = number %1000/100;
R4 = number /1000;
У нас тут ещё вычисляется результат цифр недостающих, так же во втором разряде произошли некоторые изменения в силу того. что он теперь не последний, и надо сотни и тысячи отбросить.
Переменные мы рассчитали, осталось их как-то отобразить на индикаторе.
Для этого мы изменим код в обработчике прерывания от таймера
ISR ( TIMER1_COMPA_vect )
if ( n_count ==0) { PORTB &=~(1<< PORTB0 ); PORTB |=(1<< PORTB1 )|(1<< PORTB2 )|(1<< PORTB4 ); segchar ( R1 );}
if ( n_count ==1) { PORTB &=~(1<< PORTB1 ); PORTB |=(1<< PORTB0 )|(1<< PORTB2 )|(1<< PORTB4 ); segchar ( R2 );}
if ( n_count ==2) { PORTB &=~(1<< PORTB2 ); PORTB |=(1<< PORTB0 )|(1<< PORTB1 )|(1<< PORTB4 ); segchar ( R3 );}
if ( n_count ==3) { PORTB &=~(1<< PORTB4 ); PORTB |=(1<< PORTB0 )|(1<< PORTB1 )|(1<< PORTB2 ); segchar ( R4 );}
N_count ++;
If ( n_count >3 ) n_count =0;
Тут, я думаю также всё понятно, мы подаём логический ноль на ключевой транзистор нужного нам разряда, так как мы знаем, что ключи у нас инверсные и с другой строны будет единица, а также подаём логические единицы на ключевые транзисторы тех разрядов, которые в данный момент светиться не должны, также мы считаем не до одного, а до трёх.
С этим всё.
Но, так как у нас теперь количество индикаторов увеличилось, теперь очередь до того же индикатора доходит позже, то есть скорость обнолвения показаний одного индикатора у нас упала, и мы должны немного перенастроить таймер. Как это делать, нас учить не надо
OCR1AH = 0b00001111 ; //записываем в регистр число для сравнения
OCR1AL =0b01000010 ;
Ну и сделаем возможность нашему счётчику считать не до 99, а до 9999 для этого в цикле мы напишем не 100, а 10000
for ( i =0; i < 10000 ; i ++)
И также уменьшим задержку, иначе с такой скоростью мы четвёртой цифры долго не дождёмся
Delay_ms (10 );
Соберём код, прошьём контроллер и посмотрим результат нашей работы
Вот теперь другое дело. У нас теперь есть рабочий код для организации динамической индикации четырёхразрядного динамического индикатора, поэтому в следующей части нашего занятия нам к этому вопросу уже больше возвращаться не придется.
5 542Иногда полезно иметь в системе часы отсчитывающие время в секундах, да еще с высокой точностью. Часто для этих целей применяют специальные микросехмы RTC (Real Time Clock) вроде . Вот только это дополнительный корпус, да и стоит она порой как сам МК, хотя можно обойтись и без нее. Тем более, что многие МК имеют встроенный блок RTC. В AVR его правда нет, но там есть асинхронный таймер, служащий полуфабрикатом для изготовления часиков.
Первым делом нам нужен часовой кварц на 32768Герц.
Почему кварц именно 32768Гц и почему его зовут часовым? Да все очень просто — 32768 является степенью двойки. Два в пятнадцатой степени. Поэтому пятнадцати разрядный счетчик, тикающий с частотой 32768 Гц, будет переполняться раз в секунду. Это дает возможность строить часы на обычной логической рассыпухе без каких либо заморочек. А в микроконтроллере AVR организовать часы с секундами можно почти без использования мозга, на рефлексах периферии.
Асинхронный режим таймера
Помните как работают таймеры? Тактовая частота с основного тактового генератора (RC внешняя или внутренняя, внешний кварц или внешний генератор) поступает на предделители, а с выхода предделителей уже щелкает значениями регистра TCNT. Либо сигнал на вход идет с счетного входа Тn и также щелкает регистром TCNT
Для этого на выводы TOSC2 и TOSC1 вешается кварцевый резонатор. Низкочастотный, обычно это часовой кварц на 32768Гц. На он смонтирован справа от контроллера и подключается перемычками. Причем тактовая частота процессора должна быть выше как минимум в четыре раза. У нас тактовая от внутреннего генератора 8Мгц, так что нас это условие вообще не парит:)
И не нужно высчитывать количество тактов основного кварца, а если его нет, то заморачиваться на плавающую частоту встроенного RC генератора. Часовой кварц имеет куда более компактные размеры чем обычный кварц, да и стоит дешевле.
Также немаловажным является тот факт, что асинхронный таймер может тикать сам по себе, от часового кварца, ведь тактовая частота процессора ему не нужна, а это значит тактирование ядра контроллера (самое жручее, что у него есть) можно отключить, загнав процессор в спячку, существенно снизив потребление энергии и просыпаясь только по переполнению таймера (1-2 раза в секунду), чтобы записать новые показания времени.
Конфигурирование
Для включения надо всего лишь установить бит AS2 регистра ASSR — и все, таймер работает в асинхронном режиме. Но есть тут одна фича которая мне стоила много головняков в свое время. Дело в том, что при работе от своего кварца все внутренние регистры таймера начинают синхронизироваться по своему же кварцу. А он медленный и основная программа может менять уже введенное значение гораздо быстрей чем оно обработается таймером.
Т.е., например, предустановил ты значение TCNT2, таймер на своей 32кгц молотилке его еще даже прожевать не успел, а твой алгоритм уже пробежал и снова туда что то записал — в результате в TCNT2 наверняка попадет мусор. Чтобы этого не случилось запись буфферизируется. Т.е. это ты думаешь, что записал данные в TCNT2, но на самом деле они попадают во временный регистр и в счетный попадут только через три такта медленного генератора.
Также буфферизируется регистры сравнения OCR2 и регистр конфигурации TCCR2
Как узнать данные уже внеслись в таймер или висят в промежуточных ячейках? Да очень просто — по флагам в регистре ASSR. Это биты TCN2UB, OCR2UB и TCR2UB — каждый отвечает за свой регистр. Когда мы, например, записываем значение в TCNT2 то TCNUB становится 1, а как только наше число из промежуточного регистра таки перешло в реальный счетный регистр TCNT2 и начало уже тикать, то этот флаг автоматом сбрасывается.
Таким образом, в асинхронном режиме, при записи в регистры TCNT2, OCR2 и TCCR2 сначала нужно проверять флаги TCN2UB, OCR2UB и TCR2UB и запись проводить только если они равны нулю. Иначе результат может быть непредсказуемым.
Да, еще один важный момент — при переключениях между синхронным и асинхронным режимом значение в счетном регистре TCNT может побиться. Так что для надежности переключаемся так:
- Запрещаем прерывания от этого таймера
- Переключаемся в нужный режим (синхронный или асинхронный)
- Заново настраиваем таймер как нам нужно. Т.е. выставляем предустановку TCNT2 если надо, заново настраиваем TCCR2
- Если переключаемся в асинхронный режим, то ждем пока все флаги TCN2UB, OCR2UB и TCR2UB будут сброшены. Т.е. настройки применились и готовы к работе.
- Сбрасываем флаги прерываний таймера/счетчика. Т.к. при всех этих пертурбациях они могут случайно установиться
- Разрешаем прерывания от этого таймера
Несоблюдение этой последовательности ведет к непредсказуемым и трудно обнаруживаемым глюкам.
Спящие режимы и асинхронный таймер
Т.к. асинхронный таймер часто используется в разных сберегающих режимах, то тут возникает одна особенность, раскладывающая целое поле из граблей.
Суть в том, что таймер, работающий от медленного кварца, не успевает за главным процессором, а в том дофига зависимостей от периферии — те же прерывания, например. И когда проц спит, то эти зависимости не могут реализоваться, в результате возникают глюки вроде неработающих прерываний или поврежденных значений в регистрах. Так что логика работы с асинхронным таймером и спящим режимом должна быть построена таким образом, чтобы между пробуждением и сваливаеним в спячку асинхронный таймер успел отработать несколько своих тактов и выполнил все свои дела.
Примеры:
Контроллер использует режим энергосбережения и отключения ядра, а пробуждается по прерываниям от асинхронного таймера. Тут надо учитывать тот факт, что если мы будем изменять значения регистров TCNT2, OCR2 и TCCR2, то уход в спячку нужно делат ТОЛЬКО после того, как флаги TCN2UB, OCR2UB и TCR2UB упадут. Иначе получится такая лажа — асинхронный таймер еще не успел забрать данные из промежуточных регистров (он же медленный, в сотни раз медленней ядра), а ядро уже отрубилось. И ладно бы конфигурация новая не применилась, это ерунда.
Хуже то, что на время модификаций регистров TCNT или OCR блокируется работа блока сравнения, а значит если ядро уснет раньше, то блок сравнения так и не запустится — некому его включить будет. И у нас пропадет прерывание по сравнению. Что черевато тем, что событие мы прошляпим и будем их терять до следующего пробуждения из спячки.
А если контроллер будится прерыванием по сравнению? То он уснет окончательно. Опаньки!
Вот и лови такой глюк потом.
Так что перед уходом в режимы энергосбережения надо обязательно дать асинхронному таймеру прожевать введенные значения (если они были введены) и дождаться обнуления флагов.
Еще один прикол с асинхронным режимом и энергосбережением заключается в том, что подсистема прерываний при выходе из спячки стартует за 1 такт медленного генератора. Так что даже если мы ничего не меняли, то обратно в спячку сваливаться нельзя — не проснемся, т.к. прерывания не успеют запуститься.
Так что выход из спячки и засыпание по прерыванию асинхронного таймера должно быть в таком виде:
- Проснулись
- Что то сделали нужное
- Заснули
И длительность операции между Проснулись и Заснули НЕ ДОЛЖНА БЫТЬ МЕНЬШЕ чем один тик асинхронного таймера. Иначе анабиоз будет вечным. Можешь delay поставить, а можешь сделать как даташит советует:
- Проснулись
- Что то сделали нужное
- Ради прикола записали что то в любой из буфферизиуемых регистров. Например, в TCNT было 1, а мы еще раз 1 записали. Ничего не изменилось, но произошла запись, поднялся флаг TCN2UB который продержится гарантированно три такта медленного генератора.
- Подождали пока флаг упадет
- Уснули.
Также не рекомендуется при выходе из спячки сразу же читать значения TCNT — можно считать лажу. Лучше подождать один тик асинхронного таймера. Или сделать прикол с записью в регистр и ожиданием пока флаг спадет, как было написано выше.
Ну и последний, но важный, момент — после подачи питания, или выхода из глубокой спячки, с отключением не только ядра, а вообще всей периферии, пользоваться медленным генератором настоятельно рекомендуется не раньше чем через 1 секунду (не миллисекунду, а целая секунда!). Иначе генератор может еще быть нестабильным и в регистрах будет еще каша и мусор.
И, в завершение статьи, небольшой примерчик. Запуск асинхронного таймера на Atmega16 (Как полигон используется плата )
Проект типовой, на базе диспетчера, одно лишь отличие — диспечтер переброшен на таймер0, чтобы освободить таймер2.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | int main(void ) { InitAll() ; // Инициализируем периферию InitRTOS() ; // Инициализируем ядро RunRTOS() ; // Старт ядра. UDR = "R" ; // Маркер старта, для отладки SetTimerTask(InitASS_Timer, 1000 ) ; // Так как таймер в асинхронном режиме // запускается медленно, то делаем // Выдержку для запуска инициализации таймера. while (1 ) // Главный цикл диспетчера { wdt_reset() ; // Сброс собачьего таймера TaskManager() ; // Вызов диспетчера } return 0 ; } |
int main(void) { InitAll(); // Инициализируем периферию InitRTOS(); // Инициализируем ядро RunRTOS(); // Старт ядра. UDR = "R"; // Маркер старта, для отладки SetTimerTask(InitASS_Timer,1000); // Так как таймер в асинхронном режиме // запускается медленно, то делаем // Выдержку для запуска инициализации таймера. while(1) // Главный цикл диспетчера { wdt_reset(); // Сброс собачьего таймера TaskManager(); // Вызов диспетчера } return 0; }
Сама процедура инициализации таймера в асинхронном режиме сделана в виде конечного автомата. При первом запуске она взводит бит асинхронного режима и делает приготовления, после запускает сама себя снова же, через диспетчер, чтобы дать возможность еще чему либо проскочить в очереди, не блокируюя систему на ожидание.
При последующих входах проверяются флаговые биты готовности регистров таймера. Если они все по нулям, то мы на всякий случай зануляем флаги прерывания таймера, чтобы не было глюков и ложных срабатываний, а потом разрешаем нужное нам прерывание. И выходим.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | void InitASS_Timer(void ) { if (ASSR & (1 << AS2) ) //Если это второй вход то { if (ASSR & (1 << TCN2UB | 1 << OCR2UB | TCR2UB) ) // проверяем есть ли хоть один бит флаговый { SetTask(InitASS_Timer) ; // Если есть, то отправляем на повторный цикл ожидания } else // Если все чисто, то можно запускать прерывания { TIFR |= 1 << OCF2 | 1 << TOV2; // Сбрасываем флаги прерываний, на всякий случай. TIMSK |= 1 << TOIE2; // Разрешаем прерывание по переполнению return ; } } TIMSK &= ~(1 << OCIE2 | 1 << TOIE2) ; // Запрещаем прерывания таймера 2 ASSR = 1 << AS2; // Включаем асинхронный режим TCNT2 = 0 ; TCCR2 = 5 << CS20; // Предделитель на 128 на 32768 даст 256 тиков в секунду // Что даст 1 прерывание по переполнению в секунду. SetTask(InitASS_Timer) ; // Прогоняем через диспетчер, чтобы зайти снова. } |
void InitASS_Timer(void)
{
if(ASSR & (1< ISR(TIMER2_OVF_vect) // Прерырвание по переполнению таймера 2
{
UDR = i;
i++;
} Можно было сделать переменные содержащие часы:минуты:секунды и щелкать этими переменными со всей их логикой переполнения часов/минут, но мне было лень. И так все понятно. Эта схема была опубликована еще в 2008 году, на сайте
http://radiokot.ru/circuit/digital/home/33/ , и не смотря на явные
схемотехнические ошибки - схема работает, многие за это время ее повторили,
там же на сайте есть большая тема форума, где обсуждается это устройство.
Кроме авторскйо прошивки, на форуме есть еще наборы прошивок. В том числе
и для вариантов схемы при использовании различных индикаторов, как с собщим
катодом, так и с общим анодом. Архив с проверенными прошивками и их исходными
текстами в конце страницы.
Я вспомнил об этой схеме, когда мне потребовались простые "первичные часы".
Схема была повторена в точности, с единственным изменением - вместо индикатора
установлен разъем, к которому будет подключаться силовая часть "больших часов".
Для того, чтобы убедиться в том, что часы работают - подключен первый,
попавшийся под руку индикатор: XYLNH 420401B-0 - понятия не имею что эта
надпись на корпусе означает, но индикатор по распиновке полностью совпадает с
рекомендуемым авторм индикатором CC56-12SRWA, только синего свечения.
Управление часами очень простое: Кнопкой S2 устанавливают минуты,
а кнопкой S3 - часы. Кнопка сброс (S1), позволяет установить время на полночь,
иногда бывает полезно, хотя ее можно не устанавливать. Точка, разделяющая часы
и минуты, моргает с частотой 1,25 Гц, то есть 0,4 секунды горит, 0,4 сек. нет.
В целом - схема работает. Но, если предполагается использовать ее так как она
есть, то я бы все-таки посоветовал увеличил сопротивление резисторов R4-R11 до,
хотя бы 330 Ом, и поставил бы транзисторы в цепь управления катодами.
ATtini2313 процессор конечно живучий, но думаю не следует его мучать в таком
режиме.
И пару слов о программировании МК. Я использовал программатор
Программатор AVR ISP mkII
с программой AVRDUDE_PROG 3.2