Простейшая программа для устройства дистанционного управления освещением

В этой статье рассмотрена простейшая программа для устройства дистанционного управления освещением на контроллере PIC12F629.

Реализованный в программе алгоритм управления позволяет устройству работать в двух режимах: обычном и дистанционном.

При включении питания (включение света настенным выключателем) контроллер открывает силовой симистор и запитывает лампу. При отключении питания (выключение света настенным выключателем) контроллер и лампа, естественно, обесточиваются. Это, собственно, и есть обычный режим работы, когда дистанционное управление отключено и лампа привычным образом управляется с помощью выключателя. Чтобы перейти в режим дистанционного управления нужно один раз нажать на кнопку нашего девайса. При этом загорается светодиод (индикация режима ДУ).

В режиме ДУ свет будет включаться/выключаться от любого сигнала, любого ИК-пульта. Это не очень удобно, поскольку при этом вы не сможете пользоваться ни одним бытовым прибором с ИК-управлением, одновременно не управляя светом, но во-первых, на то это и простейший алгоритм, а во-вторых, иногда и этого вполне достаточно. Такой девайс подойдёт людям, которым приходится часто вставать посреди ночи, например тем, у кого есть маленькие дети. Просто перед тем как ложиться спать включаете режим дистанционного управления, кладёте рядом пульт и всё. Если же вы хотите ещё и телевизор перед сном посмотреть, то придётся использовать какой-либо более сложный алгоритм. Но, об этом позже, а пока, — не будем отвлекаться.

Поскольку фотоприёмник располагается в непосредственной близости от лампы, то он принимает значительное количество ИК-помех. Для их фильтрации применён цифровой фильтр, основанный на том факте, что в большинстве ИК-протоколов длительность «единицы» более 500 мкс (например, в RC-5 длительность единицы равна 888 мкс, а в NEC — 560 мкс). То есть, если уж мы начали принимать «единицу» по одному из ИК-протоколов, то как минимум 500 мкс у нас этот сигнал будет висеть. В программе используются 4 проверки через каждые 100 мкс, и если во всех случаях сигнал присутствует, то делается вывод о том, что это не помеха, а действительно сигнал с пульта.

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

Алгоритм:

Алгоритм программы устройства управления светом
Алгоритм программы устройства управления светом

Итак, в аппаратной части мы имеем:

входы:
GP2 — приём информации от интегрального фотоприёмника,
GP3 — кнопка

выходы:
GP0 — управление оптосимистором,
GP4 — светодиод

Неиспользуемые ноги микроконтроллера программируем как «выходы», генератор — внутренний

Текст программы под катом

 list    p = 12f629
 __config 01FC4h
;*** Переменные ******************************************
   CBLOCK 0x20   ; Начальный адрес блока пользовательской памяти
      T1
      T2
   ENDC
;**** Константы / Адреса регистров ************************
Status equ   03h       ; выбор банка
Cmcon  equ   19h       ; компаратор (банк 0)
OSCCAL equ   10h       ; хранение калибровочной константы (банк 1)
INTCON equ   0Bh       ; разрешение(1)/запрет(0) прерываний (любой банк)
IOCB   equ   16h       ; регистр разрешения прерываний по GP0...GP5
INDF   equ   0h        ; регистр косвенной адресации
FSR    equ   04h       ; регистр адреса при косвенной адресации
GPIO   equ   05h       ; управление защелками порта (банк 0)
TrisIO equ   05h       ; выбор направления работы выводов порта (банк 1)
;*********************************************************
 
          org 0
            goto start
          org 4
;*********************************************************
;--- Смотрим, откуда прерывание ---
       btfss  GPIO,3      ; если кнопка нажата - проп.следующ.команду
       goto   priem
;--- Инвертировать светодиод ---
knopka movlw  .16         ; 00010000 - маска для инверсии сост-я светодиода
       xorwf  GPIO,1      ; инвертируем состояние светодиода
       goto   exit
;--- Если сигнал с приёмника ---
priem  btfsc  GPIO,2      ; если на входе ILMS ноль - пришёл сигнал
       goto   exit
;--- Проверяем, не помеха ли это ---
       movlw  .4
       movwf  T1          ; кол-во циклов проверки
timer  movlw  .25
       movwf  T2          ; таймер на каждую проверку
time_cikl
       nop
       decfsz T2,1
       goto   time_cikl
       btfsc  GPIO,2      ; если на входе 0 - подтвержд-ся сигнал и проп.выход
       goto   exit
       decfsz T1,1
       goto   timer
;--- Если разрешено, то инвертировать состояние оптрона ---
       btfsc  GPIO,4      ; если светодиод вкл. - пропустить следующ.команду
       goto   exit
       movlw  .1          ; 00000001
       xorwf  GPIO,1      ; после этого выход оптрона инвертируется
exit   call   pause       ; пауза
       bcf    INTCON,0    ; сбросить флаг прерываний
       retfie
;*********************************************************
;*** КОНФИГУРИРОВАНИЕ КОНТРОЛЛЕРА ************************
;****** Калибровка Генератора ****************************
start  bsf    Status,5
       Call   3FFh        ; Загрузить калибровочную константу в w
       movwf  OSCCAL
;*** Установка направления работы ног ********************
       bcf    Status,5    ; перейти в банк 0
       clrf   GPIO        ; инициализация защелок (все выходы равны нулю)
       movlw  .7          ; биты 0..2 поднять
       movwf  Cmcon       ; компарат.выключен, GP0,GP1,GP2 - цифров.вх/вых
       bsf    Status,5    ; Перейти в 1-й банк
       movlw  b'00101100' ; настройка входов/выходов
       movwf  TrisIO
       bcf    Status,5    ; перейти в нулевой банк
;*** Включить оптрон и погасить светодиод ****************
       bsf    GPIO,0      ; поднять нулевой бит (включить свет)
       nop
       bsf    GPIO,4      ; поднять 4-й бит (выключить светодиод)
;*** Разрешить прерывания на входах GP2, GP3 *************
       bsf    Status,5    ; перейти в первый банк
       movlw  .12         ; .12 = 00001100
       movwf  IOCB        ; разрешить прерыв.на GP2, GP3, на остальных - нет
       bcf    Status,5    ; Перейти в 0-й банк
       movlw  .8          ; .8 = 00001000 
       movwf  INTCON      ; разрешить прерывание от GPIO
       bsf    INTCON,7    ; разрешить немаскированные прерывания
;--------------------
work   nop                ; ждём прерывание
       goto   work
;--------------------
pause  movlw  .100
       movwf  T1
cikl1  movlw  .255
       movwf  T2
cikl2  nop
       nop
       decfsz T2,1
       goto   cikl2
       decfsz T1,1
       goto   cikl1
       return
 end
;---------------------------------------------------------

[свернуть]

Скачать готовую прошивку и asm-файл

Внимание. Во избежание затирания калибровочных констант — алгоритм заливки этой прошивки в контроллер следующий:

  1. Считываем текущую конфигурацию контроллера.
  2. Записываем значение битов калибровки схемы BOR (12-й, 13-й биты слова конфигурации, они же bandgap)
  3. Записываем значение последнего слова программного кода (слово по адресу 03FF) — биты калибровки генератора.
  4. Открываем нашу прошивку в программе программатора, и меняем в ней биты калибровки схемы BOR и генератора на считанные и записанные значения.
  5. Всё, теперь эту (исправленную для конкретного экземпляра PIC12) прошивку можно заливать в контроллер.

Update от 24.10.2013

Внимательные читатели заметили, что в программе выключение светодиода делается командой bsf GPIO,4. Почему так, если эта команда подаёт на ногу контроллера высокий уровень? Объясняю. Так получилось из-за того, что при разводке платы оказалось удобнее включить светик не между ногой контроллера и общим проводом (как на схеме), а между плюсом питания и ногой контроллера. В этом случае всё получается наоборот, — чтобы зажечь светодиод — нужно подать на вывод контроллера низкий уровень, а чтобы погасить — высокий.

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