Hi all,
Thanks for the helping hand and code. I used your code samples but it just didn't do the trick. My goal was to be able to have 2 low freqency PWM signals with a 90 degree phase shift.
I finally accomplished this by using a 18F1230 @ 8Mhz , DT-INTS and a few lines of code.
The code below produces a 30Hz PWM that increments it's dutycycle every interrupt until it reaches 100%, it will then decrement to 1% and start over. It uses a 'base' frequency of 60Hz (PTPER 519), and distributes the dutycycle over the 30Hz periods.
Code:
'==== Set fuses
@ __CONFIG _CONFIG1H, _OSC_INTIO2_1H & _FCMEN_OFF_1H & _IESO_OFF_1H
@ __CONFIG _CONFIG2L, _PWRT_OFF_2L & _BOR_OFF_2L & _BORV_3_2L
@ __CONFIG _CONFIG2H, _WDT_OFF_2H & _WDTPS_1_2H
@ __CONFIG _CONFIG3L, _HPOL_HIGH_3L & _LPOL_HIGH_3L & _PWMPIN_ON_3L
@ __CONFIG _CONFIG3H, _FLTAMX_RA5_3H & _T1OSCMX_HIGH_3H & _MCLRE_OFF_3H
@ __CONFIG _CONFIG4L, _STVREN_OFF_4L & _BBSIZ_BB256_4L & _XINST_OFF_4L & _DEBUG_OFF_4L
@ __CONFIG _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L
@ __CONFIG _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H
@ __CONFIG _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L
@ __CONFIG _CONFIG6H, _WRTB_OFF_6H & _WRTC_OFF_6H & _WRTD_OFF_6H
@ __CONFIG _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L
'==== Include DT interrupts
INCLUDE "DT_INTS-18.bas" ;Base Interrupt System
INCLUDE "ReEnterPBP-18.bas" ;Include if using PBP interrupts
'==== Dec's for OSC
OSCCON = %01110000 'Int OSC @ 8 MHz
'OSCTUNE = %00000000 'PLL disabled, center freqency
DEFINE OSC 8 'Int OSC @ 8 MHz, for PBP
'==== Initialize DT_INTS
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler PT_INT, _pwmINT, PBP, YES
endm
INT_CREATE ;Creates the interrupt processor
ENDASM
'==== Set port associated registers
ADCON0 = %00000000 'A/D convertor disabled
ADCON1 = %00001111 'All ports configured digital
ADCON2 = %10000000 'Right justify results
CMCON = %00000000 'Comparator modules disabled
CVRCON = %00000000
PTCON0 = %00001100 'Fosc/4 Prescale 1:64, Free running mode
PWMCON0 = %00110111 'PWM0,1,2,3 enabled, independent mode
PWMCON1 = %00000001 'Special event on count upwards, Sync PWM timebase
PORTA = %00000000
PORTB = %00000000
TRISA = %01100000
TRISB = %00000100
'==== Dec's for pin aliasing INPUT'S
'none
'==== Dec's for pin aliasing OUTPUT'S
'none
'==== Reset PWM duty registers
PDC0L = 0: PDC0H = 0 'Reset duty register 0
PDC1L = 0: PDC1H = 0 'Reset duty register 1
PDC2L = 0: PDC2H = 0 'Reset duty register 2
'==== Dec's for variables
pwmFREQ var word
pwmDUTY_TGT var word
pwmDUTY var word
pwmDIR var bit
pwmTOG var bit
pwmFL var bit
'==== Initialise variables
pwmFREQ = 0
pwmDUTY_TGT = 0
pwmDUTY = 0
pwmDIR = 0
pwmTOG = 0
pwmFL = 0
'==== Wait for hardware settle
Pause 500 'Settle for 0,5 seconds
'==== Enable PWM interrupts
@ INT_ENABLE PT_INT ;Enable PWM to PTPER match interrupts
'==== SET PWM frequency and dutycycle
pwmFREQ = 519 'Makes 60,010 Hz, 100% dutycycle = 2076
pwmDUTY = 1 'Initial dutycycle
PTPERL = pwmFREQ.lowbyte 'Set PWM frequency lowbyte
PTPERH = pwmFREQ.highbyte 'Set PWM frequency lowbyte
'pwmFREQ_CO = 2076 '100% dutycycle
'Find out if desired PWM is below 50% or over.
'Double the ammount of dutycycle because
'the frequency will be half the base frequency ..
if pwmDUTY <= 1038 then
pwmDUTY_TGT = pwmDUTY * 2
pwmDIR = 0
else
pwmDUTY_TGT = (pwmDUTY - 1038) * 2
pwmDIR = 1
endif
PTCON1 = %10000000 'Start PWM output
'==== Main program loop
main_loop:
@ nop 'Do nothing
goto main_loop
'==== The End
theend: 'Endless loop
goto theend 'Endless loop
'==== Routines
pwmINT:
PWMCON1.1 = 1
if pwmDIR = 0 then
if pwmTOG = 0 then
PDC0L = 0
PDC0H = 0
PDC1L = pwmDUTY_TGT.lowbyte
PDC1H = pwmDUTY_TGT.highbyte
pwmTOG = 1
else
PDC0L = pwmDUTY_TGT.lowbyte
PDC0H = pwmDUTY_TGT.highbyte
PDC1L = 0
PDC1H = 0
pwmTOG = 0
endif
else
if pwmTOG = 0 then
PDC0L = 2076
PDC0H = 2076
PDC1L = pwmDUTY_TGT.lowbyte
PDC1H = pwmDUTY_TGT.highbyte
pwmTOG = 1
else
PDC0L = pwmDUTY_TGT.lowbyte
PDC0H = pwmDUTY_TGT.highbyte
PDC1L = 2076
PDC1H = 2076
pwmTOG = 0
endif
endif
if pwmfl = 0 then
pwmduty = pwmduty + 1
else
pwmduty = pwmduty - 1
endif
if pwmduty >= 2076 then pwmfl = 1
if pwmduty <= 0 then pwmfl = 0
if pwmDUTY < 1038 then
pwmDUTY_TGT = pwmDUTY * 2
pwmDIR = 0
else
pwmDUTY_TGT = (pwmDUTY - 1038) * 2
pwmDIR = 1
endif
PWMCON1.1 = 0
@ INT_RETURN
Problem solved, Thanks guys !
Best regards, UltiBlade
Bookmarks