LIST P=PIC16F628, F=INHX8M __CONFIG _CP_OFF & _WDT_OFF & _HS_OSC & _LVP_OFF ;***************************************************************************** ; ; Timer2 Test program, ; Demo program for N channel software PWM generator using TMR2 ; The current application will output a 50% PWM signal on PortB pin 0 ; And will fade the outputs on PortB pin1 and pin2 from OFF->ON->OFF->ON ; ; Program TMR2.ASM ; Author Wim de Vree, pe1grl@amsat.org ; Revision history ; 20030712 Created from TIMER0 test program ; 20050206 Rewritten als small demo program, PWM's two outputs ; demo's phasing loops, now uses 256 steps ; include ;***************************************************************************** ; Equates, I/O, vars ;***************************************************************************** RESET_V EQU 0x0000 ; Address of RESET Vector ISR_V EQU 0x0004 ; Address of Interrupt Vector _w EQU 0x7C ; Save area for 'W' register _status EQU 0x7D ; Save area for 'STATUS' register CBLOCK 0x20 ; Declare variable addresses starting at 0x20 Phase ; Phase of PWM counter (0..255) DutyCycle0 ; "ON" period for channel 0 (0..255) DutyCycle1 ; "ON" period for channel 1 (0..255) DutyCycle2 ; "ON" period for channel 2 (0..255) tempB ; Temp holding for PORT B HiCount,LoCount,temp ; Main loop counters ENDC ;***************************************************************************** ; Program start ;***************************************************************************** ORG RESET_V ; RESET vector location RESET GOTO START ;***************************************************************************** ; This is the Periperal Interrupt routine. ;***************************************************************************** ORG ISR_V ; Interrupt vector location INTERRUPT GOTO INTHANDLER ;***************************************************************************** ; Initialize processor registers ;***************************************************************************** START ; POWER_ON Reset (Beginning of program) CLRF STATUS ; Do initialization, Select bank 0 CLRF INTCON ; Clear int-flags, Disable interrupts CLRF PCLATH ; Keep in lower 2KByte CLRF PORTA ; ALL PORT output should output Low. CLRF PORTB bsf STATUS,RP0 MOVLW 0xFF ; RA3-0 all inputs MOVWF TRISA MOVLW 0x000 ; RB7-0 outputs MOVWF TRISB clrf PIE1 ; Disable peripheral interrupts bcf STATUS,RP0 clrf Phase clrf DutyCycle1 ; Set Dutycycle at 0 clrf DutyCycle2 bcf PORTB,1 ; LEDs off bcf PORTB,2 clrf T2CON ; Stop Timer2, Prescaler = 1:1, Postscaler = 1:1 clrf TMR2 ; Clear Timer2 register clrf PIR1 ; Clear peripheral interrupts Flags bsf STATUS, RP0 ; Select bank 1 movlw .99 ; Period for TMR2 (100 usec for 4 MHz) movwf PR2 bsf PIE1,TMR2IE ; Timer 2 interrupt on bcf STATUS, RP0 bsf INTCON,PEIE ; Pheriperal interrupts enabled bsf INTCON,GIE ; Global interrupts enabled bsf T2CON, TMR2ON ; Timer2 starts to increment movlw .64 ; Set PWM0 at 25 % ( 64/256) movwf DutyCycle0 movlw .128 ; Set PWM1 at 50 % (128/256) movwf DutyCycle1 movlw .192 ; Set PWM2 at 75 % (192/256) movwf DutyCycle2 FadeON clrf temp ; Start with 0, end with 255 FadeONloop call BigDelay ; Delay fading to slow it down movf temp,W movwf DutyCycle1 sublw 0 ; Led 2 in tegenfase led 1 movwf DutyCycle2 incfsz temp,F goto FadeONloop FadeOFF movlw .255 ; Start with 255, end with 0 movwf temp FadeOFFloop call BigDelay ; Delay fading to slow it down movf temp,W movwf DutyCycle1 sublw 0 ; Led 2 in tegenfase led 1 movwf DutyCycle2 decfsz temp,F goto FadeOFFloop goto FadeON BigDelay movlw .14 ; Approx 10 milliseconds movwf HiCount movwf LoCount Dlay: decfsz LoCount,f goto Dlay decfsz HiCount,f goto Dlay return INTHANDLER movwf _w ; Save W and STATUS movf STATUS,W movwf _status bcf STATUS, RP0 ; Select bank 0 bcf PIR1, TMR2IF ; Clr Timer2 interrupt incf Phase,f ; Increment Phase clrf tempB ; All outputs OFF movf DutyCycle0,W subwf Phase,W ; Check if dutycycle reached skpc bsf tempB,0 ; Output on movf DutyCycle1,W subwf Phase,W ; Check if dutycycle reached skpc bsf tempB,1 ; Output on movf DutyCycle2,W subwf Phase,W ; Check if dutycycle reached skpc bsf tempB,2 ; LED ON movf tempB,W movwf PORTB int_done movf _status,w ; Restore W and STATUS movwf STATUS swapf _w,F swapf _w,W retfie END ; End of program