видимо 36 кГц для "TSOP" ...
вот примерно обьяснено, как сделать эти 36 кГц
правда сделано на прерывании переполнения.
на асм сам справишься перевести.
для светодиода лучше будем использовать ножку C0.
т.к. альтернативная функция предложенной ножки D2
является внешнее прерывание INT0. Лучше подобные
интересные ножки экономить для чего то более важного.
имеем
период частоты тактирования микроконтроллера:
T(8MHz) : 1/800000000Гц = 0,000000125 sek
период частоты 36 кГц:
T(36kHZ) : 1/36000Гц = 0,000027777 sek
длительность импульса или длительность паузы между импульсами частоты 36 кГц при коэффициенте заполнения равному 50%:
T(36kHZ/2) : (1/36000)/2 = 0,000013888 sek
предделитель таймера-0 ставим равным единице:
в регистре TCCR0 в биты
Bit 2:0 – CS02:0: Clock Select записываем 001
TCCR0 = 0b00000001
расчитаем период переполнения таймера-0.
мы установили у таймера-0 предделитель равный 1, то есть он считает с тактовой частотой µC. поэтому получаем:
T(OVF)=256*1/800000000Гц = 0,000032 sek
(256 - это число тактовых импульсов для заполнения всех восьми бит таймера-0, т.к. он восьмибитный)
находим число предустановки таймера-0.
длительность импульса частоты 36 кГц делим на период тактирования таймера-0:
T(36kHZ/2)/T(8MHz) = 0,000013888 sek / 0,000000125 sek = 111,04
округляем до целой доли, получаем число 111.
т.к. восьмибитный таймер считает от нуля, вычитаем:
256-111 = 145
ради этого 145 и все расчёты:)
грубые вычисления окончены.
пишем код.
; настраиваем ножку C0 на выход.
DDRC0=OUT
; настраиваем ножку D3 на вход.
DDRD3=IN
; инициализация таймера-0
TCCR0 = 0b00000001 ; устанавливаем предделитель таймера-0 равным единице.
; инициализируем внешнее прерывание на низкий уровень (т.к. у TSOP активный уровень - низкий, нуль)
;Bit 3, 2 – ISC11, ISC10: Interrupt Sense Control 1 Bit 1 and Bit 0
MCUCR = 0b00000000 ; поэтому биты #3 и #4 должны быть нулём.
MAIN_LOOP:
; тут идёт основной цикл основной программы
; светим, управляем, гасим, включаем
; или просто обогреваем окружающую среду,
; можно отправить микроконтроллер в спячку
; коммандой sleep, или выполнять какие либо вычисления...
; bla - bla - bla
; можно пройтись проверкой по нужным флажкам,
; например проверить и что то сделать (не забыть его потом сбросить!),
; если флаг "TSOP_IS_ACTIV" установлен.
; в какой то момент решаем посветить светодиодом
; и проверить TSOP. для этого переходим на подпрограмму TEST_TSOP
rcall INIT_TSOP
; bla - bla - bla
; тут дальше шуруем в основном цикле
; bla - bla - bla
; bla - bla - bla
; пока не упрёмся в его конец
rjmp MAIN_LOOP ; конец основного цикла, прыгаем на начало.
; \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; тут ниже идут подпрограммы, прерывания и всякая требуха...
; \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; !!! ИНИЦИАЛИЗАЦИЯ ПРОВЕРКИ TSOP !!!
INIT_TSOP:
; инициализируем количество вспышек в пачке:
flash_counter=40 ; ставим удвоенное число.
; разрешаем прерывание по переполнению таймера-0:
; Bit 0 - TOIE0: Timer/Counter0 Overflow Interrupt Enable
TIMSK = 0b00000001 ; для этого устанавливаем бит #0 в регистре TIMSK
; сбрасываем µC-флаги прерывания INT1 (это очень важно! повышает надёжность от непредусмотренных прерываний):
; Bit 7 – INTF1: External Interrupt Flag 1
GIFR = 0b10000000 ; для этого устанавливаем бит #7 в регистре GIFR
; разрешаем внешнее прерывание INT1:
; Bit 7 – INT1: External Interrupt Request 1 Enable
GICR = 0b10000000 ; для этого устанавливаем бит #7 в регистре GICR
RET ; возвращаемся
; !!! ПРЕРЫВАНИЕ ПО ПЕРЕПОЛНЕНИЮ ТАЙМЕРА-0 !!!
; TIMER0 OVF Timer/Counter0 Overflow
T0_OVFL_INT:
; во-первых загружаем в счётчик расчётное число предустановки:
TCNT0=145
; во-вторых убавим счётчик вспышек на один:
flash_counter=flash_counter-1
; и проверим, не обнулился ли он:
if flash_counter==0
then { ; если обнулился ...
; 1. запрещаем прерывание по переполнению таймера-0
; Bit 0 - TOIE0: Timer/Counter0 Overflow Interrupt Enable
TIMSK = 0b00000000 ; для этого сбрасываем бит #0 в регистре TIMSK
; 2. запрещаем внешнее прерывание INT1
; Bit 7 - INT1: External Interrupt Request 1 Enable
GICR = 0b00000000 ; для этого сбрасываем бит #7 в регистре GICR
; 3. выходим из прерывания
RETI
}
else{ ; а если счётчик вспышек не обнулился...
; инвертируем удобным нам способом ножку для светодиода
invert LED_PIN ; LED_PIN мы определили для C0!!
; и выходим из переывния
RETI
}
; !!! ВНЕШНЕЕ ПРЕРЫВАНИЕ INT1 !!!
;INT1 External Interrupt Request 1
TSOP_INT:
; если мы тут оказались , это значит что:
; 1. внешнее прерывание INT1 разрешено
; 2. на выходе TSOP оказался низкий уровень сигнала
set flag "TSOP_IS_ACTIV" ; устанавливаем флаг "TSOP_IS_ACTIV"
; и выходим из прерывания
RETI
после написания кода. компилируем. и контролируем в симуляторе период прерывания.
(или период вспышек светодиода в пачках)
если надо - корректируем число 145 в ту или другую сторону.