;************************************************************************
;*																		*
;* Device: PIC16F684		FILE: Interupt2-2			Date: 07.02.10	*
;*  																	*
;* Activation of RA3 (SW1) Generates Interupt and turns on Led DS2		*
;* Ux greater than Ref_2 Resets DS2 and turns on Led DS1				*
;*																		*
;*																	GC	*
;************************************************************************

;		H'<HEX>'	D'<Decimal>'	B'<Binary>'		A'<ASCII>'

; 		Registers and constants are defined here:
INDF		equ H'00'		; Indirect Register (Uses content of FSR)
PCL			equ H'02'		; Program Counter Low byte address
STATUS		equ	H'03'		; Status-register
FSR			equ H'04'		; Indirect Data Memory Address Pointer
PORTA		equ	H'05'		; Input/output-register A
TRISA		equ	H'05'		; Bank-1, input/output configuration A
PORTC		equ	H'07'		; Input/output-register C
TRISC		equ	H'07'		; Bank-1, input/output configuration C

INTCON		equ H'0B'		; Interupt Control register (Enable-bits/Flags)		<<<<== Interupt
IOCA		equ H'16'		; Bank-1 (96h):	Interupt On Change on Port A

CMCON0		equ H'19'		; Comparator control register
ANSEL		equ H'11'		; Bank-1, Analog select register (A/D conversion Clock)
ADRESH		equ H'1E'		; A/D result
ADRESL		equ H'1E'		; Bank-1, A/D result
ADCON0		equ H'1F'		; A/D Control register 
ADCON1		equ H'1F'		; Bank-1, A/D Control register

; 		RAM-registers used by routines:
Ux			equ	H'20'		; Ux? (A/D Converter)
Ref_1		equ	H'21'		; Low_?
Ref_2		equ H'22'		; High_?
Dly_1		equ H'23'		; Delay1
Dly_2		equ H'24'		; Delay2

W_tmp		equ H'25'		; W-register content is stored here
Status_tmp	equ H'26'		; STATUS-register content is stored here



	;	Definitions:
#define	Out_1	PORTC,0		; DS1
#define	Out_2	PORTC,1		; DS2


		list p=16F684

		org		H'00'		; Start of code
		goto	Init		; Reset Vector 	(0x0000)
		nop					;
		nop					;
		nop					;
		goto	Isr			; ISR Vector	(0x0004)

;*********************      Chip setup      *************************

Init						; Start of chip setup

;Bank_1	
		bsf		STATUS,5	; Switch to Bank-1

		bsf		IOCA,3		; Enable Interupt from SW1 on PICkit1				<<<<== Interupt

		movlw	B'11001111'	; RA0 is ADC-input
		movwf	TRISA		; RA5 and RA4 are digital outputs
							; RA3, RA2 and RA1 are digital inputs (Tristate)

		clrf	TRISC		; PORTC= Outputs (TRISC<5:0>= 000000)
							; Bit5=RS, Bit4=Strobe, Bit<3:0>=Data (Nibble)

		movlw	B'00000001'	; RA0: ADC-Input, All other pins = digital I/O
		movwf	ANSEL		; 
		movlw	B'00010000' ; Bit<6:4> A/D Clock=Fosc/8
		movwf	ADCON1

;Bank_0	
		bcf		STATUS,5	; Switch back to Bank-0

;Coparators off
		movlw	H'07'		; CM<2:0>=111			<=	!!! IMPORTANT !!!
		movwf	CMCON0		; Disable comparators 		General purpos I/O

;ADC setup
		movlw	B'00000000'	; Bit7=0:	0-------, Makes A/D Result Left justified (8 Bits used)
							; Bit6=0:	-0------, Vref for A/D =VDD
		movwf	ADCON0		; Bit<4:2>	---000--, Channel 0 selected: RA0/AN0= ADC-input
							; Bit1:		------1-, A/D start and Busy test bit
							; Bit0=1:	-------1, Turns on A/D Converter
;References
		movlw	D'85'		; Ref_1	:	Low limit
		movwf	Ref_1		; (85/255:  ca.33%)

		movlw	D'170'		; Ref_2	:	High limit
		movwf	Ref_2		; (170/255: ca.66%)


;Interupt control setup		 													<<<<== Interupt
		bcf		INTCON,0	; Clear Interupt-flag for SW1 (Caused by pull-up resistor)
		bsf		INTCON,3	; Enable Interupt (RAIF) from SW1 on RA3 PORTA
		bsf		INTCON,7	; Enable global interupt-bit GIE

; Initial setting of ports
		clrf	PORTA		; PORTA Outputs are cleared (LED's off)
		clrf	PORTC		; PORTC Outputs are cleared

		goto	Start


;*******************    Subroutines   *********************

		;	Short delays used by:	Ux?, Strobe, Dis_txt, Delay2
Delay1	movwf	Dly_1		; Store W in Dly_1
lp_d	decfsz	Dly_1,f		;   
		goto	lp_d		; 
		return

		; 	Long delays used by:	Various Display-routines
Delay2	movwf	Dly_2		; Store W in Dly_2
		movlw	H'00'		
lp_d2	call	Delay1		; 
		decfsz	Dly_2,f
		goto	lp_d2
		return

		;	Reads A/D Converter value
Ux?		bsf		ADCON0,0	; Turn on A/D Converter
		movlw	D'4'		; W contains delay-value for Dly_1 (23h)
		call	Delay1		; Delay
		bsf		ADCON0,1	; GO, Start A/D conversion
loop1	btfsc	ADCON0,1	; Done ?	(Bit1: A/D Start and Busy test-bit)
		goto	loop1		; No, try again
		movf	ADRESH,w	; Yes, 
		movwf	Ux			; store result in Ux
		bcf		ADCON0,0	; Turn off A/D Converter
		return				; Go back to Main program

		;	Checks if Ux exceeds Ref_2 value 
High_?	movf	Ref_2,w		; Get Ref_2 to W
		subwf	Ux,w		; Subtract Ref2 from Ux
		btfss	STATUS,0	; Ux > Ref_2 ?			(C-bit=1)
		return				; No, Go back to Main program
		clrf	PORTC
		bsf		Out_1		; Yes, Switch on Led DS1
		return				; Go back to Main program

;*******************     Interupt-routine(s)    *********************

Isr		bcf		INTCON,7		; Disable further interupts !

Push	movwf	W_tmp			; Save W-content
		swapf	STATUS,w		; Swap STATUS to be savwed into W
		clrf	STATUS			; Bank 0, regardless of current bank, clears IRP, RP1, RP0
		movwf	Status_tmp		; Save STATUS in Status_temp register

Isr_A	movf	PORTA,f			; Read PORTA for reference on next change 
		clrf	PORTC			; Turn off DS1. 			<<==	Interupt caused by SW1 
		bsf		Out_2			; Turn on  DS2
		movlw	H'FF'			; Test-Delay				(Enables to see blink on DS2)
		call	Delay2
		bcf		INTCON,0		; Reset Interupt-flag for SW1

Pop		swapf	Status_tmp,w	; Swap Status_temp register into W
								; (sets bank to original state)
		movwf	STATUS			; Restore STATUS register content.
		swapf	W_tmp,f			; 
		swapf	W_tmp,w			; Restore W-register content
		retfie					; GIE=1, ready for new interupts

;*********************       Main program       *********************

Start	
New		call	Ux?			; Read ADC!
		call	High_?		; Ux > Ref_2	=> Reset, Led DS1 = ON	
		goto	New			; New mesurement

		end					; Program ends here



;*********************************** Programming a Device *******************************

;	  Select:
;
;	1.Configure		Select Device...	16f684
;	2.Configure		Configuration Bits	Clock:								Internal-RC,-
;																			No Clock
;
;										WatchDogTimer:						Off
; 										Master Clear Enable:				Internal
; 										Internal External Switch Over Mode:	Disabled
; 										Monitor Clock Fail-safe: 			Disabled
;
;	3.Project		Quickbuild 	*.asm
;	4.Programmer	Select Programmer	(PICkit 2)
;	5.Programmer	Program Device 		(Or Yellow Icon)
