	 list      p=PIC16F873A
     #include  P16F873A.inc ;	; 16.000 MHz
	__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON& _HS_OSC  &_LVP_OFF &_CPD_OFF
	errorlevel -302
#define	sin_ok		Modes,0	;ако сме определили синхро импулс
#define	sin_fal		Modes,1	;ако е инало синхрониация и е пропаднала
#define  ready_in	Modes,2	;ако е минал цял цикъл приемане и
			; ако е запазена и синхронизацията => прехвърля buf_in в buf_r
#define	sub_proc	Modes,4
#define	Carry_fl		Modes,5	;използва се за да се запази състоянието на преноса при
			;блоковата обработка на информацията
 #define cin	PORTC,2
#define stmacro_
st macro v
#ifdef 	stmacro
	CBLOCK	0x79
	mtot:2			;за 	stmacro
	endc

	movlw 	v & H'FF'        ;Mask to get LSB
	addwf	mtot+1,f
	btfsc	STATUS,C
	incf	mtot,f
	movlw   v >>D'08' & H'FF'
	addwf	mtot,f
 	call	delay_200iS
	movf	mtot,w
	movwf	TMR1H
	movwf	CCPR1H
	movf  mtot+1,w
	movwf	TMR1L
	movwf	CCPR1L
	bsf	PIR1,CCP1IF
#else
	nop
	nop	
#endif
	endm
; --------------------------------------------------
	CBLOCK	0x7B
	W_TEMP		;storage for WREG during interrupt
	STATUS_TEMP		;storage for STATUS during interrupt
	PCLATH_TEMP		;storage for PCLATH during interrupt
	FSR_TEMP		;storage for FSR during interrupt
	Modes	
	endc		;0x7F

	CBLOCK 	0x20
	CCP1_Mode	;съхраняваме режима на работа на CCP1
	DigVal		;цифрови изходи
	buf_r:.30	;СИ + СП + 6  аналогови + 6 цифрови + СИ
 	CCP1_buf:.2	;буфер за съхранение на CCP1
	CCP1_prev:2	;буфер за съхранение на CCP1
	CCP1_Ti:2	;буфер за изчислената продължителност на импулса

	in_pass		;брояч на миналите приемания на информацията
	CCP1_Tmp	;временна променлива за работа в CCP1	
	
	buf_CCP2:12	;тук ще се съхранява информацията за стойностите за машинките
	Calc_CCP2:2	;изчисленото CCP2  - къде трябва да спре машинката
	CCP2_pass	;за цикъла за обработка на стойностите
	CCP2_tmp:2	;временна променлива
	dig_tmp		;временна промелива за цифровите сигнали
	pass_ix		;брояч за указване коя машинка пускаме
	PPM_ix		;указател за пуснатата машинка
	
	eed		;променлива за работа с EEPROM

	d1	;ЗА ЗАКЪСНЕНИЕТО
	d2

 	endc

	org 0x0000
start 
	nop 
	goto main
	nop
	nop

	org 0x0004
	goto	interrupt


main 
	bsf	    	STATUS, RP0		;bank 1
	movlw   	b'00000111'
    	movwf   	CMCON        ; компараторите - изключени
	movlw		0x06
	movwf		ADCON1
	movlw		0xc0	;6 изхода за дискретни команди
	movwf		TRISA
	movlw		b'11000000'	;6 изхода за аналогови команди
	movwf		TRISB
	movlw		b'11111111'	;всички входове
	movwf		TRISC

	bsf		PIE1,CCP1IE	;enable interrupt CCP1
	bsf		PIE2,CCP2IE	;enable interrupt CCP2	
					;ще се пусне за първи път след приемане на пълен пакет данни
	bcf		PIE2,EEIE	;disable interrupt EEPROM
	bcf		PIE1,TMR1IE		;disable interrupt TMR1
	bsf		PIE1,TMR2IE		;disable interrupt TMR2
					;ще се пусне за първи път след приемане на пълен пакет данни
	movlw		.118
	movwf		PR2		; Fosc/(4*16*(118+1)*7) = 0.0033 S
	movlw		b'01000111'		; вкл притягащите резистори, 
	movwf		OPTION_REG		; TMR0 с предделител 256
	bcf	    	STATUS, RP0		;bank 0

	bcf		INTCON,TMR0IE	;disable interrupt TMR0
 	movlw   	b'00110001'
   	movwf   	T1CON        ; TMR1 - Fosc/4, prescale 8,TMR1 включено
	movlw   	b'00110010'
    	movwf   	T2CON        ; TMR2 - Fosc/4, prescale 16*(118+1)*7,TMR2 включено
				;очаква се да предизвиква прекъсване на 3.3 mS
	clrf		ADCON0	;ADC изключено


	movlw   	b'00000100'	;
	movwf		CCP1_Mode	;запазваме си режима на работа на CCP1
    	clrf	   	CCP1CON        ; Capture mode, every rising
	clrf		CCP2CON		;спираме CCP2

	bsf		INTCON,PEIE	;enable interrupt's
	bsf		INTCON,GIE	;enable interrupt's

	clrf	PORTA
  goto	end_test_start
test_start
;PORTC,2 е установен като изход
 clrf		CCP1CON		;спираме CCP1
 bsf	    	STATUS, RP0		;bank 0
 bcf		PIE2,CCP2IE	;enable interrupt CCP2	
 bcf		PIE1,CCP1IE	;enable interrupt CCP1	
 bcf	    	STATUS, RP0		;bank 0
	movf		CCP1_Mode,w	;запазваме си режима на работа на CCP1
	movwf	   	CCP1CON        ; Capture mode, every rising


ttt
	nop
	nop
	nop
	goto	$-2

	bsf	Modes,6
	btfss	PORTC,2
	bcf	Modes,6
;	bsf	PORTC,2
  	movlw	0xeb
	movwf	TMR1H
	movlw	0xd0
	movwf	TMR1L
	btfss	Modes,6
	bsf	PORTC,2
	btfsc	Modes,6
	bcf	PORTC,2
call 	Delay_19k

rise
	nop
 	btfsc	cin
	goto	check_rise
	goto	rise
check_rise
	nop
	btfss	cin
	goto	rise
	goto	capture

fall
	nop
 	btfsc	cin
	goto	check_fall
	goto	fall
check_fall
	nop
	btfss	cin
	goto	fall
	goto	capture
capture
; movlw		1
 ;xorwf CCP1CON ,f
	bsf	Modes,6
	btfss	PORTC,2
	bcf	Modes,6
;	bsf	PORTC,2
 	movlw	0xf5
	movwf	TMR1H
	movlw	0x90
	movwf	TMR1L
	btfss	Modes,6
	bsf	PORTC,2
	btfsc	Modes,6
	bcf	PORTC,2
 call 	Delay_19k
	bsf	Modes,6
	btfss	PORTC,2
	bcf	Modes,6
;	bsf	PORTC,2
 	movlw	0xff
	movwf	TMR1H
	movlw	0x50
	movwf	TMR1L
	btfss	Modes,6
	bsf	PORTC,2
	btfsc	Modes,6
	bcf	PORTC,2
 call 	Delay_19k
; movlw		1
 ;xorwf CCP1CON ,f
	nop
  st	 0x0603		;1
	nop
ts_loop
 st	 0x09c0		;2
 	nop
 st	 0x07c0		;3
	nop
 st	 0x0501		;4
	nop
 st	 0x0300		;5
	nop
 st	 0x0302		;6
	nop
 st	 0x0180		;7
	nop
 st	 0x0603		;8
	nop
 st	 0x0180		;9
	nop
 st	 0x0504		;10
	nop
 st	 0x0300		;11
	nop
 st	 0x0405		;12
	nop
 st	 0x0180		;13
	nop
 st	 0x06a6		;14
	nop
 st	 0x0300		;15
	nop
 goto	ts_loop

 
end_test_start

 #ifdef	stmacro
	movlw	0xff
	movwf	mtot
	movlw	0x50
	movwf	mtot+1
#endif
	
	movlw		1
	movwf		PPM_ix		;подготвяме за пускане първата машинка
	bcf		sin_ok
	clrf		DigVal
	clrf		in_pass	
	clrf		Modes
	clrf		pass_ix

	movf		CCP1_Mode,w	;запазваме си режима на работа на CCP1
	movwf	   	CCP1CON        ; Capture mode, every rising

main_loop
 st	 0x09c0		;2
 	nop
 st	 0x07c0		;3
	nop
 st	 0x0581		;4
	nop
 st	 0x0300		;5
	nop
 st	 0x0382		;6
	nop
 st	 0x0180		;7
	nop
 st	 0x0683		;8
	nop
 st	 0x0180		;9
	nop
 st	 0x0584		;10
	nop
 st	 0x0180		;11
	nop
 st	 0x0485		;12
	nop
 st	 0x0180		;13
	nop
 st	 0x06a6		;14
	nop
 st	 0x0300		;15
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	goto main_loop


interrupt
	bcf	INTCON, PEIE		; turn off interupts
	movwf	W_TEMP
	swapf	STATUS,w
	movwf	STATUS_TEMP
	clrf	STATUS
	movf 	PCLATH,w	;save PCLath
	movwf 	PCLATH_TEMP	
	clrf 	PCLATH	;assume that this ISR is in page 0
	movf 	FSR,w
	movwf 	FSR_TEMP

interrupt_TMR1
	btfss	PIR1,TMR1IF
	goto		interrupt_CCP2
;	goto	interrupt_TMR2	; не е от TMR1
	bcf		PIR1,TMR1IF
	goto	interrupt_done


interrupt_CCP2
	btfss	PIR2,CCP2IF
	goto	interrupt_TMR2
	bcf		PIR2,CCP2IF
	clrf		PORTB		;свършило е времето за работа на машинката	
	clrf		CCP2CON	;и спираме CCP2
	incf		eed,f
	goto	interrupt_done


interrupt_TMR2
	btfss		PIR1,TMR2IF
	goto		interrupt_CCP1	; не е от TMR2
	bcf		PIR1,TMR2IF
	
	btfss		ready_in	;имаме ли валидни данни
	goto		interrupt_done
	
	movlw		buf_CCP2+1
	movwf		FSR
	btfss		STATUS,C
	rlf		pass_ix,w
	addwf		FSR,f
	incf		FSR,f
	movf		INDF,w
	addwf		TMR1L,w
	movwf		CCPR2L
	decf		FSR,f
	movf		INDF,w
	btfsc		STATUS,C
	incf		INDF,w
	addwf		TMR1H,w
	movwf		CCPR2H
;	clrf		CCP2CON
; incf	eed,f
	movlw		0x0A
	movwf		CCP2CON	;ако сме имали предишен СИ пускаме CCP2
;следващ индекс
	
	incf		pass_ix,f
	movf		pass_ix,w
	sublw		6
	btfsc		STATUS,Z
	clrf		pass_ix
	movf		PPM_ix,w
	movwf		PORTB
	bcf		STATUS,C
	rlf		PPM_ix,f
	movlw		0x41
	btfsc		PPM_ix,6
	xorwf		PPM_ix,f	;нулираме старшия бит и установяваме младшия
	
	goto		interrupt_done

interrupt_CCP1		;приемане на информацията и предварителна обработка
	btfss		PIR1,CCP1IF
	goto		interrupt_done
	bcf		PIR1,CCP1IF
	clrf		CCP1CON	;изключваме CCP1
	
;обръщаме фронта на сработване на CCP1
	movlw		1
	xorwf		CCP1_Mode,w
	movwf		CCP1_Mode
;	movwf		CCP1CON

;запазваме сработилото CCP1
	movf		CCPR1H,w	;запазваме CCPR1H:L  във временна променлива CCP1_prev
	movwf		CCP1_buf
;	btfsc		STATUS,Z	;ако е 0  имаме лъжливо сработване
;	goto	get_tmr1
	movf		CCPR1L,w
	movwf		CCP1_buf+1
;	goto		CCP1_valid_data		
;get_tmr1
;	movf		TMR1L,w
;	movwf		CCP1_buf+1
;	movf		TMR1H,w
;	movwf		CCP1_buf
CCP1_valid_data		
	movf		in_pass,w
	btfss		STATUS,Z	;ако in_pass <> 0
	goto		CCP1_next
in_pass_add	
	goto		incf_pass	; in_pass == 0
;продължаваме с обработката	- in_pass е по голямо или равно на 1
CCP1_next
;да си определим продължителността на импулса
	movf		CCP1_buf+1,w
	subwf		CCP1_prev+1,w
	movwf		CCP1_Ti+1
	btfss		STATUS,C
	decf		CCP1_buf,f
	movf		CCP1_buf,w
	subwf		CCP1_prev,w
	movwf		CCP1_Ti
; определили сме продължителността на импулса
; сега ще си го обработим	
	movlw		buf_r-2
	movwf		FSR
	bcf		STATUS,C
	rlf		in_pass,w
	addwf		FSR,f
	incf		FSR,f
	movf		CCP1_prev+1,w
	subwf		CCP1_buf+1,w
	btfss		STATUS,C
	decf		CCP1_buf,f
	movwf		INDF		;младша част
	decf		FSR,f
	movf		CCP1_prev,w
	subwf		CCP1_buf,w
	movwf		INDF		;старша част
;дали 	in_pass ==1
	movlw		.1	
	subwf		in_pass,w
	btfsc		STATUS,Z
	goto		check_SI
	movlw		.15	
	subwf		in_pass,w
	btfss		STATUS,Z
	goto		incf_pass

check_SI	;ако in_pass==1 или in_pass==15 ще проверяваме за СИ
;ще определяме дали е равно на СИ 0x9C0
;	decf		FSR,F	;вече сме го изчислили и знаем къде е	
	movlw		0x09
	subwf		INDF,w
	btfss		STATUS,Z
	goto		do_not_si
	incf		FSR,f
	movf		INDF,w
	andlw	0x80
	xorlw	0x80
	btfss	STATUS,Z	;младшата част на приетото 0x80 ли е?
	goto	do_not_si
;определили  сме СИ 
;	movlw		0
;	btfsc		sin_ok	;дали сме имали предишен СИ
;	movlw		0x0a
;	movwf		CCP2CON	;ако сме имали предишен СИ пускаме CCP2
	movf		in_pass,w
	btfsc		sin_ok	;дали сме имали предишен СИ
	movlw		1
	movwf		in_pass	;ако сме имали СИ и пак го получаваме in_pass==1
	movlw		0
	btfss		sin_ok	;ако сме имали предишен СИ
	goto		set_si
	movf		INDF,w
	movwf		buf_r+1
	decf		FSR,f
	movf		INDF,w
	movwf		buf_r
;тук ще обработим информацията за предаване на изходите
	movlw		6
	movwf		CCP2_pass	;имаме 6 машинки
CCP2_Calc_Loop
	;вземаме информацията от buf_r + CCP2_pass*4
	movlw		buf_r
	movwf		FSR
	movf		CCP2_pass,w
	movwf		CCP2_tmp
	bcf		STATUS,C
	rlf		CCP2_tmp,f
	rlf		CCP2_tmp,w
	addwf		FSR,f
	decf		INDF,w		;изваждаме 0х100
	movwf		CCP2_tmp	;съхраняваме в междинна променлива
	incf		FSR,f
	movf		INDF,w
	movwf		CCP2_tmp+1
	; подготвяме 	buf_CCP2+CCP2_pass*2
	movlw		buf_CCP2
	movwf		FSR
	bcf		STATUS,C
	rlf		CCP2_pass,w
	addwf		FSR,f
	movf		CCP2_tmp+1,w
	movwf		INDF		;и записваме
	decf		FSR,f
	movf		CCP2_tmp,w
	movwf		INDF		;и записваме
	decfsz		CCP2_pass,f
	goto		CCP2_Calc_Loop
; и цифровите команди
	movlw		6
	movwf		CCP2_pass	;имаме 6 машинки
	clrf		dig_tmp
	movlw		buf_r+8
	movwf		FSR
	movf		CCP2_pass,w
	movwf		CCP2_tmp
	bcf		STATUS,C
	rlf		CCP2_tmp,f
	rlf		CCP2_tmp,w
	addwf		FSR,f
	decf		FSR,f
	decf		FSR,f
dig_Calc_Loop
	movlw		4
	subwf		FSR,f
	decf		INDF,w
	bcf		STATUS,C
	btfss		STATUS,Z
	bsf		STATUS,C
	rlf		dig_tmp,f
	decfsz		CCP2_pass,f
	goto		dig_Calc_Loop
	movf		dig_tmp,w
	movwf		DigVal		;прехвърляме стойността в реалния буфер
	movwf		PORTA		;и на 	PORTA
 	btfsc		ready_in
	goto		set_si		;избягваме повторно предизвикване на прекъсване
	bsf		ready_in	;минал е цял цикъл приемане и е запазена синхронизацията
	bsf	T2CON,2	;TMR2 On	
;	bsf		PIR1,TMR2IF		;и предизвикваме прекъсване по TMR
; call WriteEE
set_si
	bsf		sin_ok
	goto		incf_pass
do_not_si
	clrf		CCP2CON	;спираме CCP2
	clrf		in_pass
	bcf		sin_ok		;нямаме минал СИ
	bcf		ready_in	;нямаме валидна информация
incf_pass
	incf		in_pass,f	
	movf		CCPR1H,w	;запазваме CCPR1H:L  във временна променлива CCP1_prev
	movwf		CCP1_prev
	movf		CCPR1L,w
	movwf		CCP1_prev+1
	movf		CCP1_Mode,w
	movwf		CCP1CON
;	goto	interrupt_done

interrupt_done
	movf 	FSR_TEMP,w
	movwf 	FSR
	movf 	PCLATH_TEMP,w
	movwf	 PCLATH
	swapf	STATUS_TEMP,w
	movwf	STATUS
	swapf	W_TEMP,f
	swapf	W_TEMP,w
	bsf	INTCON,PEIE		;enable interrupt's
	retfie

#ifdef 	stmacro		;само ако се използва st 
delay_200iS
			;798 cycles
	movlw	0x9F
	movwf	d1
	movlw	0x01
	movwf	d2
Delay_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	Delay_0

			;2 cycles
	goto	$+1
	return
#endif

Delay_19k			;19968 cycles
			;19968 cycles
	movlw	0x99
	movwf	d1
	movlw	0x10
	movwf	d2
Delay_19k_loop
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	Delay_19k_loop

	return

WriteEE	;зациклено е
; bsf 	PORTA,0
	movlw	.51
	movlw	0x33

	movwf	eed
	btfsc	Modes,3
	goto	Write_exit
	movlw	0x20
; movlw	wcb
	movwf	FSR		;source
	bsf	STATUS,RP1	;bank 2
	movlw	0x00		;0x2100
	movwf	EEADR
	bsf	STATUS,RP0		;bank 3
	bcf	EECON1, EEPGD	; ще записваме в EEPROM  
	bcf	INTCON,GIE		;малко да спрем прекъсванията
	bsf	EECON1,WREN	;разрешаваме записа
	bcf	STATUS,RP0		;bank 2

write_loop
	movf	INDF,w
	movwf	EEDATA
	bsf	STATUS,RP0	;bank 3
;	btfsc	EECON1,WR
;	goto	$-1
;задължителния код
	movlw	0x55
	movwf	EECON2
	movlw	0xAA
	movwf	EECON2
	bsf	EECON1,WR	;write
;край задължителния код
	btfsc	EECON1,WR
	goto	$-1
	nop
;	bcf	EECON1,WREN	;разрешаваме записа
	bcf	STATUS,RP0	;bank 2
	incf	FSR,f
	incf	EEADR,f
	decfsz	eed,f
	goto	write_loop
	bsf	STATUS,RP0	;bank 3
	bcf	EECON1,WREN	;разрешаваме записа
	bcf	STATUS,RP0		;bank 0
	bcf	STATUS,RP1		;bank 0
	bcf	PIR2,EEIF
	bsf	INTCON,GIE		;малко да пуснем прекъсванията
	bsf	Modes,3


 bcf	INTCON,PEIE		;disable interrupt's

 nop
 nop
 goto $-2
Write_exit
	return

	
;EEPROM данни
	ORG 0X2100
AN_Cor de 0x00,0x01,0x02,0x03

	end