;****************************************************************************************
;* PIC microprojekt														Date: 13.01.10	*
;*																						*
;* FILE: ADC-Step.asm				 									Navn: GC		*
;*  																					*
;* Device: PIC16F684																	*
;*																						*
;*																						*
;* 																						*
;* 																						*
;* ADC-value controles step frequency on DS1 to DS4 on PICkit 2							*
;*																						*
;****************************************************************************************

;		H'<HEX>'		D'<Decimal>'		B'<Binary>'			A'<ASCII>'

; 	Registers og konstants are defined here:


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, A/D Control register

; 	RAM-registers used by routines:
Ux		equ	H'20'	; Ux? (A/D Converter)

Dly_1	equ H'23'	; Delay
Dly_2	equ H'24'	; Delay2
Dly_3	equ H'25'	; Delay3
Tmp_1	equ H'26'	; 
Tmp_2	equ H'27'	; 
Tmp_3	equ H'28'	; 

	;	Definitions:
#define	Out_1	PORTC,0	; DS1
#define	Out_2	PORTC,1	; DS2
#define	Out_3	PORTC,2	; DS3
#define	Out_4	PORTC,3	; DS4

		list p=16F684

		org		H'05'		; Start of program  (05)


;*************************************** Chip setup *************************************


;Bank_1
		bsf		STATUS,5	; Switch to Bank-1 for chip-setup

;PORT_A						; 
		movlw	B'111111'	; PORTA= inputs (Tristate)
		movwf	TRISA		; RA0 is ADC-input
 
;PORT_C						; 
		clrf	TRISC		; PORTC= Outputs (TRISC<5:0>= 000000)

;ADC_in						; Setup of analog input for ADC
		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

		movlw	H'07'		; CM<2:0>=111	=>			!!! IMPORTANT !!!
		movwf	CMCON0		; Disable comparator, 		General purpos I/O

;ADC						; Setup of ADC
		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 Bussy test bit
							; Bit0=1:	-------1, Turns on A/D Converter

		clrf	PORTC		; PORTC Outputs are cleared

		goto	start


;***********************************    Subroutines   ***********************************

		;	Short delays used by:	Delay2, Ux?, 
Delay1	movwf	Dly_1		; Store W in Dly_1
lp_d1	decfsz	Dly_1,f		;   
		goto	lp_d1		; 
		return				; Delay= (1+(1+3<Dly_1>+2))*4TC

		; 	Long delays 
Delay2	movwf	Dly_2		; Store W in Dly_2
lp_d2	movlw	H'FF'		
		call	Delay1
		decfsz	Dly_2,f
		goto	lp_d2
		return


		;	Reads ADC-value 
Ux?		bsf		ADCON0,0	; Turn on ADConverter
		movlw	D'4'		; W contains delay-value for Dly_1
		call	Delay1		; Delay1
		bsf		ADCON0,1	; GO, Start A/D conversion
loop1	btfsc	ADCON0,1	; Done ?	(Bit1: ADC Start and Busy test-bit)
		goto	loop1		; No, try again
		movf	ADRESH,w	; Yes, 
		movwf	Ux			; Store result in Ux
		movwf	Tmp_1		; Store a copy in Tmp_1
		comf	Tmp_1,f		; Complement Tmp_1
		incf	Tmp_1,f		; Make Tmp_1 > 0
		bcf		ADCON0,0	; Turn off A/D Converter
		return				; Go back to Main program


		;	Pulse time is generated acording to ADC value
T_stp	movf	Tmp_1,w		; Get delay-value
		call	Delay2		; Delay acording to ADC
		bcf		STATUS,0	; Clear C-bit
		rrf		Tmp_2,f		; Prepare for next step
		movf	Tmp_2,w
		btfss	STATUS,2	; Through all 4 steps ?
		return
		movlw	B'1000'		; New sequense
		movwf	Tmp_2
		return


		;	Steps on LED: DS1 to DS4.  Uses ADC as input to Delay routine
Step_1	call	Ux?			; Read ADC!
		movf	Ux,w
		btfsc	STATUS,2	; Ux > 0 ?
		return
		bsf		Out_1		; Out_1 ON
		bcf		Out_4		; Out_4 OFF
		call	T_stp		; Pulse time
		return

Step_2	call	Ux?			; Read ADC!
		movf	Ux,w
		btfsc	STATUS,2	; Ux > 0 ?
		return
		bsf		Out_2		; Out_2 ON
		bcf		Out_3		; Out_3 OFF
		call	T_stp		; Pulse time
		return

Step_3	call	Ux?			; Read ADC!
		movf	Ux,w
		btfsc	STATUS,2	; Ux > 0 ?
		return
		bcf		Out_1		; Out_1 OFF
		bsf		Out_4		; Out_4 ON
		call	T_stp		; Pulse time
		return

Step_4	call	Ux?			; Read ADC!
		movf	Ux,w
		btfsc	STATUS,2	; Ux > 0 ?
		return
		bcf		Out_2		; Out_2 OFF
		bsf		Out_3		; Out_3 ON
		call	T_stp		; Pulse time
		return


		;	Steps through 4 phases (if Ux is greter than zero)
Step	btfsc	Tmp_2,3
		call	Step_1
		btfsc	Tmp_2,2
		call	Step_2
		btfsc	Tmp_2,1
		call	Step_3
		btfsc	Tmp_2,0
		call	Step_4
		return


;************************************* Main program *************************************

	
start	clrf	PORTC
		movlw	B'1000'		; Ready for first step
		movwf	Tmp_2

New		call	Step		; Show steps on DS1 to DS4
		goto	New			; New measurement

		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)
