	list p=16F876a
	#include <p16F876a.inc>
 
#define			RS		PORTC,0
#define			RW		PORTC,2
#define			E		PORTC,1


#define		 	Inc		PORTB,4		;b1- increment	
#define			Dec		PORTB,5		;b2-decrement
#define			bckl		PORTA,3
#define 		CS		PORTC,6
#define 		mosfet		PORTC,7
	;Program MEMORY

TEMP_ZAD		equ 	0X20
COUNTER			equ		0x21
LCD_temp		equ		0x22
TEMP_H			equ		0x23
TEMP_L			EQU 	0X24
templcd			EQU 	0X25
BF_temp			equ		0x26
Key_number		EQU 	0X30
NumL			equ		0x31
NumH			equ		0x32
TenK			equ		0x33
Thou			equ		0x34
Hund			equ		0x35
Tens			equ		0x36
Ones			equ		0x37
Point			equ		0x38
LCD_flags		equ		0x39
D_COUNTER		equ		0x3A
templcd2		equ		0x3B
	
		ORG 	H'0000'
		GOTO	START

		ORG		H'0004'
		GOTO	Interrupt
;***********************************************************************
;Inicializaciq

START:
				banksel	TRISB
				MOVLW	B'00110000'
				MOVWF	TRISB
				banksel	OPTION_REG	
				MOVLW	B'00010010'				
				MOVWF	OPTION_REG
				banksel	TRISA					
				MOVLW	B'00000000'
				MOVWF	TRISA
				banksel	TRISC		
				MOVLW	B'00001000' 	;5bit 0
				MOVWF	TRISC				
				clrf	TEMP_ZAD
				clrf	TEMP_H
				clrf	TEMP_L
																			
INIT_LCD
	;Initalize LCD
		movlw	d'255'			;wait 255mS
		call	Wait

		movlw	b'00000011'
		movwf	PORTB
	
		call	Pulse_e
		movlw	d'10'
		call	Wait

		movlw	b'00000011'
		movwf	PORTB
		call	Pulse_e
		movlw	d'5'
		call	Wait

		movlw	b'00000011'
		movwf	PORTB
		call	Pulse_e
		movlw	d'5'
		call	Wait

;&&&&&&&&&&&&&

		movlw	b'00000010'		;set 4 bit comunication mode
		movwf	PORTB
		call	Pulse_e

;&&&&&&&&&&&&&

		movlw	b'00101000'		;N,F
		call	LCD_CMD			;

		movlw	b'00001100'		;DISPLAY OFF
		call	LCD_CMD			;

		movlw	b'00000001'		;DIPLAY ON
		call	LCD_CMD			;

		movlw	b'00000110'		;entry mode, inc, no shift
		call	LCD_CMD		;
	
;INIT_SPI								
				banksel	SSPSTAT
				MOVLW	B'01000000'		;D. se predawat po narastwasht front na takta
				MOVWF	SSPSTAT	
				banksel	SSPCON		;aktiwno niwo 0							
				MOVLW	B'00110010'		;Rejim SPI master, Takt=Fosc/64
				MOVWF	SSPCON
				banksel	INTCON
				MOVLW	B'11001000'
				MOVWF	INTCON
;***********************************************************************

;***********************************************************************
MAIN_loop			
				
				call	Screen_1
				
Repeat				bcf	CS		;chip selekt tc77-ON
				BCF 	mosfet		;turn of transistor
				banksel	SSPCON
begin				bsf	SSPCON,SSPEN	;turn on SPI
				banksel	SSPSTAT
				bcf   	SSPSTAT,BF
				
				btfss   SSPSTAT,BF	;Check BF
				goto	$-1
				banksel	SSPBUF
				movf	SSPBUF,w	;read BUFER	
				movwf	TEMP_H
				banksel	SSPSTAT
				bcf		SSPSTAT,BF						
				btfss	SSPSTAT,BF		;Check BF
				goto 	$-1
				banksel	SSPBUF	
				movf	SSPBUF,w	;read BUFER
				movwf	TEMP_L	
							
				bcf		SSPCON,SSPEN		;Turn_off SPI
				bsf		CS			;chip selekt tc77-on			
				call	Screen_1
				movf	TEMP_H,w		;compare TEMP_H with 
				subwf	TEMP_ZAD,w		;TEMP_ZAD
				btfss	STATUS,C
				goto	Repeat
				bsf		mosfet
				banksel	SSPCON
				goto 	begin
;**********************************************************************
Interrupt		
check_buttons	bcf		INTCON,GIE	
				btfss	INTCON, RBIF			
				goto	end_int
			;	call	Check_keys		;proveri broq na natisnatite butoni
			;	movf	Key_number,w		;Key-number--w
			;	btfsc	STATUS,Z		;nqma natisnati klavi6i
			;	goto 	end_int
			;	xorlw	H'01'			;Wx00000001
			;	btfss	STATUS,Z		;edin buton li e natisnat
			;	goto 	end_int
				movlw	d'5'
				call 	Wait			; izchakaj 10ms				
				btfss	Inc
				goto	Increment		
				
Next			btfss 	Dec
				goto 	Decrement
				goto	end_int
Increment			
				incf  	TEMP_ZAD,f		;TEMP_ZAD+1
				movf	TEMP_ZAD,w				
				sublw	B'01111110'		;TEMP_ZAD = 127 ???
				btfsc	STATUS,Z
				goto	Decrement		;Da,idi na TEMP_ZAD-1
				call 	Screen_1		;ne,pokaji go na displ
				movlw	d'255'	
				call	Wait			;izchakai 300ms
				btfss 	Inc
				goto 	Increment
				goto	end_int
Decrement
				decf  	TEMP_ZAD,f
				movf	TEMP_ZAD,w
				sublw	B'10000001'		;TEMP_ZAD = -127 ???
				btfsc	STATUS,Z
				goto	Increment
				call 	Screen_1
				movlw	d'255'				
				call	Wait			;izchakai 300ms
				btfss 	Dec
				goto 	Decrement
				goto	end_int
end_int				
				
				bcf	INTCON,RBIF
				bsf	INTCON,GIE		
			retfie
;**********************************************************************
;SUBROUTINES
;**********************************************************************
Check_keys			clrf	Key_number	;Key-number=0
				btfss	Inc
				incf	Key_number,w
				btfss	Dec
				incf	Key_number,w
			return

;***********************************************************************

LCD_busy
	banksel		TRISB			;select bank 1
		movlw	b'00111111'		;PortB,4;7 pins inputs
		movwf	TRISB			;
	banksel		PORTB			;select bank 0
Busy_loop
		
		bcf		RS				;clear RS - command mode
		bsf		RW				;set R/W - read mode
	nop
		bsf		E				;Pulse E line high
		movf	PORTB,w	
			
		bcf		E
		movwf	templcd2
		bcf		RS				;clear RS - command mode
		bsf		RW				;set R/W - read mode
	nop
		bsf		E				;Pulse E line high (dummy read lower nibble)
		nop						;read upper nibble (busy flag)			
		bcf		E
				

		btfsc	templcd2,3		;check busy flag, high = busy
		goto	Busy_loop		;busy -> check again
		bcf		RW				;no -> clear R/W - write mode
	banksel		TRISB			;select bank 1
		movlw	b'00110000'		;all Port B pins outputs
		movwf	TRISB			;
	banksel		PORTB			;select bank 0
	return
;***********************************************************************
LCD_CMD
		movwf	templcd			;load command
	
		call 	LCD_busy
	
		swapf	templcd,w		;send lower nibble
					
		andlw	b'00001111'		;clear lower 4 bits of port B
		movwf	PORTB			;
		bcf		RS
		bcf		RW
		call	Pulse_e			;Pulse the E line high
	
	
		call 	LCD_busy
	
		movf	templcd,w
		andlw	b'00001111'		;clear lower 4 bits of port B
		movwf	PORTB			;
		bcf		RS
		bcf		RW
		call	Pulse_e			;Pulse the E line high
	

	retlw		0x00
;***********************************************************************

LCD_CHAR
		movwf	templcd			;load char	
		call 	LCD_busy
		swapf	templcd,w		;send upper nibble
		andlw	b'00001111'		;
		movwf	PORTB			;
		bcf		RW
		bsf		RS				;RS line to 1
		call	Pulse_e			;Pulse the E line high
	
	
		call 	LCD_busy

		movf	templcd,w	
		andlw	b'00001111'		;clear lower 4 bits of port C
		movwf	PORTB			;
		bcf		RW				;
		bsf		RS				;RS line to 1
		call	Pulse_e			;Pulse the E line high

	retlw		0x00
;***********************************************************************

Pulse_e
		bsf		E
	nop
		bcf		E
	return
;***********************************************************************

LCD_Line1
		movlw	0x80			;move to 1st row, first column
		call	LCD_CMD
	retlw		0x00
;***********************************************************************

LCD_Line2
		movlw	0xc0			;move to 2nd row, first column
		call	LCD_CMD
	retlw		0x00
;***********************************************************************

LCD_Clr
		movlw	0x01			;Clear display
		call	LCD_CMD
	retlw		0x00
;***********************************************************************

Delay
		movwf	D_COUNTER
D_loop
		movlw	d'255'
		call	Wait
		decfsz	D_COUNTER,f
		goto	D_loop
	return
;***********************************************************************

Wait
		movwf	COUNTER
		bcf		STATUS,RP0
		clrf	TMR0
again	bcf		INTCON,T0IF		;нулиране на флаговия бит на таимер 0
loop	btfss	INTCON,T0IF		;проверка на флаговия бит
		goto	loop
		decfsz	COUNTER,f
		goto	again
	return
;***********************************************************************
LCD_Decimal
					
				call    Convert
				btfss   LCD_flags,0
				goto	$+4
				btfsc	LCD_flags,1
				goto	LCD_HUND
				goto	LCD_TENS
				movf    Hund,w
				btfss   STATUS, Z
				goto    LCD_HUND
				movf    Tens,w
				btfss   STATUS, Z
				goto    LCD_TENS
				goto    LCD_ONES
LCD_HUND
				movf    Hund, w
				addlw	0x30			;add 0x30 to convert to ASCII
				call    LCD_CHAR
				movlw	0x02			;test if decimal point 2
				subwf   Point, w
				btfss   STATUS    , Z
				goto	LCD_TENS
				movlw	'.'
				call	LCD_CHAR		;display decimal point
LCD_TENS
				movf	Tens,w
				addlw	0x30			;add 0x30 to convert to ASCII
				call	LCD_CHAR
				movlw	0x01			;test if decimal point 1
				subwf	Point,w
				btfss	STATUS,Z
				goto	LCD_ONES
				movlw	'.'
				call	LCD_CHAR		;display decimal point
LCD_ONES
				movf	Ones, w
				addlw	0x30			;add 0x30 to convert to ASCII
				call	LCD_CHAR
				retlw	0x00
;***********************************************************************
Convert
				swapf	NumH,w
				iorlw	b'11110000'
				movwf	Thou
				addwf	Thou,f
				addlw	0XE2
				movwf	Hund
				addlw	0X32
				movwf	Ones
		
				movf	NumH,w
				andlw	0X0F
				addwf	Hund,f
				addwf	Hund,f
				addwf	Ones,f
				addlw	0XE9
				movwf	Tens
				addwf	Tens,f
				addwf	Tens,f
		
				swapf	NumL,w
				andlw	0X0F
				addwf	Tens,f
				addwf	Ones,f
		
				rlf		Tens,f
				rlf		Ones,f
				comf	Ones,f
				rlf		Ones,f
		
				movf	NumL,w
				andlw	0X0F
				addwf	Ones,f
				rlf		Thou,f
		
				movlw	0X07
				movwf	TenK
		
		;At this point, the original number is
		;equal to
		;TenK*10000+Thou*1000+Hund*100+Tens*10+Ones
		;if those entities are regarded as two's
		;complement binary.  To be precise, all of
		;them are negative except TenK.  Now the number
		;needs to be normalized, but this can all be
		;done with simple byte arithmetic.
		
				movlw	0X0A                             ; Ten
Lb1:
				addwf	Ones,f
				decf	Tens,f
				btfss	3,0
				goto	Lb1
Lb2:
				addwf	Tens,f
				decf	Hund,f
				btfss	3,0
				goto	Lb2
Lb3:
				addwf	Hund,f
				decf	Thou,f
				btfss	3,0
				goto	Lb3
Lb4:
				addwf	Thou,f
				decf	TenK,f
				btfss	3,0
				goto	Lb4
			retlw		0x00
;***********************************************************************
Screen_1_neg	movlw	'-'
				call	LCD_CHAR
				comf	TEMP_ZAD,w
				addlw	b'00000001'
				return
;***********************************************************************
Screen_1		bcf		INTCON,RBIE
				bsf		bckl		
				call	LCD_Clr
				call	LCD_Line1
				movf	TEMP_ZAD,w
				btfsc	TEMP_ZAD,7
				call	Screen_1_neg					
				movwf	NumL
				clrf	NumH	
				call	LCD_Decimal
				movlw	B'11011111'
				call	LCD_CHAR
				movlw	'C'
				call	LCD_CHAR
				movlw	' '
				call	LCD_CHAR
				movlw	'Z'
				call	LCD_CHAR
				movlw	'a'
				call	LCD_CHAR
				movlw	'd'
				call	LCD_CHAR
				movlw	'a'
				call	LCD_CHAR
				movlw	'd'
				call	LCD_CHAR
				movlw	'e'
				call	LCD_CHAR
				movlw	'n'
				call	LCD_CHAR
				movlw	'a'
				call	LCD_CHAR
			;	movlw	d'1'			;wait 800mS
			;	call	Delay
line2			call	LCD_Line2
				movf	TEMP_H,w
				btfsc	TEMP_H,7
				call	Screen_1_neg				
				movwf	NumL
				clrf	NumH
				call	LCD_Decimal
				movlw	B'11011111'
				call	LCD_CHAR
				movlw	'C'
				call	LCD_CHAR
				movlw	' '
				call	LCD_CHAR				
				movlw	'I'
				call	LCD_CHAR
				movlw	'z'
				call	LCD_CHAR
				movlw	'm'
				call	LCD_CHAR
				movlw	'e'
				call	LCD_CHAR
				movlw	'r'
				call	LCD_CHAR
				movlw	'e'
				call	LCD_CHAR
				movlw	'n'
				call	LCD_CHAR
				movlw	'a'
				call	LCD_CHAR
			;	movlw	d'10'
			;	call	Delay
				bcf		bckl		;turn LCD backlight off
				bsf		INTCON,RBIE			
			retlw		0x00


;***********************************************************************
			END




