Программа для самодельного ИК-пульта на PIC12F629, протокол RC-5 (манчестерское кодирование)

Программа, рассмотренная в этой статье, разработана специально для самодельного ИК-пульта дистанционного управления на контроллере PIC12F629. Если вы измените аппаратную часть (например, будете использовать другой порядок ног, повесите внешний генератор), то программу также нужно будет переделать.

Прежде чем разбираться с программой, наверное, каждому будет полезно посмотреть описание протокола RC-5.

Алгоритм:

Алгоритм работы самодельного ИК-пульта (протокол RC5)
Алгоритм работы самодельного ИК-пульта (протокол RC5)

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

входы: GP5 — кнопка SB1, GP2 — кнопка SB2, GP4 — кнопка SB3, GP1 — кнопка SB4

выходы: GP0 — вывод информации по протоколу RC-5.

MCLR внешне подтянут к питанию; используется внутренний генератор.

Пусть мы планируем управлять светом, то есть номер системы будет 29.

Текст программы под катом (частота несущей 36 кГц)

 list    p = 12f629
 __config 01FE4h
;*** Переменные ******************************************
  CBLOCK 0x20  ; Начальный адрес блока пользовательской памяти
    T_Cr       ; таймер несущей
    T_NC       ; счетчик количества импульсов в пакете
    T_0        ; таймер интервала между пакетами
    LBC        ; младший байт посылки
    MBC        ; старший байт посылки
  ENDC
;*** Константы / Адреса регистров ************************
  Cr1     equ  .2   ; длительность 1 несущей
  Cr0     equ  .4   ; длительность 0 несущей
  NCr     equ  .32  ; кол-во имп-сов несущей в одном пакете (полбита = 889uS)
  Sys     equ  .29  ; номер системы
  CMD_1   equ  .1   ; код команды 1
  CMD_2   equ  .2   ; код команды 2
  CMD_3   equ  .3   ; код команды 3
  CMD_4   equ  .4   ; код команды 4
  Status  equ  03h  ; Регистр выбора банка
  GPIO    equ  05h  ; Регистр управления защелками порта
  Cmcon   equ  19h  ; Регистр Cmcon - компаратора
  TrisIO  equ  05h  ; Регистр выбора направления работы выводов порта
  INTCON  equ  0Bh  ; Регистр разрешения(1)/запрета(0) прерываний
  OSCCAL  equ  10h  ; Регистр хранения калибровочной константы
  F       equ  1    ; Результат направить в регистр
;********************************************************
 
     org 0 
;*** КОНФИГУРИРОВАНИЕ КОНТРОЛЛЕРА ***********************
;*** Калибровка Генератора ******************************
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  .62      ; Записать конфигурацию GPIO в аккумулятор (W)
                      ; .62=00 111110 GP0 - выход, остальные - входы
      movwf  TrisIO   ; Скопировать конфигурацию GPIO из W в регистр TrisIO
      bcf    Status,5 ; Перейти в 0-й банк
;*** ФОРМИРОВАНИЕ СТАРШЕГО БАЙТА ПАКЕТА *****************
      movlw  Sys
      movwf  MBC      ; запись в старший разряд кода номера системы
      bsf    MBC,6    ; установка стартбита
      bsf    MBC,7    ; установка стартбита
;*** СКАНИРОВАНИЕ КЛАВИАТУРЫ ****************************
Scan  btfss  GPIO,5   ; если на входе GP5 низкий уровень - нажата клавиша 1
      goto   Tx_CMD1
      btfss  GPIO,2   ; если на входе GP2 низкий уровень - нажата клавиша 2
      goto   Tx_CMD2
      btfss  GPIO,4   ; если на входе GP4 низкий уровень - нажата клавиша 3
      goto   Tx_CMD3
      btfss  GPIO,1   ; если на входе GP1 низкий уровень - нажата клавиша 4
      goto   Tx_CMD4
      bsf    MBC,5    ; установить управляющий бит в 1 (первое нажатие)
      goto   Scan
;*** ФОРМИРОВАНИЕ МЛАДШЕГО БАЙТА ПАКЕТА *****************
Tx_CMD1
      movlw  CMD_1
      movwf  LBC      ; запись номера команды 1 в младший разряд кода
      goto   TxRC
;********************************************************
Tx_CMD2
      movlw  CMD_2
      movwf  LBC      ; запись номера команды 2 в младший разряд кода
      goto   TxRC
;********************************************************
Tx_CMD3
      movlw  CMD_3
      movwf  LBC      ; запись номера команды 3 в младший разряд кода
      goto   TxRC
;********************************************************
Tx_CMD4
      movlw  CMD_4
      movwf  LBC      ; запись номера команды 4 в младший разряд кода
      goto   TxRC
;*** ПЕРЕДАЧА ПАКЕТА RC-5 *********************************
TxRC  btfsc  MBC,7    ; Startbit 1. Если он = 1, то выполняется Tx_1,
      call   Tx_1     ; если он равен нулю, то выполняется Tx_0
      btfss  MBC,7    ; аналогично остальные биты
      call   Tx_0
;--------------------------------
      btfsc  MBC,6    ; Startbit 2
      call   Tx_1
      btfss  MBC,6
      call   Tx_0
;--------------------------------
      btfsc  MBC,5    ; Toggle bit
      call   Tx_1
      btfss  MBC,5
      call   Tx_0
;--------------------------------
      btfsc  MBC,4    ; System bit 4
      call   Tx_1
      btfss  MBC,4
      call   Tx_0
;--------------------------------
      btfsc  MBC,3    ; System bit 3
      call   Tx_1
      btfss  MBC,3
      call   Tx_0
;--------------------------------
      btfsc  MBC,2    ; System bit 2
      call   Tx_1
      btfss  MBC,2
      call   Tx_0
;--------------------------------
      btfsc  MBC,1    ; System bit 1
      call   Tx_1
      btfss  MBC,1
      call   Tx_0
;--------------------------------
      btfsc  MBC,0    ; System bit 0
      call   Tx_1
      btfss  MBC,0
      call   Tx_0
;--------------------------------
      btfsc  LBC,5    ; Command bit 5
      call   Tx_1
      btfss  LBC,5
      call   Tx_0
;--------------------------------
      btfsc  LBC,4    ; Command bit 4
      call   Tx_1
      btfss  LBC,4
      call   Tx_0
;--------------------------------
      btfsc  LBC,3    ; Command bit 3
      call   Tx_1
      btfss  LBC,3
      call   Tx_0
;--------------------------------
      btfsc  LBC,2    ; Command bit 2
      call   Tx_1
      btfss  LBC,2
      call   Tx_0
;--------------------------------
      btfsc  LBC,1    ; Command bit 1
      call   Tx_1
      btfss  LBC,1
      call   Tx_0
;--------------------------------
      btfsc  LBC,0    ; Command bit 0
      call   Tx_1
      btfss  LBC,0
      call   Tx_0
      bcf    MBC,5    ; установить управляющий бит в 0 (повторное нажатие)
;*** ПАУЗА, РАВНАЯ МЕЖПАКЕТНОМУ ИНТЕРВАЛУ ***************
;*** Пауза между пакетами равна 50 bit, *****************
;*** т.е. надо послать 100 нулевых полубитов (RCN) ******
      movlw  .99      ; здесь записано 99, а не 100, т.к. далее
                      ; call стоит раньше декремента
      movwf  T_0
pause call   RCN
      decfsz T_0,F    ; декремент T_0
      goto   pause
      goto   Scan
;*** КОНЕЦ ОСНОВНОЙ ПРОГРАММЫ ***************************
;*** ПОДПРОГРАММЫ ПЕРЕДАЧИ НУЛЯ И ЕДИНИЦЫ ***************
;*** Передача нуля манчестерским кодом ******************
Tx_0  call   RCY      ; первые полбита единица
      call   RCN      ; вторые полбита ноль
      return
;*** Передача единицы манчестерским кодом ***************
Tx_1  call   RCN      ; первые полбита ноль
      call   RCY      ; вторые полбита единица
      return
;********************************************************
;*** ПОДПРОГРАММЫ ФОРМИРОВАНИЯ СОСТОЯНИЙ "ON" И "OFF" ***
;*** Передача единичного полубита ("ON") ****************
RCY   movlw  NCr      ; поместить константу NCr в аккумулятор
      movwf  T_NC     ; скопировать содержимое аккумулятора в регистр T_NC
Y_001 movlw  Cr1      ; поместить Cr1 в аккумулятор (изменяя Cr1 и Cr0 можно
                      ; грубо подстраивать частоту несущей)
      movwf  T_Cr     ; поместить содерж.аккум-ра в T_Cr (таймер несущей)
      bsf    GPIO,0   ; установить на выходе GP0 единицу
Cr1_Y decfsz T_Cr,F   ; декремент T_Cr с ветвлением: если f=0 - результат
                      ; сохр-ся в аккум., если f=1 - результат сохр-ся в T_Cr
      goto   Cr1_Y
      nop             ; добавляя еще nop - можно подстр-ть частоту несущей
      bcf     GPIO,0  ; Установить на выходе GP0 ноль
      movlw  Cr0      ; поместить Cr0 в аккумулятор (изменяя Cr1
                      ; и Cr0 можно грубо подстраивать частоту несущей)
      movwf  T_Cr     ; скопировать содержимое аккумулятора в регистр T_Cr
Cr0_Y decfsz T_Cr,F
      goto   Cr0_Y    ; для точной подстройки чатоты несущей
      decfsz T_NC,F
      goto   Y_001
      return
;***** Передача нулевого полубита ("OFF") *******************
RCN   movlw  NCr      ; подпр. передачи 0-го полубита имеет ту же структуру,
      movwf  T_NC     ; что и подпрограмма передачи единичного полубита,
N_001 movlw  Cr1      ; чтобы было легче регулировать их длительности
      movwf  T_Cr
      nop             ; вместо bsf GP0
      nop             ; дополнительно
Cr1_N decfsz T_Cr,F
      goto   Cr1_N
      nop
      nop             ; вместо bсf GP0
      nop             ; дополнительно
      movlw  Cr0
      movwf  T_Cr
Cr0_N decfsz T_Cr,F
      goto   Cr0_N
      decfsz T_NC,F
      goto   N_001
      return
;*********************************************************
end

[свернуть]

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

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

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

Если интересно — можете посмотреть для сравнения аналогичную программу для ATtiny13 (алгоритм абсолютно такой же, отличается только порядок ног).

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