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

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

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

Алгоритм:

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

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

входы: PB4 — кнопка SB1, PB2 — кнопка SB2, PB0 — кнопка SB3, PB1 — кнопка SB4

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

RESET внешне подтянут к питанию; используется внутренний генератор на 9,6 МГц.

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

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

 .device ATtiny13
 .include "tn13def.inc"
 .list
;--- определяем свои переменные
 .def  w=r16     ; это будет наш аккумулятор
 .def  T_Cr=r17  ; таймер несущей
 .def  T_NC=r18  ; счётчик кол-ва импульсов в пакете
 .def  T_0=r19   ; таймер интервала между пакетами
 .def  LBC=r20   ; младший байт посылки
 .def  MBC=r21   ; старший байт посылки
;-- определяем константы
 .equ  Cr1=22    ; длительность 1 несущей
 .equ  Cr0=64    ; длительность 0 несущей
 .equ  NCr=32    ; кол-во импульсов несущей в одном пакете
 .equ  Sys=29    ; номер системы
 .equ  CMD_1=1   ; код команды 1
 .equ  CMD_2=2   ; код команды 2
 .equ  CMD_3=3   ; код команды 3
 .equ  CMD_4=4   ; код команды 4
;---------------------------------------------------------
 
 .cseg
 .org 0
;--- начало программы ------------------------------------
Init: ldi  w,RAMEND     ; устанавливаем указатель вершины
      out  SPL,w        ; стека на старший байт RAM
      sbi  ACSR,7       ; выключаем компаратор
      ldi  w,0b00001000 ; определяем входы и выходы порта
      out  DDRB,w
      ldi  w,0b11110111 ; включаем подтягивающие резисторы
      out  PORTB,w      ; и определяем начальное состояние выходов
;-- формирование старшего байта пакета
      ldi  MBC,Sys        ; записываем в старший байт номер системы
      sbr  MBC,0b11000000 ; устанавливаем старт-биты
Scan: sbis PINB,4         ; если на входе PB4 низкий уровень - нажата КН1
      rjmp Tx_CMD1
      sbis PINB,2         ; если на входе PB2 низкий уровень - нажата КН2
      rjmp Tx_CMD2
      sbis PINB,0         ; если на входе PB0 низкий уровень - нажата КН3
      rjmp Tx_CMD3
      sbis PINB,1         ; если на входе PB1 низкий уровень - нажата КН4
      rjmp Tx_CMD4
      sbr  MBC,0b00100000 ; установить toggle bit в 1 (первое нажатие)
      rjmp Scan
;--- формирование младшего байта пакета ------------------
Tx_CMD1:
      ldi  LBC,CMD_1     ; записываем в младший байт номер команды 1
      rjmp TxRC
Tx_CMD2:
      ldi  LBC,CMD_2     ; записываем в младший байт номер команды 2
      rjmp TxRC
Tx_CMD3:
      ldi  LBC,CMD_3     ; записываем в младший байт номер команды 3
      rjmp TxRC
Tx_CMD4:
      ldi  LBC,CMD_4     ; записываем в младший байт номер команды 4
      rjmp TxRC
;--- Передача пакета RC-5---------------------------------
TxRC: sbrc  MBC,7      ; Startbit 1. Если бит равен 1 - выполняется
      rcall Tx_1       ; Tx_1, если бит равен 0 - выполняется Tx_0
      sbrs  MBC,7
      rcall Tx_0
;------------
      sbrc  MBC,6      ; Startbit 2
      rcall Tx_1
      sbrs  MBC,6
      rcall Tx_0
;------------
      sbrc  MBC,5      ; Toggle bit
      rcall Tx_1
      sbrs  MBC,5
      rcall Tx_0
;------------
      sbrc  MBC,4      ; System bit 4
      rcall Tx_1
      sbrs  MBC,4
      rcall Tx_0
;------------
      sbrc  MBC,3      ; System bit 3
      rcall Tx_1
      sbrs  MBC,3
      rcall Tx_0
;------------
      sbrc  MBC,2      ; System bit 2
      rcall Tx_1
      sbrs  MBC,2
      rcall Tx_0
;------------
      sbrc  MBC,1      ; System bit 1
      rcall Tx_1
      sbrs  MBC,1
      rcall Tx_0
;------------
      sbrc  MBC,0      ; System bit 0
      rcall Tx_1
      sbrs  MBC,0
      rcall Tx_0
;------------
      sbrc  LBC,5      ; Command bit 5
      rcall Tx_1
      sbrs  LBC,5
      rcall Tx_0
;------------
      sbrc  LBC,4      ; Command bit 4
      rcall Tx_1
      sbrs  LBC,4
      rcall Tx_0
;------------
      sbrc  LBC,3      ; Command bit 3
      rcall Tx_1
      sbrs  LBC,3
      rcall Tx_0
;------------
      sbrc  LBC,2      ; Command bit 2
      rcall Tx_1
      sbrs  LBC,2
      rcall Tx_0
;------------
      sbrc  LBC,1      ; Command bit 1
      rcall Tx_1
      sbrs  LBC,1
      rcall Tx_0
;------------
      sbrc  LBC,0      ; Command bit 0
      rcall Tx_1
      sbrs  LBC,0
      rcall Tx_0
;------------
      cbr   MBC,0b00100000 ; сбрасываем toggle bit (повторное нажатие)
;---------------------------------------------------------
;--- пауза, равная межпакетному интервалу (50 бит), т.е. надо послать
;--- 100 нулевых полубитов (RCN) -------------------------
      ldi   T_0,99
pause:
      rcall RCN
      dec   T_0
      brne  pause
      rjmp  Scan
;--- КОНЕЦ ОСНОВНОЙ ПРОГРАММЫ ----------------------------
;--- ПОДПРОГРАММЫ ПЕРЕДАЧИ НУЛЯ И ЕДИНИЦЫ ----------------
;--- передача нуля манчестерским кодом -------------------
Tx_0: rcall RCY   ; первые полбита единица
      rcall RCN   ; вторые полбита ноль
      ret
;--- передача единицы манчестерским кодом ----------------
Tx_1: rcall RCN   ; первые полбита ноль
      rcall RCY   ; вторые полбита единица
      ret
;---------------------------------------------------------
;--- ПОДПРОГРАММЫ ФОРМИРОВАНИЯ СОСТОЯНИЙ "ON" И "OFF" ----
;--- передача единичного полубита ("ON") -----------------
RCY:  ldi   T_NC,NCr   ; загрузить кол-во импульсов
Y_001:
      ldi   T_Cr,Cr1   ; загрузить длительность импульса
      sbi   PORTB,3    ; установить 1 на выходе
Cr1_Y:
      dec   T_Cr
      brne  Cr1_Y      ; для точной подстройки частоты несущей
      cbi   PORTB,3    ; установить 0 на выходе
      ldi   T_Cr,Cr0   ; длительность паузы в импульсе
Cr0_Y:
      dec   T_Cr
      brne  Cr0_Y      ; для точной подстройки частоты несущей
      dec   T_NC
      brne  Y_001
      ret
;--- передача нулевого полубита ("OFF") ------------------
RCN:  ldi   T_NC,NCr   ; подпрограмма передачи нулевого полубита имеет
N_001:
      ldi   T_Cr,Cr1   ; туже структуру, что и подпрограмма передачи
      nop              ; единичного полубита только для того, чтобы
Cr1_N:
      dec   T_Cr       ; было легче регулировать их длительности
      brne  Cr1_N      ; единственное отличие - команды sbi, cbi
      nop              ; заменены на nop
      ldi   T_Cr,Cr0
Cr0_N:
      dec   T_Cr
      brne  Cr0_N
      dec   T_NC
      brne  N_001
      ret
;---------------------------------------------------------

[свернуть]

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

Кроме этого должны быть запрограммированы следующие фьюзы: SPIEN, SUT0, CKSEL0. Запрограммированы — то есть сброшены в ноль, то есть в Pony Prog, например, напротив них должны стоять галочки.

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

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