

**********************************************************************   
; Filename: 16F628A_PWM.asm 
; Uses PIC16F628A
; Date: 13 Nov. 2013      
; Author:  Lewis Loflin
; http://www.bristolwatch.com
; http://www.bristolwatch.com/PIC16F628A/a7.htm
; This demo blinks RA0 on/off and outputs 
; on RB3 a 5 kHz 50% duty cycle square wave. 
; Shows how to turn on-off by altering TRISB bit 3
; Delay routines and PWM based on 16 mHz external crystal 
;
; PWM Period = [(PR2) + 1] * 4 ? TOSC * (TMR2 Prescale Value)
; PWM duty cycle = (DCxB9:DCxB0 bits value) 
; * Tosc * (TMR2 prescale value)
; Tosc = 16 mHz / 4
; PWM output PORTB, 3 
;**********************************************************************

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
	count4
	endc

	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    TRISA
	clrf    TRISB
	clrf	PIE1
	movlw	d'49' ; frequency = 5 kHz
	movwf	PR2
	banksel INTCON ; back to bank 0
	clrf	PORTA
	clrf	PORTB
	clrf	PIR1
	movlw	b'00000111'
	movwf	T2CON ; turn on TMR2 prescale 16
	movlw	d'24' ; duty cycle = 50%
	movwf	CCPR1L
	movlw	b'0001100'
	movwf	CCP1CON 	; turn on PWM 
	goto main

main
; remaining code goes here
	banksel TRISB
	bsf TRISB, 3
	call delay_100ms
	call delay_100ms
	call delay_100ms
	bcf TRISB, 3
	call delay_100ms
	call delay_100ms
	call delay_100ms

	goto	main 

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'
