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 :
Anyone have an idea ?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
Best regards, UB




Bookmarks