	title  "Test of A/D, by PEK"

;
; Test of A/D for PIC16F876
;


	list P=16F876, R=DEC

	include "P16F876.inc"

	__config _CP_OFF & _WDT_OFF & _PWRTE_OFF & _HS_OSC


;
; Registers
;
_w		equ 0x20			; All banks blocked at 0x20
_status	equ 0x21
_pclath	equ 0x22
_fsr	equ 0x23


;	code

; **************************************
; Start of Program
; **************************************
	org		0
	pagesel	Main
	goto		Main

	org		4
	pagesel	Interrupt_Routine
	goto		Interrupt_Routine


; **************************************
; ISR
; **************************************
Interrupt_Routine
	movwf		_w			; save W
	movf		STATUS,w
	clrf		STATUS		; force to page 0
	movwf		_status		; save STATUS
	movf		PCLATH,w
	movwf		_pclath		; save PCLATH
	movf		FSR,w
	movwf		_fsr			; save FSR

	banksel	PIR1

	pagesel	TimerInt
	btfsc		PIR1,CCP1IF		; Timer Compare Match?
	goto		TimerInt

	pagesel	ADInt
	btfsc		PIR1,ADIF		; AD Done?
	goto		ADInt

End_ISR
	clrf		STATUS		; select bank 0
	movf		_fsr,w		; restore the FSR
	movwf		FSR
	movf		_pclath,w		; restore PCLATH
	movwf		PCLATH
	movf		_status,w		; restore STATUS
	movwf		STATUS
	swapf		_w,f			; restore W without corrupting STATUS
	swapf		_w,w
	retfie

; Timer Compare Match Interrupt
TimerInt
	bsf		ADCON0,GO		; Start A/D conversion
	bcf		PIR1,CCP1IF		; Clear flag
	clrf		TMR1L			; Init Timer value
	clrf		TMR1H
	goto		End_ISR

; AD Done Interrupt
ADInt
	movf		ADRESH,w		; Copy the higher byte to PortB
	movwf		PORTB
	bcf		PIR1,ADIF		; Clear flag
	goto		End_ISR


; **************************************
; Main
; **************************************
Main

; Init Ports
	banksel	TRISB
	clrf		TRISB			; PortB as output
	movlw		0x01
	movwf		TRISA			; RA0 as input

; Init A/D
	banksel	ADCON1
	clrf		ADCON1		; Left justified, all pins as A/D
	bsf		PIE1,ADIE		; Enable A/D interrupts
	banksel	ADCON0
	movlw		0x81
	movwf		ADCON0		; FOSC/32, Chan 0, A/D on

; Init Timer
	banksel	PIE1
	bsf		PIE1,CCP1IE		; Enable TMR1 compare interrupt
	banksel	CCP1CON
	movlw		0x0A
	movwf		CCP1CON		; Compare mode - generate interrupt on match
	movlw		62
	movwf		CCPR1L		; Compare value - lower byte
	movlw		73
	movwf		CCPR1H		; Compare value - higher byte : (62+73*256)*8 = 100ms at 6MHz
	clrf		TMR1L			; Init Timer value
	clrf		TMR1H
	movlw		0x3D
	movwf		T1CON			; 1:8, Oscillator enabled, Internal clock, Timer on

	bsf		INTCON,PEIE		; Enable peripheral interrupts
	bsf		INTCON,GIE		; Enable all interrupts

; Init Registers


Loop


	pagesel	Loop
	goto		Loop


	end

