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

Недавно мне родители поставили задачу — сделать ночник (нечто между настольной лампой и фонариком, если вдруг кто — то не знает что это). В связи с временным переездом с деталями пока что напряженка, так что собирал буквально из того что смог найти. В итоге получилась такая схема (проект создан в программе 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-битPIC12F6291
DIP8Q1-Q3
Биполярный транзисторКТ315А3
Любой маломощныйD1-D3
СветодиодLED3
Любой, подходящий по яркости и токуC1, C2
Конденсатор33 пФ2
0805R1-R3
Резистор220 Ом3
Мощность зависит от светодиодовR4
Резистор2.2 кОм1
+/- 20%PB1
КнопкаPB11
Лобая, подходящая по габаритамX1
Кварцевый резонатор12 МГц1
Желательно низкопрофильныйДобавить все

Скачать список элементов (PDF)

Прикрепленные файлы:

Добавить комментарий

Ваш адрес email не будет опубликован.