16+
Среда
15 августа
Вход |Карта сайта | |Upload |codebook | PARTS

 О смысле всего сущего 0xFF

 Средства и методы разработки

 Мобильная и беспроводная связь

 Блошиный рынок Объявления

caxapa

Микроконтроллеры ARM 

AVR PIC MSP PLD,FPGA,DSP 

Кибернетика Технологии 

Схемы, платы, компоненты 

Микроконтроллеры AVR

 
   Новая тема Правила Регистрация Поиск »» Архив
Вернуться в конференциюТопик полностью
Adept  (05.08.2014 13:02 - 05.08.2014 13:09) , в ответ на Ну тогда давай так и договоримся, что для кода объемом до 8 килобайт требующего максимальной эффективности и допускающего его вылизывания пока самому не надоест асм рулит. Если ТЗ выходит за эти рамки, наступаем на горло своей песни и зовем автор: Codavr
ну так у мну примерно в таком режиме работа и идёт :)) А лучшая оптимизация, - как известно это оптимизация алгоритма, а не кода, так что меня особо оптимизаторы не впечают. Видел не раз ассемблерный листинг  
сишного кода, да, порой вполне себе оптимально (даже в "гнутом" компиляторен, не говоря уж про ИАР), но почему-то проблемы с сишным программером у нас примерно одинаковые (поиск траблов на уровне алгоритма, а не элементарных операций, ну и учитывая то, что в трёёх соснах директив и операторов ассемблера, практически не заблудишься, мне почти всегда легче что-то написать/отладить) Кстати я свой код частенько не совсем оптимально с т.зр быстродействия и размера пишу, - для лучшего понимания и универсальности, но, тем не менее особо от этого не тстрадаю, и как-то получается что не особо напрягаясь выходят довольно стройные , красивые и быстрые вещи :)) (сам себя не похвалишь - никто не похвалит :)) Кстати, по поводу понятности/универсальности/красивости кода, вот, к примеру одно из моих поделийи образцов "наскальной живописи" :)) В общем не вижу проблем перенести его, на любой другой камень, хоть на асме, хоть на Си
ДЕКОДИРОВАНИЕ 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
Главная | Карта сайта | О проекте | Проекты | Файлообменник | Регистрация | Вебмастер | RSS
Лето 7526 от сотворения мира. При использовании материалов сайта ссылка на caxapу обязательна.
MMI © MMXVIII