Hi All,
I'm kind of stuck at the moment.
I need a pwm signal with a low frequency. Darrel has made the awesome slow pwm module but i can't use because i need timer1 to do a continues pulse count. So i'm trying to code my own, but i can't seem to figure it out.
I'm using timer0 to to make the frequency, with Darrels DT_INTS-14. This works perfect. Preloading timer0 with 190 give about 118Hz where i need 120Hz so thats ok. On every interrupt the PORTC.0 pin is made high.
I'm using timer2 to make the dutycycle. I thought if i have a frequency of 120Hz the period is about 8333uS. If i need 256 dutycycle steps i need a interrupt at 8333uS/256 steps = 32,6uS. Timer2 is setup (presc. 1:1, postsc. 1:1, pr2=64) to generate an interrupt every 32,5uS.
If i need a 50% dutycycle, simply count 128x timer2 interrupts and that make the output low. Could be quite simple I thought, but i was wrong. On my scope i see a nice 117Hz stable signal with a dutycycle of 1 or so. If i alter the dutycycle var i sometimes see a dutycycle that ramps down at every cycle ?
Here's my code :
Code:
'==== Set fuses =========================================
'Fuse are set in .inc file
'==== Set includes ======================================
INCLUDE "DT_INTS-14.bas" 'DTints Interrupt System
include "ReEnterPBP.bas" 'Enable PBP int reenter
'==== Dec's for OSC =====================================
DEFINE OSC 8 'Int OSC @ 8 MHz, for PBP
OSCCON = %01110001 'Int OSC @ 8 MHz
'==== Set defines =======================================
OPTION_REG = %00000111 'Set TMR0 precsaler to 1:256, source Fosc/4
WPU = %00000000 'Weak pull-ups disabled
INTCON = %11100000 'Global + Perhip. INT enabled, TMR0 int enabled
PIE1 = %00000010 'TMR2 to PR2 match INT enabled
PIE2 = %00000000 'Set TMR1 overflow interrupt
PIR1 = %00000000
PIR2 = %00000000
PCON = %00000000
IOC = %00000000 'Interrupt On Change disabled
PCON = %00000000 'Ultra lowpower + BOR disabled
ANSEL = %00000000 'Select analog inputs: none
ANSELH = %00000000 'Select analog inputs: none
ADCON0 = %00000000 'A/D Module is OFF
ADCON1 = %00000000 'A/D control register
CM1CON0 = %00000000 'Comparator1 Module is OFF
CM2CON0 = %00000000 'Comparator2 Module is OFF
VRCON = %00000000 'Voltage ref. disabled
TRISA = %00000000 'Set Input/Output (0 to 5)
PORTA = %00000000 'Ports High/Low (0 to 5)
TRISB = %00000000 'Set Input/Output (4 to 7)
PORTB = %00000000 'Ports High/Low (4 to 7)
TRISC = %00000000 'Set Input/Output (0 to 7)
PORTC = %00000000 'Ports High/Low (0 to 7)
T2CON = %00000100 'Timer2 is On,
T1CON = %00000000 'Timer1 is off
CCP1CON = %00000000 'CCP engine is off
'==== Set Constants =====================================
'none
'==== Setup DTints interrupt handler ====================
ASM
INT_LIST macro ;Setup IntSource
INT_Handler TMR0_INT, _intTMR0, PBP, yes ;Enable TMR0 interrupts
INT_Handler TMR2_INT, _intTMR2, PBP, yes ;Enable TMR0 interrupts
endm
INT_CREATE ;Create interrupt processor
ENDASM
'==== Dec's for pin aliasing INPUT'S ====================
'none
'==== Dec's for pin aliasing OUTPUT'S ===================
gi1 var PORTC.0 'Injector 1 output pin
'==== Dec's for variables ===============================
dutycycle var byte 'Holds the needed dutycycle
dutycount var byte 'Counter for dutycycle
'==== Initialise variables ==============================
gistate = 0
dutycycle = 0
dutycount = 0
'==== Wait for hardware settle ==========================
pause 500
'==== Enable interrupt processing =======================
TMR0 = 190 'Preload Timer0 for interrupt @ 120Hz
PR2 = 64 'Preload PR2 for dutycycle interrupt
dutycycle = 128 'Set duty cycle to 50%
@ INT_ENABLE TMR0_INT ;Activate TMR0 INT
@ INT_ENABLE TMR2_INT ;Activate TMR2 INT
'==== Main program loop =================================
main:
@ nop ;Do nothing
goto main
'==== The End ===========================================
theend: ' Endless loop
goto theend ' Endless loop
'Routines and Handlers
'==== TMR0 Interrupt handler ============================
intTMR0: 'TMR0 INTERRUPT HANDLER
TMR0 = 190 'Reload TMR0
gi1 = 1 'Activate injector 2
@ INT_RETURN ;Jump back to previous process
'==== TMR2 Interrupt handler ============================
intTMR2: 'TMR0 INTERRUPT HANDLER
PR2 = 64 'Reload PR2
if dutycount = dutycycle then 'If dutycycle is met,
gi1 = 0 'Deactivate injector 1
dutycount = 0 'Reset the dutycounter
else
dutycount = dutycount + 1 'Add 1 to dutycounter
endif
@ INT_RETURN ;Jump back to previous process
Anyone have an idea ?
Best regards, UB
Bookmarks