; Program PWM.ASM
;
; Illustrates use of the PWM command. Average voltage at PORTB.0 is
; ramped up from zero and then down from near +5.0. Process repeats.
;
; Peter H. Anderson, MSU, August 7, '97
;

     processor  16F84A
     include    <p16F84A.inc>
     __config   _CP_OFF & _PWRTE_OFF & _WDT_OFF & _XT_OSC

     ERRORLEVEL -302          ; suppress bank selection messages


CONSTANT        BASE_VAR=0CH
PWM_DUTY EQU    BASE_VAR+0
PWM_LOOP EQU    BASE_VAR+1


MAIN:
     BSF     STATUS,RP0
     BSF     TRISB,0          ; make pin RB.0 an input, high impedance
     BCF     STATUS,RP0
     CLRF    PWM_DUTY         ; start duty cycle at minimum

MAIN_1:
     CALL    PWM
     INCFSZ  PWM_DUTY,F       ; and ramp up
     GOTO    MAIN_1

MAIN_2:
     CALL    PWM              ; now, ramp down
     DECFSZ  PWM_DUTY,F
     GOTO    MAIN_2
     GOTO    MAIN

PWM:
     CLRF    PWM_LOOP         ; 256 counter
     BSF     STATUS,RP0       ; bank 1
     BCF     TRISB,0          ; make PORTB.0 an output
     BCF     STATUS,RP0       ; back to bank 0

PWM_1: 
     ADDWF   PWM_DUTY,W       ; accum = accum + duty
     BTFSS   STATUS,C 
     BCF     PORTB,0 
     BTFSC   STATUS,C 
     BSF     PORTB,0 
                              ; a delay may be inserted here
     DECFSZ  PWM_LOOP,F       ; do this 256 times

     GOTO    PWM_1 
     BSF     STATUS,RP0 
     BSF     TRISB,0          ; make PORTB.0 an input
     BCF     STATUS,RP0 
     RETURN 

  END 
