Ночник на микроконтроллере

Недавно мне родители поставили задачу — сделать ночник (нечто между настольной лампой и фонариком, если вдруг кто — то не знает что это). В связи с временным переездом с деталями пока что напряженка, так что собирал буквально из того что смог найти. В итоге получилась такая схема (проект создан в программе Proteus 8.1):

Схема ночника на микроконтроллере 
Рис. 1

Как видите основа — микроконтроллер PIC12F629. Для управления светодиодами пришлось использовать транзисторные ключи, а для стабильности генератора — кварцевый резонатор на 12 МГц.

Устройство обладает следующими характеристиками:

  • Напряжение питания 5 В.
  • Ток потребления (не учитывая светодиоды ) < 10мА
  • Для управления светодиодами используется ШИМ
  • Время полного отключения — 30 минут

Управление устройством предельно простое: подал питание — светодиоды плавно включились. Причем светодиоды (а их, как вы заметили, 3) выключаются по очереди. Соответственно сначала плавно гаснет первый, потом 2-й и 3-й, с интервалом в 10 минут. Кнопка служит для программного перезапуска (я посчитал что использовать аппаратный «reset» будет не правильно, к тому же в будущем еще хочу добавить на эту кнопку функций).

Что касается печатной платы, то оказалось, что в данном случае будет достаточно и односторонней разводки. Вот что вышло:

Плата ночника
Рис. 2

Размеры платы 40х45 мм. Если использовать все компоненты в smd исполнении, то можно значительно сократить размеры платы.

И наконец «слово» о программе. Программа для микроконтроллера писалась в среде mikroPascal for PIC (версия 6.4).

Исходный код:

 program NightLamp;  var count, systime, ctime: integer;     tp1, tp2, tp3, e1, e2, e3, startup: byte;  label but1;  procedure Interrupt; begin      inc(systime); //////////////////////////////////////////////////////////////////////////////// Эта часть программы отвечает за плавное зажигание светодиодов при старте.      if startup = 1 then begin         if systime >= 1171 then begin            systime := 0;            dec(tp1);            dec(tp2);            dec(tp3);            if tp1 = 1 then startup := 0;         end;      end else begin //////////////////////////////////////////////////////////////////////////////// Здесь происходит плавное гашение светодиодов          if systime >= 11718 then begin             systime := 0;             inc(ctime);             if e1 = 1 then begin                inc(tp1);                if tp1 = 99 then e1 := 0;             end;             if e2 = 1 then begin                inc(tp2);                if tp2 = 99 then e2 := 0;             end;             if e3 = 1 then begin                inc(tp3);                if tp3 = 99 then e3 := 0;             end;         end;      end; //////////////////////////////////////////////////////////////////////////////// Проверка на предмет совпадения прошедшего и установленноговремени, запуск цикла выключения светодиодов.      if ctime = 500 then e1 := 1 else      if ctime = 1100 then e2 := 1 else      if ctime = 1500 then e3 := 1; //////////////////////////////////////////////////////////////////////////////// Собственно сам программны ШИМ.      if count <= 100 - tp1 then GP0_bit := 1 else GP0_bit := 0;      if count <= 100 - tp2 then GP1_bit := 1 else GP1_bit := 0;      if count <= 100 - tp3 then GP2_bit := 1 else GP2_bit := 0;      if count >= 100 then count := 0;      inc(count); //////////////////////////////////////////////////////////////////////////////// Сбрасываем флаг прерывания Т0.      INTCON.T0IF := 0; end;  begin CMCON := 0x7;                                                                   // Отключаем копаратор. OPTION_REG := 0x8;                                                              // Конфигурация Т0. INTCON := 0xA0;                                                                 // Конфигурация прерываний. TRISIO := 0x8;                                                                  // Конфигурация порта. GPIO := 0x0;                                                                    //  INTCON.T0IE := 1; startup := 1; tp1 := 99; tp2 := 99; tp3 := 99; While TRUE do begin       if Button(GPIO, 3, 10, 0) then begin                                      // Проверка, нажата ликнопка. Если нажата, то выполнение действий по отпусканию.          but1:          if Button(GPIO, 3, 10, 0) then goto but1 else begin             tp1 := 99;             tp2 := 99;             tp3 := 99;             ////////////////////////////////////////////////////////////////////             count := 0;             ctime := 0;             systime := 0;             ////////////////////////////////////////////////////////////////////             startup := 1;          end;       end; end; end.

Практически все действия в программе «завязаны» на таймере T0. Это связано не столько с «экономией» энергии, сколько с тем, что мне было лень возиться с таймером T1.

Так как микроконтроллер работает на частоте 12МГц, то при выключенном предделителе Т0 (просто переключаем его от Т0 к WDT) и условии что таймер 8-ми битный последний будет переполняться 12000000/(4*256) = 11718 раз в секунду. По этому для отсчета времени было использовано 2 переменные типа «integer». В первую записывается количество переполнений Т0,а во вторую — непосредственно прошедшее время, в секундах.

Дальше все просто — считаем нужное количество секунд и включаем / выключаем светодиод.

Что касается ШИМа — то он программный. Частота импульсов ~117 Гц (шаг 0 — 100). Вообще — то прямоугольные импульсы, генерируемые микроконтроллером, следуют с частотой 11 кГц, но с учетом необходимости регулирования длительности импульса и паузы, получаем всего 117 Гц. Но, на практике и такой частоты достаточно. Мерцания светодиодов не видно.

Так для микроконтроллеров PIC конфигурация (выбор генератора, WDT и т.п.) находится в .hex файле, то скриншот с выставлением фузов приводить не буду. К слову, для прошивки микроконтроллера использовал программу WinPic800 и программатор JDM.

Теперь коротко о возможной замене деталей:
Транзисторы можно использовать любые маломощные структуры NPN. У меня кроме КТ315 под рукой ничего не было, по-этому «в бой пошли одни старики». Микроконтроллер заменить на более «старший» 12F675 или 12F683 нельзя. Светодиоды можно использовать любые (только не забывайте про ток).

Ну и напоследок сравнение ожидаемого и действительного.

Модель
Рис. 4

Реальность
Рис. 5

Еще фото
Рис. 6


Рис. 7


Рис. 8

А вот фотография устройства после замены светодиодов на белые.


Рис. 9

И небольшое видео, демонстрирующее работу девайса.

Список радиоэлементов

Обозначение Тип Номинал Количество Примечание Магазин Мой блокнот
U1 МК PIC 8-бит PIC12F629 1 DIP8
Q1-Q3 Биполярный транзистор КТ315А 3 Любой маломощный
D1-D3 Светодиод LED 3 Любой, подходящий по яркости и току
C1, C2 Конденсатор 33 пФ 2 0805
R1-R3 Резистор 220 Ом 3 Мощность зависит от светодиодов
R4 Резистор 2.2 кОм 1 +/- 20%
PB1 Кнопка PB1 1 Лобая, подходящая по габаритам
X1 Кварцевый резонатор 12 МГц 1 Желательно низкопрофильный