PWM MPASM code


;Created on January 16, 2024, 2:05 PM

    processor 12F629

    #include 
    __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF
    errorlevel -302

; This shorthand assigns i=0x20, cycles=0x21, etc.
    cblock 0x20
        i               ;define 0x20 register as the PWM loop variable
        cycles          ;define 0x21 register as the number of delays
        j               ;define 0x22 register in delay routine
        dir             ; define 0x23 register as 1 bit incr/decr indicator
    endc
    ORG 0x0000

INIT
    movlw b'111'    ; 0x03
    movwf CMCON     ; turn off comparator        
    MOVLW 0xF8      ; w=1111 1000
    ; TRIS GPIO   	; deprecated	 
    BSF STATUS,RP0  ; select bank 1
    MOVWF TRISIO    ; set GP0,1,2 as an outputs  w= 11111000                     
    BCF STATUS,RP0  ; select bank 0
    CLRF dir        ;  0=decr, 1=incr
    MOVLW 0xFE      ; w=254
    MOVWF i         ; i=254

pwm_loop:
   MOVF  i,w            ; copy i to W     
   MOVWF cycles         ; copy w to cycles, cycles = i
   BSF GPIO, GP1        ; turn on GP1
   CALL DELAY           ; times cycles
   COMF i,w             ; inverse of i stored in w
   MOVWF cycles         ; cycles = ~i
   BCF GPIO, GP1        ; turn off GP1
   CALL DELAY           ; times cycles
   ;-------------end pwm-------------
   BTFSS dir,0          ; if dir==1 skip next line
   GOTO decr            
   GOTO incr
   

decr:
   DECFSZ i,f           ; i--, skip next line if i=0  
   GOTO pwm_loop        ; back to PWM
   BSF dir,0            ; dir = 1 (incr)
   MOVLW 0x02           ; 
   MOVWF i              ; start i=2, because i=1 already run
   GOTO pwm_loop        ; back to PWM 

incr:
   INCF i,f             ; i++
   MOVLW 0xFF           ; w=255
   XORWF i,w           ;  if i==w, result=0 
   BTFSS STATUS,Z      ; if zero bit is set, skip next line                      
   GOTO pwm_loop 
   BCF dir,0            ; dir = 0 (decr)
   DECF i               ; i=254       
   GOTO pwm_loop
               
DELAY   ;Start DELAY subroutine here
		;31 cycles
	MOVLW	0x10  
	MOVWF	j
Delay_0
	DECFSZ	j, f
	GOTO	Delay_0
			;1 cycle
	NOP   
    DECFSZ	cycles, f
    GOTO DELAY
    RETLW 0   			 ;Return from subroutine, placing value into W
                
    END