;*******************************************************
;dbt_pwm_qrtr_sinwave
;Demonstrates quarter sin wave output, on CCP1
;Uses full ten bits of PWM period setting
;TJW 9.7.05								Tested 11.7.05
;*******************************************************
;Clock is 4MHz
;
	list 	p=16F873A
	#include p16f873A.inc
;
;Set Configuration Word: crystal oscillator HS, WDT off, 
;     power-up timer on, code protect off, LV Program off.
	__CONFIG _HS_OSC & _WDT_OFF & _PWRTE_ON & _LVP_OFF
;
;Specify RAM
delcntr1 equ	20	;used in delay5 & delayADC SRs
delcntr2 equ	21
pointer  equ	22
temp 	 equ	23
	
;Specify some port bits
;For Port A
mot_en_rt 	equ	2
mot_en_left	equ	5

;For Port B
sounder		equ	1	;piezo electric sounder
us_rt		equ 6	;right microswitch
us_left		equ 7	;left microswitch

;For PortC
mot_left 	equ 1	;left motor direction bit, 1=forward
mot_rt 		equ 2	;right motor direction bit
led_rt		equ 5	;diagnostic led
led_left	equ 6	;diagnostic led
mode		equ	7	;mode switch

	org 00
;Initialise
;set up SFRs in Bank 1
	bcf	status,rp1
	bsf		status,rp0 	;select memory bank 1
	movlw	B'00011011'	;set port A bits, bit 4 ip for opto
	movwf	trisa		
	movlw	B'11001000'
	movwf	trisb		;also port B bits
	movlw	B'10000001' ;
	movwf	trisc		;and port C bits, bit 0 ip for opto
	movlw	B'01000100' 
	movwf	adcon1		;select port A bits 0,1,3 for analog input, others digital
	movlw 	D'250'			;set PWM prd
	movwf	pr2
;set up SFRs in Bank 0	
	bcf		status,rp0 		;select bank 0
	movlw	B'01111100' ;switch on Timer2, no prescale, /16 postscale
	movwf	t2con
	movlw	B'00001100' ;enable PWM
	movwf	ccp1con
;
;Switch all outputs off
	clrf 	porta
	clrf 	portb
	clrf 	portc

;diagnostic, flash leds
	bsf 	portc,6
	bsf 	portc,5
	call 	delay500
	bcf 	portc,6
	bcf 	portc,5
;
	clrf	pointer
sin_loop	movf pointer,0
	call	sin_table	;get more significant byte of sample
	movwf	ccpr1l		;move it to the PWM output
	incf 	pointer,1	;increment the pointer
	movf 	pointer,0
	call 	sin_table	;get the less significant byte
	andlw	B'11000000'	;we only use ms 2 bits of this, adjust for CCP1CON
	movwf	temp
	bcf		status,c
	rrf		temp,1
	rrf		temp,0
	iorlw	B'00001100'	;ensure other bits of CCP1COn are set correctly
	movwf	ccp1con		;and output
	incf 	pointer,1
	movf	pointer,0
	sublw	D'92'		;test for end of table
	btfsc	status,z
	clrf	pointer		;reset pointer
	call 	delay1
	goto	sin_loop
;
Sin_Table
	addwf pcl,1
	retlw 00	;0 degrees, higher byte
	retlw 00	;0 degrees, lower byte
	retlw 03	;2 degrees, higher byte
	retlw 5A	;2 degrees, lower byte
	retlw 06	;4 degrees, higher byte
	retlw 0B2	;4 degrees, lower byte
	retlw 0A
	retlw 09
	retlw 0D
	retlw 5C
	retlw 10 	;10degs
	retlw 0AC	
	retlw 13
 	retlw 0F6
 	retlw 17
 	retlw 39
 	retlw 1A
 	retlw 76
 	retlw 1D
 	retlw 0AA
	retlw 20  ;20 degs
	retlw 0D5
	retlw 23
	retlw 0F6
	retlw 27
	retlw 0C
	retlw 2A
	retlw 15
	retlw 2D
	retlw 12 
	retlw 30  ;30 degs	
	retlw 00
 	retlw 32
	retlw 0DF
	retlw 35
	retlw 0AF
	retlw 38
	retlw 6D
	retlw 3B
	retlw 1A
    retlw 3D  ;40 degs 	
	retlw 0B5
	retlw 40
	retlw 36
	retlw 42
	retlw 0B0
	retlw 45
	retlw 0E
	retlw 47
	retlw 58 
    retlw 49 ;50 degs 	
	retlw 8A
 	retlw 4B
 	retlw 0A6
 	retlw 4D
 	retlw 0AA
 	retlw 4F
 	retlw 96
 	retlw 51
 	retlw 6A 
    retlw 53 ;60 degs
 	retlw 23
 	retlw 54
 	retlw 0C3
 	retlw 56
 	retlw 49
 	retlw 57
 	retlw 0B3
 	retlw 59
 	retlw 02
	retlw 5A ;70 degs 
	retlw 36
	retlw 5B
 	retlw 4D
 	retlw 5C 
	retlw 48 	
	retlw 5D
 	retlw 26
 	retlw 5D
 	retlw 0E7 
 	retlw 5E ;80 degs
 	retlw 86
 	retlw 5F
 	retlw 11
 	retlw 5F
 	retlw 79
 	retlw 5F
 	retlw 0C4
 	retlw 5F 
	retlw 0F1
 	retlw 60
 	retlw 00											

;*********************************************************
;SUBROUTINES
;*********************************************************
;introduces delay of 1ms approx
delay1  movlw 	D'250'	;250 cycles called, 
;			each taking 4us
        movwf  	delcntr1
del1    nop	;4 inst cycles in this loop, ie 4us
        decfsz 	delcntr1,1
        goto 	del1
        return
;500ms delay (approx)	;500 calls to delay1
delay500  movlw D'250'
        movwf  	delcntr2
del5    call 	delay1
		call 	delay1
        decfsz  delcntr2,1
        goto 	del5
        return  
;
	end
