

;**********************************************************************   
; Filename: TLC548_PWM.asm 
; Date: 13 Nov. 2013      
; Author:  Lewis Loflin
; http://www.bristolwatch.com 
; Reads 8-bit ADC then controls duty cycle of pwm PB3.   
;
; PWM Period = [(PR2) + 1] * 4 * TOSC * (TMR2 Prescale Value)
; PWM duty cycle = (DCxB9:DCxB0 bits value) * Tosc * (TMR2 prescale value)
; Tosc = 16 mHz
; PWM output PORTB, 3 
;
; Pins on the TLC548 8-bit ADC:
; 1 - Ref + connect to Vcc
; 2 - analog in
; 3 - Ref - connect to GND
; 4 - GND
; 5 - CS-NOT  chip select active LOW
; 6 - DATA OUT
; 7 - CLK
; 8 - Vcc
;************************************************************************



	list      p=16f628A           ; list directive to define processor
	#include <p16F628A.inc>       ; processor specific variable definitions
	errorlevel  -302              ; suppress message 302 from list file

__CONFIG   _CP_OFF & _LVP_OFF & _BOREN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC 
	
; Use  _INTOSC_OSC_NOCLKOUT  for 
; internal 4 mHz osc and no ext reset, use pin RA5 as an input
; Use _HS_OSC for a 16 mHz ext crystal. 
; Use _XT_OSC for 4 mHz ext crystal. Page 95 in spec sheet. 

;------------------------------------------------------------
	cblock 0x20	; Begin General Purpose-Register
;-------------------------- counters ------------------------	
	count1
	count2
	count3
	val
	i
	endc
;-----------------------------------------------
	CS        equ 2  ; select TLC548 pin 5
	DATABIT   equ 0  ; DATA bir TLC548 pin 6
    CLK       equ 1  ; CLK TLC548 pin 7
;------------------------------------------------

	ORG     0x000             ; processor reset vector
	goto    setup              ; go to beginning of program


setup ; init PIC16F628A

	movlw	0x07		; Turn comparators off and enable pins for I/O 
	movwf	CMCON
	clrf	INTCON
	clrf	T2CON
	clrf	TMR2
	banksel TRISA    ; BSF	STATUS,RP0 Jump to bank 1 use BANKSEL instead
	clrf	PIE1
	movlw	d'255' ; frequency = 1000 Hz
	movwf	PR2
	movlw b'00000001' ; RA0 is input
	movwf	TRISA
	clrf    TRISB
	banksel INTCON ; back to bank 0
	clrf	PORTB
	movlw b'00000100'
	movwf	PORTA
	movlw	b'00000111'
	movwf	T2CON ; turn on TMR2 prescale 16
	movlw	d'0' ; duty cycle = 0%
	movwf	CCPR1L
	movlw	b'00001100'
	movwf	CCP1CON 	; turn on PWM 
	goto main


main
	call delay_100ms
	call get_adc ; value returned in val
	movfw val
	movwf CCPR1L ; output pwm duty cycle RB3
goto main


get_adc ; value returned in val

	clrf val
	bcf PORTA, CS ; LOW CS
	movlw 0x08
	movwf i
zz	bsf PORTA, CLK  ; HIGH CLK
	call delay_1ms
	btfss PORTA, DATABIT
	goto $+3  
   	movlw 0x01
	addwf val, F 
	bcf PORTA, CLK  ; LOW CLK
	decfsz i, F
	goto $+3
	goto $+4
	nop
	rlf val
	goto zz
 	bsf PORTA, CS  ; HIGH CS
	return

delay_1ms
	; 16 mHz crystal
	movlw 0x07
	movwf count1
aa	movlw 0xBC
	movwf count2
	decfsz count2, F
	goto $-1
	decfsz count1, F
	goto aa 
	return
delay_100ms
	; 16  mHz crystal
	movlw d'99'
	movwf count3
bb	call delay_1ms
	decfsz count3, F
	goto bb
	return

	END  ; directive 'end of program'

