MENU
Главная » Статьи » ДИСТАНЦИОННОЕ УПРАВЛЕНИЕ IK,RF,USB

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

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

Программа реализует следующие функции:

1) Подпрограмма обработки прерывания проверяет принимаемый код на соответствие манчестерскому алгоритму, декодирует принятый код и записывает его в 2 байта:

MBC - 7,6 биты - стартовые; 5 - управляющий бит; 4...0 - номер системы

LBC - 7...2 биты - номер команды; 1,0 биты - не используются

если принимаемый код не манчестерский - загорается первый светодиод.

2) В рабочей части программы реализуется управление тремя оставшимися светодиодами: если номер системы в принятом коде не тот, который мы ждали - загорается второй светодиод, если номер системы совпадает с ожидаемым, но номер команды не совпадает с ожидаемым - загорается третий светодиод, и, наконец, если и номер системы и номер команды совпадают с ожидаемыми - загорается четвертый светодиод.

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

Основные идеи алгоритма:

1) Выход ILMS1836 - инвертированный, т.е. когда принимается "1" - на выходе фотоприемника "0" (низкий уровень), когда приема нет или принимается "0" - на выходе фотоприемника "1"(высокий уровень).

2) Стартовый бит манчестерским кодом передается как последовательность "01", но первый полубит ("0") мы не отличим от отсутствия сигнала, т.е. фактически прием начинается со второго полубита.

3) В процессе работы программа считывает значение на входе контроллера каждые 889 мкс и считает это значение - значением принятого полубита.

4) Программа уходит в прерывание очень быстро - за несколько микросекунд, поэтому, чтобы читать значения подальше от границы полубитов, перед приемом первого полубита вводится пауза, примерно равная половине полубита.

5) Для проверки на соответствие манчестерскому алгоритму используется следующее его свойство: никакие три последовательных полубита не могут быть одновременно нулями или единицами.

6) Если записывать все четные полубиты, начиная со второго, то мы восстановим исходную посылку.

То есть мы принимаем все полубиты, но! Четные - записываем и используем для проверки на соответствие манчестерскому алгоритму, нечетные - используем только для проверки.

Алгоритм:

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

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

входы: PB3 - вход ИК-приемника

выходы: PB2, PB1, PB0, PB4 - выходы на транзисторы управления светодиодами.

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

Пусть мы ожидаем команду 2 управления светом (номер системы 29).

Программа:

;---------------------------------------------------------
.device ATtiny13
.include "tn13def.inc"
.list
;-- определяем свои переменные
.def w=r16 ; это будет наш аккумулятор
.def MBC=r17 ; старший байт посылки
.def LBC=r18 ; младший байт посылки
.def Sch=r19 ; счётчик принятых бит
.def Preg=r20 ; проверочный регистр (для проверки на манчестер)
.def N_bit=r21 ; номер бита для записи
.def Schp=r22 ; счётчик для паузы
;-- определяем константы
.equ T1=210 ; задержка около четверти бита (делитель на 64)
.equ T2=123 ; задержка в половину бита (делитель на 64)
.equ TP=10 ; задержка между приёмом посылок (делитель на 1024)
.equ Sys=29 ; номер системы
.equ CMD_1=4 ; 000001 00 младшие 2 бита не используются,
 ; поэтому код команды=1
;-- Используемые регистры
; SPL - указатель вершины стека
; ACSR - управление компаратором
; DDRB - направление работы ног
; PORTB - выходы порта
; PCMSK - разрешение прерываний на отдельных входах
; GIMSK - общее разрешение прерываний по входам
; GTCCR - сброс предделителя
; TCCR0B - управление таймером
; TIMSK0 - прерывания от таймера
;-- начало программного кода
 .cseg
 .org 0
 rjmp Init ; переход на начало программы
;-- вектора прерываний
 reti ; INT0
 rjmp Pch ; Pin Change
 rjmp Timer ; Timer
 reti ; EEPROM
 reti ; comparator
 reti ; timer compare match A
 reti ; timer compare match B
 reti ; watchdog
 reti ; ADC
;-- начало программы
Init: ldi w,RAMEND ; устанавливаем указатель вершины
 out SPL,w ; стека на старший байт RAM
 sbi ACSR,7 ; выключаем компаратор
 ldi w,0b00010111 ; определяем входы и выходы порта
 out DDRB,w
 ldi w,0b11101000 ; включаем подтягивающие резисторы
 out PORTB,w ; и определяем начальное состояние выходов
;-- (пока таймер не запущен - прерывание не произойдёт)
 ldi w,0b00000010
 out TIMSK0,w ; разрешить прерывания от таймера
;-- разрешить прерывание от входов
 ldi w,0b00100000
 out GIMSK,w ; разрешаем прерывание от входов
;-- разрешить прерывания на входе PB3
Start: ldi w,0b00100000
 out GIFR,w ; сбросить флаг прерываний от входов
 ldi w,0b00001000
 out PCMSK,w ; разрешаем прерывания на входе PB3
 sei ; разрешить глобальные прерывания
Scan: nop
 rjmp Scan
;-- ОБРАБОТЧИК ПРЕРЫВАНИЯ ПО ВХОДУ
;-- инициализируем счётчик, адр.бита, пров.рег., адр.рег.записи
Pch: sbic PINB,3 ; если на входе низкий уровень - пропуск.команду
 reti ; это не приём - выходим
 ;---
 clr w
 out PCMSK,w ; запрещаем прерывания от всех входов
 clr MBC ; реинициализируем приёмные регистры
 clr LBC
 clr Sch ; сбрасываем счётчик
 ldi N_bit,128 ; поднять 7-й бит в N_bit, остальные - сбросить
 clr Preg ; три младших бита проверочного регистра=0
 ldi XL,0x11 ; загружаем в XL указатель на регистр r17
;-- настраиваем таймер для отсчёта длительности четверти бита
 ldi w,T1
 out TCNT0,w
;-- запустить таймер
 ldi w,0b00000001
 out GTCCR,w ; сбросить предделитель
 ldi w,0b00000011
 out TCCR0B,w ; запустить таймер с делителем на 64
 reti
;-- ОБРАБОТЧИК ПРЕРЫВАНИЯ ОТ ТАЙМЕРА
Timer: clr w
 out TCCR0B,w ; выключить таймер
;--
Priem: ldi w,T2
 out TCNT0,w ; настр-м таймер для отсчёта длит-ти полубита
;-- читаем значение на входе и сохраняем в пользовательский флаг
 clt ; сбрасываем T
 sbis PINB,3 ; если на входе 1 - пропуск.следующую команду
 set ; установить T (принятый сигнал инвертирован)
;-- если в счётчике чётное значение - восcтанавливаем значение
;-- полубита в байт и сохраняем для проверки на манчестер, иначе
;-- используем только для проверки
 sbrc Sch,0 ; если 0-й бит Sch=0 - пропуск следующ.команды
 rjmp Mtest ; переходим к проверке на манчестер
 ld w,X ; читаем байт, в который будем восстанавливать
 brtc store0 ; если флаг T не установлен -
 ; восстанавливаем 0, иначе - 1
store1: or w,N_bit ; поднимаем бит в нужной позиции
 rjmp Sbyte
store0: com N_bit ; инвертируем N_bit
 and w,N_bit ; сбрасываем бит в нужной позиции
 com N_bit ; возвращаем N_bit в прежнее состояние
Sbyte: st X,w ; сохраняем новое значение байта
;-- сдвигаем номер записываемого бита
 clc ; очищаем флаг переноса
 ror N_bit ; сдвигаем N_bit вправо через перенос
 brcc Mtest ; если флаг C не установился - переходим
 ror N_bit ; ещё раз сдвинуть вправо (установить 7-й бит)
 inc XL ; сдвинуть указатель на следующий байт
;-- тест на манчестер
Mtest: lsl Preg ; сдвигаем влево проверочный регистр
 bld Preg,0 ; дописываем к нему справа принятый бит
 mov w,Preg ; копируем Preg в w
 andi w,0b00000111 ; отрезаем все биты, кроме трёх младших
 breq no_manch ; если 3 младших бита=0, то это не манчестер
 com w ; инвертируем w
 andi w,0b00000111 ;если все младш.биты были=1, то получ-ся 0
 breq no_manch
;-- увеличиваем счётчик
 inc Sch
;-- если счётч.полубитов=27 - перех.к паузе, иначе - продолж. приём
 cpi Sch,27
 breq rab_chast
 ;---
 ldi w,0b00000011
 out TCCR0B,w ; запустить таймер с делителем на 64
 reti
;-- РАБОЧАЯ ЧАСТЬ
;-- Проверка номера системы и команды
rab_chast: ldi w,Sys ; загружаем в w номер системы
 andi MBC,0b00011111 ; отрезаем от MBC старт. и управл.биты
 cpse w,MBC ; если MBC=Sys - пропуск. следующ.команду
 rjmp Nosys
 ldi w,CMD_1 ; загружаем в w код команды
 cpse w,LBC ; если LBC=CMD_1 - пропуск. следующ.команду
 rjmp Nocom
;-- погасить все, зажечь 4-й
 ldi w,0b11111000
 out PORTB,w
 rjmp Epocket
;-- погасить все, зажечь 2-й
Nosys: ldi w,0b11101010
 out PORTB,w
 rjmp Epocket
;-- погасить все, зажечь 3-й
Nocom: ldi w,0b11101001
 out PORTB,w
 rjmp Epocket

;-- если мы имеем дело не с манчестером, то надо
;-- включить первый светодиод, выгрузить лишнее из
;-- стека и перейти к старту
no_manch:
 ldi w,0b11101100
 out PORTB,w ; включить первый светодиод
Epocket:
 pop w
 pop w
 rjmp Start
;---------------------------------------------------------

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

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



Источник: http://radiohlam.ru/program/ikpriemnik_tiny13_prg_rc5.htm
Категория: ДИСТАНЦИОННОЕ УПРАВЛЕНИЕ IK,RF,USB | (04.03.2015)
Просмотров: 1872 | Теги: протокол RC-5, прошивка, самодельный, программа, ИК, приёмник | Рейтинг: 5.0/1
Похожие материалы
Всего комментариев: 0
avatar

Copyright MyCorp © 2024    Бесплатный конструктор сайтов - uCoz                               Яндекс.Метрика