DEFINE INTHAND INT_CODE                 ' Tell PBP Where the code starts on an interrupt
wsave       VAR BYTE    $20     SYSTEM          '$20 Save location for the W register if in bank0
wsave1      VAR BYTE    $A0     SYSTEM          ' Save location for the W register if in bank1
wsave2      VAR BYTE    $120    SYSTEM          ' Save location for the W register if in bank2
wsave3      VAR BYTE    $1A0    SYSTEM          ' Save location for the W register if in bank3
ssave       VAR BYTE    Bank0   SYSTEM          ' Save location for the STATUS register
psave       VAR BYTE    Bank0   SYSTEM          ' Save location for the PCLATH register
TMR1_ON_TICKS       var word Bank0    ' # of Tmr ticks for On Time
TMR1_OFF_TICKS      var word Bank0    ' # of Tmr ticks for Off Time
TMR1_ON_VAL         var word Bank0    ' # to load TMR1 for On Time
TMR1_OFF_VAL        var word Bank0    ' # to load TMR1 for Off Time
DataFlags           var byte Bank0
SPWMstate           var DataFlags.2   ' Current state of SPWM output high or low
GIE                 var INTCON.7
PEIE                var INTCON.6
TMR1IE              var PIE1.0
TMR1ON              var T1CON.0
clear                               'Clear All Variables
goto Start
' ------------------------------------------------------------------------
asm
INT_CODE
      if (CODE_SIZE <= 2)
        movwf   wsave              ; copy W to wsave register
        swapf   STATUS,W           ; swap status reg to be saved into W
        clrf    STATUS             ; change to bank 0 regardless of current bank
        movwf   ssave              ; save status reg to a bank 0 register
        movf    PCLATH,w           ; move PCLATH reg to be saved into W reg
        movwf   psave       ;6     ; save PCLATH reg to a bank 0 register
          endif
        
        btfss   PIR1, TMR1IF       ; is TMR1IF set?   Timer1 Interrupt Flag
        GOTO  NoTimerInt           ; No.  Bypass timer load
        btfss   _SPWMstate         ; Is Output High?
        GOTO  TurnON      ;9/15    ; No.
TurnOFF
        bcf     _CmdPwr             ; Set CmdPwr Low
        bcf     _SPWMstate          ;
        BCF     T1CON,TMR1ON        ; Turn off timer
        MOVF    _TMR1_OFF_VAL,W     ;  1
        ADDWF   TMR1L,F             ;  1    ; reload timer with correct value
        BTFSC   STATUS,C            ;  1/2
        INCF    TMR1H,F             ;  1
        MOVF    _TMR1_OFF_VAL+1,W   ;  1
        ADDWF   TMR1H,F             ;  1
        BSF     T1CON,TMR1ON        ;  1    ; Turn it back on
        GOTO  TimerDone   ;12/27
TurnON  
        bsf     _CmdPwr             ; Set CmdPwr High
        bsf     _SPWMstate          ;
        bcf     T1CON,TMR1ON        ; Turn off timer
        MOVF    _TMR1_ON_VAL,W      ;  1
        ADDWF   TMR1L,F             ;  1    ; reload timer with correct value
        BTFSC   STATUS,C            ;  1/2
        INCF    TMR1H,F             ;  1
        MOVF    _TMR1_ON_VAL+1,W    ;  1
        ADDWF   TMR1H,F             ;  1
        bsf     T1CON,TMR1ON        ;  1    ; Turn it back on
       
TimerDone        
        bcf     PIR1, TMR1IF ; 1/28 ; Clear Timer1 Interrupt Flag
NoTimerInt    
        Movf    psave,w             ; Restore the PCLATH reg
        Movwf   PCLATH
        swapf   ssave,w             ; Restore the STATUS reg            
        movwf   STATUS
        swapf   wsave,f
        swapf   wsave,w    ; 6/34   ; Restore W reg
       
    Retfie                          ; Exit the interrupt routine    
endasm
' ------------------------------------------------------------------------
StartSPWM:          'Set Freq and DutyCycle before calling
                    'For 2khz pwm and 8mhz clock Ticks = 1000 per cycle 
    GIE = 1
    PEIE = 1
    TMR1H = 255        'Load TMR1 with 65535, First tick will cause
    TMR1L = 255        'an interrupt that will load TMR1_???_VAL 
    TMR1_ON_TICKS = DutyCycle       '(Must be between 100 & 900 (10-90%)
    TMR1_OFF_TICKS = 1000 - TMR1_ON_TICKS
    TMR1_ON_VAL = 65535 - TMR1_ON_TICKS + 8
    TMR1_OFF_VAL = 65535 - TMR1_OFF_TICKS + 8
    TMR1IE = 1
    T1CON = 1        'Set Timer1 prescaler to 1 and turn Timer1 on
    return
'*************************************************  ************************************ 
'*********************************** Main Program ************************************
			
		
 
	
Bookmarks