ну так у мну примерно в таком режиме работа и идёт :)) А лучшая оптимизация, - как известно это оптимизация алгоритма, а не кода, так что меня особо оптимизаторы не впечают. Видел не раз ассемблерный листинг сишного кода, да, порой вполне себе оптимально (даже в "гнутом" компиляторен, не говоря уж про ИАР), но почему-то проблемы с сишным программером у нас примерно одинаковые (поиск траблов на уровне алгоритма, а не элементарных операций, ну и учитывая то, что в трёёх соснах директив и операторов ассемблера, практически не заблудишься, мне почти всегда легче что-то написать/отладить)
Кстати я свой код частенько не совсем оптимально с т.зр быстродействия и размера пишу, - для лучшего понимания и универсальности, но, тем не менее особо от этого не тстрадаю, и как-то получается что не особо напрягаясь выходят довольно стройные , красивые и быстрые вещи :)) (сам себя не похвалишь - никто не похвалит :))
Кстати, по поводу понятности/универсальности/красивости кода, вот, к примеру одно из моих поделийи образцов "наскальной живописи" :)) В общем не вижу проблем перенести его, на любой другой камень, хоть на асме, хоть на Си
ДЕКОДИРОВАНИЕ FSK:
/*
Чувствительность FSK-декодера определяется точностью работы компаратора, и к примеру, для МК ATmega88PA составляет
Для Freq1/0=1/2kHz, и формулы длины бита (в периодах несущей) 4/8, соответственно.
~5mv ~5% ошибок
~10mV ~1% ошибок
>20mV ~0% ошибок
Аппаратные ресурсы:
1) 6 I/O выводов (в т.ч. RxD,TxD,AIN0,AIN1)
2) Модуль UART
3) 16-битный таймер (аппаратный или программно аппаратный на основе 8-битного таймера). Регистры COMPARE используются для кодирования FSK
и формирования интервалов мониторинга линии TxD. Минимально необходимая разрядность регистров сравнения = 8 бит, но при других значениях
BaudRate, возможно, что понадобится использование 16-разрядных регистров. В любом случае точности 8 бит достаточно, и практически любой BaudRate можно
реализовать, используя предделитель таймера.
Дискретность счёта - не хуже 1/4 периода самой высокой частоты FSK (можно точнее, хуже не будет, но обязательно кратно 4 :)
Аналоговый компаратор (задействованы оба входа на IO ножках МК)
;-------------------------------
Расход памяти - 4 байта
Определения переменных в памяти:
#define S_FSK_TCNTH ;старший байт аппаратно-программного FSK-таймера 1 байт
#define S_FSK_TimeL ;Время, насчитанное в момент предыдущего вызова П/П FSK-декодера 2 байта
#define S_FSK_TimeH ; при 16-битных слагаемых, и выбранной частоте измерений, Fmin=~0,1Гц, чтобы не вылететь за 16-битный результат
#define S_FSK_flags ;байт флагов 1 байт
~~~~~~~~~~~~~~~~~~
Измерение частоты происходит следующим образом:
По срабатываению компаратора (прерыванию), засекается текущее время FSK-таймера.
При следующем срабатывании компаратора, определяется разница между запомненным ранее и текущем временем. Так как срабатывания компаратора -
это "zero-cross" входного сигнала (предположительно FSK), то по измеренной временной разнице между срабатываниями, мы определяем какой
из частот в данный момент сооветствует входной сигнал. Детектирование определяется по первому же полупериоду. Для НЧ частоты модуляции FSK,
и по второму для ВЧ. Таким образом достигается равенство времён детектирований "0" и "1". Это конечно корректно работает с соотношениями частот 1:2.
В соответствии с ним выставляем уровень на ножке RxD апаратного приёмника UART.
Таким образом, "на лету", практически в реальном времени, происходит декодирование FSK сигнала и перенаправление декодированного битового потока на вход
аппаратного UART. Далее, байтовые операции с приёмным буфером UART выполняются общепринятым образом.
КОДИРОВАНИЕ FSK:
~~~~~~~~~~~~~~~~~~
Байт данных, предназначенный для отправки с FSK-кодированием помещается в передающий буфер UART, откуда, штатным образом, на запрограммированной скорости
UART-BaudRate, уходит в линию TxD. Тактовый таймер FSK, с заданным интервалом "просматривая" состояние линии TxD, программирует COMPARE регистр FSK-таймера , записав в него
текущее значение счётного регистра, +значение периода для частот "0" или "1" , в зависимости от состояния контролируемой линии "TxD"
ГЕНЕРАЦИЯ FSK:
~~~~~~~~~~~~~~~~~~
Генерация FSK происходит по прерыванию по регистру COMPARE, FSK-таймера. по этому прерыванию, необходимо инвертировать состояние выходной ножки МК,
откуда снимается сигнал. Обновление COMPARE регистра происходит по смене уровня на линии TxD, а так же по событию CompareMatch
Соглашение об описании памяти:
------------------------------
В Def-файле проекта должна быть определена переменная "FSK_Memory" - начало области памяти для процедур FSK-библиотеки
Последующая подключаемая библиоека должна использовать для выделения своей области памяти переменную "FSK_Memory_END".
Первая доступная ячейка будет иметь адрес "FSK_Memory_END+1"
*/
;#define FSK_Memory 0x... ;Определение начала области памяти зарезервированной для библиотеки FSK_Lib
#define S_FSK_TCNTH FSK_Memory+1 ;старший байт аппаратно-программного FSK-таймера 1 байт
#define S_FSK_TimeL FSK_Memory+2 ;Время, насчитанное в момент предыдущего вызова П/П FSK-декодера 2 байта
#define S_FSK_TimeH FSK_Memory+3 ; при 16-битных слагаемых, и выбранной частоте измерений, Fmin=~0,1Гц, чтобы не вылететь за 16-битный результат
#define S_FSK_flags FSK_Memory+4 ;байт флагов 1 байт
#define FSK_Memory_END FSK_Memory+4 ;Определение начала области памяти зарезервированной для библиотеки FSK_Lib
;------------------------------------------------------------------------------------------------------------------------------------
;Определения Входных/Выходных линий
;-------------------------------------------
; -- Линия TxD (UART) - выход UART битового потока, направляемого в FSK-кодер
#define FSK_TxD_PIN PIND ;Регистры PIN, PORT порта контроля линии TxD и номера линии/бита
#define FSK_TxD_PORT PORTD
#define FSK_TxD_PinNum 1
#define FSK_TxD_PinMask bit1
;
; -- Линия FSK_out - выход FSK генератора (синтезируемый FSK-сигнал, соответствующий битовому потоку на ножке TxD)
#define FSK_out_PORT PORTB ;Регистры PIN, PORT выходной линии FSK и номера линии/бита
#define FSK_out_PIN PINB
#define FSK_out_DDR DDRB
#define FSK_out_PinNum 3
#define FSK_out_PinMask bit3
;
; -- Линия DATAbit_out - выход битового потока с FSK декодера (битовый поток с декодекрра FSK, подаётся на ножку RxD аппаратного UART)
#define FSK_DATAbit_PORT PORTD ;Регистры PIN, PORT выходной линии FSK и номера линии/бита
#define FSK_DATAbit_PIN PIND
#define FSK_DATAbit_DDR DDRD
#define FSK_DATAbit_PinNum 5
#define FSK_DATAbit_PinMask bit5
;
;------------------------------------------------------------------------------------------------------------------------------------
;Флаги регистра "S_FSK_flags"
#define BitStream_bm bit7 ;флаг состояния битового потока на текущий момент (для FSK-передатчика)
#define BitStream_bp 7
#define DATAbit_bm bit6 ;Бит данных на текущий момент (устанавливается и используется П/П "FSK_Detector")
#define DATAbit_bp 6
#define HiFreq_HalfDetect_bm bit5 ;Флаг показывающий, что при детектировании ВЧ FSK детектирован первый полупериод, а нужно ещё и второй
#define HiFreq_HalfDetect_bp 5 ; (это нужно, чтобы время детектирования для ВЧ/НЧ совпадало, так как ногу FSKout драйвим в конце детектирования
; и если не будет равенства времени детектирования, то получим разные длины для "0" и "1" (для НЧ импульс будет короче)
;
;#define ..._bm bit4 ;Reserved...
;#define ..._bp 4
;
;#define ..._bm bit3 ;Reserved...
;#define ..._bp 3
;
;#define ..._bm bit2 ;Reserved...
;#define ..._bp 2
;
;#define ..._bm bit1 ;Reserved...
;#define ..._bp 1
;
;#define ..._bm bit0 ;Reserved...
;#define ..._bp 0
;
;------------------
;Исходные параметры:
; !! ВНИМАНИЕ !! для корректной работы алгоритма детектирования неоходимо соблюдение двух следующих условий:
; 1) Частоты FSK для "0" и "1" должны различаться в 2 раза
; 2) Параметр FSK_BaudRate должне быть строго 1/4 самой низкой частоты FSK (4 периода на бит). Можно и 1/2, но будут ошибки декодирования.
#define FSK_frequency0 2000 ;Hz частота для "0"
#define FSK_frequency1 1000 ;Hz частота для "1" (она же частота несущей, перед старт-битом и после стоп-бита)
#define FSK_Deviation 25 ;(1..99 dec,%) допустимое отклонение частоты при детектировании, в % (33% - это уже стык допусков для Freq0 и Freq1)
#define FSK_timer_Clock 3686400/8 ;Hz частота тактирования счётного таймера FSK (для частоты 3.6864MHz это 57600kHz)
;!! ВНИМАНИЕ!! на более низкой частоте, например при предделителе 8 наблюдаются пропуски бит при генерации FSK
#define FSK_CriticalFreq FSK_timer_Clock/256/2 ;Минимальная частота, c которой можно работать при данных настройках FSK-таймера.
#define FSK_scope_ratio 10 ;сколько раз за полпериода максимальной FSK частоты, смотрим линию TxD (нужно для генерации FSK)
; (!) при значении параметра FSK_scope_ratio больше 20 могут наблюдаться проблемы с конкуренцией прерываний
#define FSK_BaudRate 250 ;скорость потока данных - на текущий момент оптимально 1/4 в отношении самой низкой часты FSK
; (но возможно и 1/2 при некотором % ошибок)
; Статистика ошибок
; Err(2 периода) 1%
; Err(4 периода) ~0%
;#define FSK_minBitLength 4 ;Минимальная длина бита, в периодах самой низкой несущей часоты
;-------------------
;Высчитываемые из исходных параметры
;------------------------------------
;Константы для отсчёта импульса/паузы (полпериода) генерируемой FSK частоты
#define FSK_freq0_constant FSK_timer_Clock/FSK_frequency0/2
#define FSK_freq1_constant FSK_timer_Clock/FSK_frequency1/2
;-------------------
;Константа для отсчёта периодов просмотра линии TxD для кодера FSK
#if FSK_frequency0>FSK_frequency1
#define FSK_scope_constant FSK_timer_Clock/FSK_frequency0/FSK_scope_ratio
#elif FSK_frequency1>FSK_frequency0
#define FSK_scope_constant FSK_timer_Clock/FSK_frequency1/FSK_scope_ratio
#endif
;-------------------
;Константа для отсчёта мёртвого времени для декодера FSK (для фильтрации ошибочных срабатываний компаратора)
;Высчитываются два порога:
; DeadTime - высчитыватся как 1/4 периода (1/2 константы) для большей частоты FSK, из Freq0, Freq1
; LostTime - высчитыватся как период для меньшей частоты FSK+допуск
#if FSK_frequency0>FSK_frequency1
#define FSK_DeadTime_constant FSK_freq0_constant/2
#elif FSK_frequency1>FSK_frequency0
#define FSK_DeadTime_constant FSK_freq1_constant/2
#endif
#if FSK_frequency0<FSK_frequency1
#define FSK_LostTime_constant FSK_freq0_constant+(FSK_freq0_constant/(100/FSK_Deviation))
#elif FSK_frequency1<FSK_frequency0
#define FSK_LostTime_constant FSK_freq1_constant+(FSK_freq1_constant/(100/FSK_Deviation))
#endif
#message "_________________________________________________________________________"
#message "FSK_frequency0 =" FSK_frequency0
#message "FSK_frequency1 =" FSK_frequency1
#message "FSK_scope_constant =" FSK_scope_constant
#message "FSK_BaudRate =" FSK_BaudRate
;-----------------------------------------------------------------------------------------------------------------------------
;П/П обслуживания прерывания переполнения 8-битного таймера FSK
;INTERRUPT handler (TCNT)
;!! ВНИМАНИЕ !! при вызове этого прерывания автоматом сохраняется только контекст (SREG+TMP),
; все остальные регистры, если они нужны - сохраняем вручную здесь
FSK_timer_OverFlow:
S_INC S_FSK_TCNTH
ret
;-------------------------------
;П/П мониторинга линии TxD UART с целью определения частоты генерации FSK (разные частоты для "0" и "1")
;INTERRUPT handler (CMPRA)
;(CompareA) - формирователь интервалов мониторинга линии TxD
;!! ВНИМАНИЕ !! при вызове этого прерывания автоматом сохраняется только контекст (SREG+TMP),
; все остальные регистры, если они нужны - сохраняем вручную здесь
FSK_TxD_scope:
;Процедуры отрабатывают достаточно быстро, но они критичны ко времни исполнения, т.к реалтайм кодинг/декодинг,
; поэтому вложенные прерывания НЕ РАЗРЕШАЕМ !!
push XTMP ;Сохраняем дополнительно используемые к TMP регистры
;
in XTMP,OCR0A ;Считаем текущее значение CompareA регистра таймера, отвечающего за период моноринга
ldi TMP,FSK_scope_constant ;константа периода мониторинга линии TxD
add TMP,XTMP ;Высчитаем новое значение CompareA регистра
out OCR0A,TMP ;Запишем его в CompareA регистр таймера
;-----------------------------
;непосредственно сам мониторинг линии TxD и установка флага BitStream, использующегося для генерации FSK, в регистре FSK-статуса
lds TMP,S_FSK_flags
;
sbic FSK_TxD_PIN,FSK_TxD_PinNum ;Установим состояние ф.BitStream в соответствие с линией TxD.
rjmp SetFSK1
SetFSK0:
cbr TMP,BitStream_bm ;ф.BitStream=0, если линия TxD в "0"
rjmp FSK_next
SetFSK1:
sbr TMP,BitStream_bm ;ф.BitStream=1, если линия TxD в "1"
FSK_next:
sts S_FSK_flags,TMP ;Сохраним регистр флагов FSK с обновлённым флагом битового потока BitStream
;-----------------
pop XTMP
ret
;-------------------------------
;П/П генерации битонального сигнала FSK (разные частоты для "0" и "1")
;INTERRUPT handler (CMPRB)
;(CompareB) - регистр периода формирователя FSK-сигнала
;!! ВНИМАНИЕ !! при вызове этого прерывания автоматом сохраняется только контекст (SREG+TMP),
; все остальные регистры, если они нужны - сохраняем вручную здесь
;процедура исполняется быстро, так что вложенные прерывания не разрешаем, чтобы не нарушать процесс генерации.
FSK_Gen:
;Процедуры отрабатывают достаточно быстро, но они критичны ко времни исполнения, т.к реалтайм кодинг/декодинг,
; поэтому вложенные прерывания НЕ РАЗРЕШАЕМ !!
push XTMP
;---- в этой секции не портить XTMP! ---\
in XTMP,OCR0B ;Считаем текущее значение CompareB регистра таймера, отвечающего за генерацию FSK
;
lds TMP,S_FSK_flags ;Анализируем ф.BitStream и идём на соответствующую ветку, для установки констант
sbrc TMP,BitStream_bp ; для генерации Freq0/1
rjmp FSKfreq1
FSKfreq0:;-- генерация "0" (запись в CompareB константы для генерации "0")
ldi TMP,FSK_freq0_constant ;константа генератора частоты FSK0 (для нуля)
rjmp FSKfreq_SET ;Уходим, с установкой новой константы регистра периода FSK (CompareB)
FSKfreq1:;-- генерация "1" (запись в CompareB константы для генерации "2")
ldi TMP,FSK_freq1_constant ;константа генератора частоты FSK1 (для единицы)
FSKfreq_SET:
add XTMP,TMP ;Высчитаем новое значение для регистра CompareB генератора FSK
out OCR0B,XTMP ;Запишем его в CompareB регистр таймера
;---------------------------------------/
;
MARKER_FLASH FSK_out_PIN,FSK_out_PORT,FSK_out_PinNum ;собственно дёргаем линию FSK
; ; (инвертирование состояния ноги при каждом исполнении макроса)
pop XTMP
ret
;-------------------------------
;П/П детектирования битонального сигнала FSK (разные частоты для "0" и "1")
;INTERRUPT handler (Analog Comparator)
;!! ВНИМАНИЕ !! при вызове этого прерывания автоматом сохраняется только контекст (SREG+TMP),
; все остальные регистры, если они нужны - сохраняем вручную здесь
;процедура исполняется быстро, так что вложенные прерывания не разрешаем, чтобы не нарушать процесс детектирования.
;
FSK_Detector:
;Процедуры отрабатывают достаточно быстро, но они критичны ко времни исполнения, т.к реалтайм кодинг/декодинг,
; поэтому вложенные прерывания НЕ РАЗРЕШАЕМ !!
push TMP2 ;Сохраним используемые в данной П/П регистры
push XTMP
PUSH_X
PUSH_Y
;
in XL,TCNT0 ;Сохраним текущие значения счётного FSK-таймера в X
lds XH,S_FSK_TCNTH
;
lds YL,S_FSK_TimeL ;Вспомним в Y ранее запомненные (при предыдущем вызове этого хэндлера) значения счётного FSK-таймера
lds YH,S_FSK_TimeH
;
sts S_FSK_TimeL,XL ;сохраним текущее время (значения счётного FSK-таймера)
sts S_FSK_TimeH,XH
;-- Высчитаем модуль разницы с моментом предыдущего вызова данного хэндлера (момента срабатывания компаратора)
;-- Результат поместим в Y (фактически - это измеренный полупериод частоты FSK)
sub YL,XL ;Вычислим сколько же насчитали с момента предыдущего вызова данного хэндлера (результат положим в "Y")
sbc YH,XH
brcc FSK_TryDetectFreq0 ;Если получился положительный результат, то идём далее,
neg YL ; иначе (если результат отрицательный), то инвертируем его
com YH
;
; -- Попробуем детектировать Freq0 (вычислим модуль разницы между измеренным интервалом и константой FSK_Freq0)
FSK_TryDetectFreq0: ;В Y - измеренные полпериода FSK-частоты
PUSH_Y ;Временно сохраним измеренный результат - полупериод FSK-частоты (на случай если
; не удасться детектировать Freq0, и придётся пробовать детектировать Freq1)
LDX FSK_freq0_constant ;Константа для полупериода Freq0
sub YL,XL ;Вычислим сколько же насчитали с момента предыдущего вызова данного хэндлера (результат положим в "Y")
sbc YH,XH
brcc FSK_Det_Freq0 ;Если получился положительный результат, то идём далее,
neg YL ; иначе (если результат отрицательный), то инвертируем его
com YH
;
; -- Детектируем Freq0 (сравним измеренный интервал с константой FSK_Freq0)
FSK_Det_Freq0: ;В Y - разница между измеренным интервалом и константой Freq0
LDX FSK_freq0_constant/(100/FSK_Deviation) ;Загрузим в "X" порог отклонения (допуск) от FSK_freq0_constant в % для полупериода
; в "Y" у нас на текущий момент разница измеренного периода FSK-частоты и образцовой константы
cp XL,YL ;Сравниваем разницу измеренного периода FSK с порогом (допуском) Freq0
cpc XH,YH
brcs FSK_TryDetectFreq1 ;Если не уложились в допуск, то значит не нашли Freq0, тогда попробуем найти Freq1, иначе
; считаем что обнаружили Freq0.
; *** Freq0_detected ***
S_LDI S_AutoShutDown_Timer,AutoShutDown_Time ;взведём таймер автоотключения (переустановим его), так как обнаружили FSK
; (FSK1 есть всегда по протоколу UART, а вот FSK0 только при наличии обмена по UART-каналу)
POP_Y ;подчистим стек (так как ранее, в начале детектирования Freq0, его сохраняли, а теперь он стал не нужнен.
;--------------------------------------
;-- выравнивание времени детектирования для разных частот Freq0 и Freq1
lds YL,S_FSK_flags ;Загрузим регистр флагов для работы с флагом "HiFreq_HalfDetect"
; (Используем YL, а не TMP чтобы нечаяно не испортить его содержимое (например макросами))
#if FSK_frequency0<FSK_frequency1 ;Если Freq0 у нас НЧ, то
cbi FSK_DATAbit_PORT,FSK_DATAbit_PinNum ;Сразу драйвим линию FSK_DATAbit
cbr YL,HiFreq_HalfDetect_bm ; сбросим ф.детектирования первого полупериода ВЧ
rjmp FSK_Det_Freq0_alignEND ; и выходим с сохранением регистра статуса.
;
#else ;Иначе считаем, что Freq0 - ВЧ, и тогда будем смотреть, это 1-й или 2-й полупериод ??
sbrs YL,HiFreq_HalfDetect_bp ;Если первого периода ещё нет,
rjmp SetFreq0_HalfDetect ; то установим ф.HalfDetect (продетектировали первый полупериод ВЧ)
cbr YL,HiFreq_HalfDetect_bm ; Иначе считаем, что флаг уже был установлен в предыдущий вызов данного хэндлера, поэтому сбросим его
cbi FSK_DATAbit_PORT,FSK_DATAbit_PinNum ; и только теперь драйвим линию FSK_DATAbit.
rjmp FSK_Det_Freq0_alignEND ;Выходим с сохранением регистра статуса.
SetFreq0_HalfDetect:
sbr YL,HiFreq_HalfDetect_bm ;Установим флаг, что сейчас мы продетектировали первый полупериод ВЧ, и выходим.
#endif
FSK_Det_Freq0_alignEND:
sts S_FSK_flags,YL ;Сохраним изменённый регистр статуса.
;--------------------------------------
rjmp FSK_Detector_Ret ;Уходим
;--------------------------------------------------
; -- Попробуем детектировать Freq1 (вычислим модуль разницы между измеренным интервалом и константой FSK_Freq1)
FSK_TryDetectFreq1:
POP_Y ;Вспомним, что намеряли (полпериода FSK-часоты. То, что сохраняли в стеке в начале процедуры детектирования Freq0.)
; -- Вычисляем измеренный временной интервал (полпериода частоты FSK)
LDX FSK_freq1_constant ;Константа для полупериода Freq1
sub YL,XL ;Вычислим сколько же насчитали с момента "0" (результат положим в "Y")
sbc YH,XH
brcc FSK_Det_Freq1 ;Если получился положительный результат, то идём далее,
neg YL ; иначе (если результат отрицательный), то инвертируем его
com YH
;
FSK_Det_Freq1: ;В Y - разница между измеренным и константой Freq1
LDX FSK_freq1_constant/(100/FSK_Deviation) ;Загрузим в "X" порог отклонения (допуск) от FSK_freq1_constant в % для полупериода
; в "Y" у нас на текущий момент разница измеренного периода FSK-частоты и образцовой константы
cp XL,YL
cpc XH,YH
brcs FSK_NotDetected ;Если не уложились в порог, то значит не нашли Freq1, т.е. и не Freq0 и не Freq1 :(
; ** Freq1_detected
;--------------------------------------
S_LDI S_AutoShutDown_Timer,AutoShutDown_Time ;взведём таймер автоотключения (переустановим его), так как обнаружили FSK
; (FSK1 есть всегда по протоколу UART, а вот FSK0 только при наличии обмена по UART-каналу)
;-- выравнивание времени детектирования для разных частот Freq0 и Freq1
lds YL,S_FSK_flags ;Загрузим регистр флагов для работы с флагом "HiFreq_HalfDetect"
; (Используем YL, а не TMP чтобы нечаяно не испортить его содержимое (например макросами))
#if FSK_frequency0>FSK_frequency1 ;Если Freq1 у нас НЧ, то
sbi FSK_DATAbit_PORT,FSK_DATAbit_PinNum ;Сразу драйвим линию FSK_DATAbit
cbr YL,HiFreq_HalfDetect_bm ; сбросим ф.детектирования первого полупериода ВЧ
rjmp FSK_Det_Freq1_alignEND ; и выходим с сохранением регистра статуса.
;
#else ;Иначе считаем, что Freq1 - ВЧ, и тогда будем смотреть, это 1-й или 2-й полупериод ??
sbrs YL,HiFreq_HalfDetect_bp ;Если первого периода ещё нет,
rjmp SetFreq1_HalfDetect ; то установим ф.HalfDetect (продетектировали первый полупериод ВЧ)
cbr YL,HiFreq_HalfDetect_bm ; Иначе считаем, что флаг уже был установлен в предыдущий вызов данного хэндлера, поэтому сбросим его
sbi FSK_DATAbit_PORT,FSK_DATAbit_PinNum ; и только теперь драйвим линию FSK_DATAbit.
rjmp FSK_Det_Freq1_alignEND ;Выходим с сохранением регистра статуса.
SetFreq1_HalfDetect:
sbr YL,HiFreq_HalfDetect_bm ;Установим флаг, что сейчас мы продетектировали первый полупериод ВЧ, и выходим.
#endif
FSK_Det_Freq1_alignEND:
sts S_FSK_flags,YL ;Сохраним изменённый регистр статуса.
;--------------------------------------
rjmp FSK_Detector_Ret ;Уходим
;--------------------------------------------------
FSK_NotDetected: ;Детектирование не получилось (не нашли ни Freq0, ни Freq1), т.е. замеренный временной интервал некорректен (помеха)
; ;Сюда обычно попадаем при множественных срабатываниях компаратора в окрестности "нуля"
nop
#warning "Dbg FSKoutNeedle"
//MARKER_nanoNEEDLE FSK_DATAbit_PIN,FSK_DATAbit_PORT,FSK_DATAbit_PinNum
;-------------------------------------------
FSK_Detector_Ret:
;
POP_Y ;Восстановим используемые в данной П/П регистры
POP_X
pop XTMP
pop TMP2
ret