list p=16F628
include "p16F628.inc"
errorlevel -302
; fuses cnfiguration
; BrownOut OFF, Code Protection OFF, Data Protection (EEPROM) OFF
; PowerOn Timer ON, Watchdog OFF, Low Voltage Programming OFF, MCLRE OFF (MCLRE tied inernally to VDD)
; Internal 4MHz oscillator ON (no output)
__config _BODEN_OFF & _CP_OFF & _DATA_CP_OFF & _PWRTE_ON & _WDT_OFF & _LVP_OFF & _MCLRE_OFF & _INTRC_OSC_NOCLKOUT
;-------------------------
; variable declarations
cblock 0x20 ; start of general purpose registers
endc
cblock 0x70 ; at Bank0 and is accessible from 0xF0, 0x170 and 0x1F0
w_temp
status_temp
endc
;--------------------------
org 0x0000
goto Main
org 0x0004
goto ISR
Main
call INIT
loop
;btfss PIR1,TMR2IF ; poll TMR2IF
;goto loop
;bcf PIR1,TMR2IF ; clear the flag - lather,rinse,repeat
;comf PORTA
goto loop
;------------ interrupt routine
ISR
; save STATUS and W register before processing interrupt
movwf w_temp
swapf STATUS,w
movwf status_temp
btfsc PIR1,TMR2IF
goto PWM_INT
goto reset_after_isr
PWM_INT
comf PORTA
bcf PIR1,TMR2IF
goto reset_after_isr
reset_after_isr
; restore the working and status register
movf status_temp,w
movwf STATUS
swapf w_temp,f
swapf w_temp,w
retfie
;------------ initialisation
INIT
; TMR2 set up for pwm, using post and pre scalars of 1:1
; (thus must enable peripheral interrupts and specifically TMR2IE)
; using the calculation defined in the datasheet
; PWM_Period -> 1/req_Freq = (PR2+1) * 4 * (1/TOSC)*1
; aiming for a 20KHz signal @ 4MHz (internal clock) with a tmr2 prescalar of 1 thus:
; 1/20 = (PR2+1) * 4 * (1/4) * 1
; 50ms = (PR2+1) * 4 * 0.25ms * 1
; 50ms = (PR2+1) -> PR2 = 49
; 8-bit resolution ok
; 25% duty cycle CCPR1L = 12
; 50% duty cycle CCPR1L = 24
; 75% duty cycle CCPR1L = 36
; bank 1 stuff
bsf STATUS,RP0
; setting trisb (bit3 must be output as it is multiplexed for use by ccp/pwm module)
clrf TRISB
clrf TRISA
clrf OPTION_REG
; pwm period
movlw .49
movwf PR2
;back to bank0
bcf STATUS,RP0
; disable comparators
movlw 0x07
movwf CMCON
clrf TMR2
clrf T2CON ; pre and postscalar 1:1 TM2ON = 0 (OFF)
clrf PIR1 ; all peripheral interrupts cleared
clrf PORTB
;pwm duty cycle is 25%
movlw .12
movwf CCPR1L
; enable pwm on ccp module
movlw b'00001100'
movwf CCP1CON
; enable tmr2 interrupt and disable other peripheral interrupts
movlw b'00000110'
movwf PIE1
; enable global and peripheral interrupts
movlw b'11000000'
movwf INTCON
; enable tmr2
bsf T2CON,TMR2ON
return
end