;********************************************************************************
;*							-  PIC microprojekt  -								*
;*																				*
;* FILE: ADC4-2Reg.asm			  Regulator					Date:	16.01.06	*
;*  														Rev.	29.12.09 	*
;* Device: PIC16F684										Navn: 	GC			*
;*																				*
;* Led: DS1 is controled by limits for Ux										*
;* Led: DS2 is controled by target MCLR: H/L 	(Or the switch: SW1)			*
;********************************************************************************

;	H'<HEX>'	D'<Decimal>'	B'<Binary>'

; 	Registre og konstanter er defineret her:

STATUS	equ	H'03'	; Status-register
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

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, Analog select register (A/D conversion Clock)

Ux		equ	H'20'	; RAM-register 
Ref_1	equ	H'21'	; RAM-register 
Ref_2	equ H'22'	; RAM-register 
Dly		equ H'23'	; RAM-register

		list p=16F684

		org		H'05'		; Start of program  (05)

;********************************** Chip setup **********************************

init

;Bank-1						;Switch to Bank-1 for setup
		bsf		STATUS,5	; 

		movlw	B'001111'	; RA5 and RA4 are digital outputs
		movwf	TRISA		; RA3, RA2 and RA1 are digital inputs (Tristate)
							; RA0 is ADC-input

		clrf	TRISC		; PORTC= Outputs (<TRISC5:TRISC0>= 000000)
		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						; Switch back to Bank-0
		bcf		STATUS,5	; 
		movlw	H'07'		; CM<2:0>=111			<=		!!! IMPORTANT !!!
		movwf	CMCON0		; Disable comparator, 			General purpos I/O

		movlw	B'00000000'	; Bit7=0:	Makes A/D Result Left justified (8 Bits used)
							; Bit6=0:	Vref for A/D =VDD (+5V)
		movwf	ADCON0		; Bit<4:2>	=0, Channel 00 selected: RA0/AN0= ADC-input
							; Bit1:		A/D start and Busy test bit
							; Bit0=1:	Turns on A/D Converter


		movlw	D'85'		; Ref_1	:	Low limit
		movwf	Ref_1		; (ca.33%)

		movlw	D'170'		; Ref_2	:	High limit
		movwf	Ref_2		; (ca.66%)

		clrf	PORTA		; PORTA Outputs are cleared (LED's off)
		clrf	PORTC		; PORTC Outputs are cleared

		goto	start		; End of chip setup


;*******************************   Subroutines   ********************************

Delay	movwf	Dly			; Store W in Dly (23h)
lp_d	decfsz	Dly,f		; Delay: Used by Ux? 
		goto	lp_d		; Delay= 1+(1+3<Dly>+2)*4TC
		return


Ux?		bsf		ADCON0,0	; Turn on A/D Converter
		movlw	D'4'		; W contains delay-value for Dly (23h)
		call	Delay		; Delay
		bsf		ADCON0,1	; GO, Start A/D conversion
loop1	btfsc	ADCON0,1	; Done ?	(Bit1: A/D Start and Bussy 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


Low_?	movf	Ux,w		; Get Ux to W
		subwf	Ref_1,w		; Subtract Ux from Ref_1
		btfss	STATUS,0	; Ux < Ref_1 ?
		return				; No, Go back to Main program
		bcf		PORTC,0		; Yes, Switch off Led: DS1.
		return				; Go back to Main program


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
		bsf		PORTC,0		; Yes, Switch on Led: DS1.
		return				; Go back to Main program


Switch	btfsc	PORTA,3		; Is SW1= ON?	(Input low)
		return				; No, proceed
		bsf		PORTC,1		; Yes, turn on Led: DS2
lp_k	btfss	PORTA,3		; SW1 still ON?
		goto	lp_k		; Yes, check again!
		bcf		PORTC,1		; No, turn off Led: DS2
		return				; Proceed



Alarm						; Code for unexpected Ux-values comes here.


;********************************* Main program *********************************
	
start	call	Ux?			; Read ADC
		call	Low_?		; Ux < Ref_1		=> Led: DS1 = OFF
		call	High_?		; Ux > Ref_2		=> Led: DS1 = ON
		call	Switch		; MCLR/SW1 activated?
		goto	start		; New mesurement

		end					; Program ends here


;******************************* Programming a Device ***************************

;			Select:

;		1.	Configure	Select Device...		16f684
;		2.	Configure	Configuration Bits... 	(See 2.Clock: below)
;		3.	Project		Quickbuild 	*.asm
;		4.	Programmer	Select Programmer		PICkit 2
;		5.	Programmer	Program Device			(Or Yellow Icon)
;
;		2.	Clock:								Internal-RC, No Clock
; 			WatchDogTimer:						Off
; 			Master Clear Enable:				Internal
; 			Internal External Switch Over Mode:	Disabled
; 			Monitor Clock Fail-safe: 			Disabled
