Low freq PWM problem


Closed Thread
Results 1 to 6 of 6

Hybrid View

  1. #1
    Join Date
    Apr 2006
    Location
    GearSweaterMountain, The Netherlands
    Posts
    52


    Did you find this post helpful? Yes | No

    Default

    You're so right ! I don't know how i missed this. Thanks !

    A couple of day's ago i found a timer calculator, i just entered the frequency and the calculations were made. However, it seems that the scrollbars that are used to set the prescalers and preload values in this calculator are refreshed after clicking calculate. I was using bad combinations every calculation.

    I tried your values, and it worked like a charm, thanks for replying !

    Thanks !

  2. #2
    Join Date
    Aug 2005
    Location
    Michigan, USA
    Posts
    224


    Did you find this post helpful? Yes | No

    Default

    You might also consider using the PWM module along with a small interrupt driven "helper" to link together several smaller PWM period "frames" into the much longer 120-Hz PWM period. This method produces a relatively low overhead high resolution jitter free PWM output.

    I don't have PBP but perhaps you and other Forum members can muddle through this pseudo C code example.

    This example uses a 12-MHz clock (Tcy = 0.3334-usecs) with PWM module settings that produce a PWM period of 333.3334-usecs (250 x 1.3334-usec 'steps'). The interrupt "helper" links together 25 of these short 333.3334-usec PWM period "frames" to produce a precise 120-Hz (8333.3334-usec) period with an output pulse width of 0 to 6250 x 1.3334-usec "steps".

    Regards, Mike

    Code:
    ;******************************************************************
    ;
    ;  // setup PWM for a 333.3 usec period (12-MHz xtal, Timer 2
    ;  // prescale 4:1, PR2 = 249) and use 25 of these 333.3 usec
    ;  // PWM "frames" for a precise 120-Hz (8.3334 msec) period.
    ;
    ;  char frame = 1;              // initialize "frame" var'
    ;  int width = 100;             // 0..6250 (1.333 usec steps)
    ;  int pulse;                   // isr work variable, 0..6250
    ;
    ;  void interrupt()             // 120-Hz example
    ;  { pir1.TMR2IF = 0;           // clear timer 2 interrupt flag
    ;    frame--;                   // decrement 'frame' number
    ;    if(frame == 0)             // if end-of-period
    ;    { frame = 25;              // reset for new period
    ;      pulse = width;           // refresh work variable
    ;    }
    ;    if(pulse > 250)            //
    ;    { ccpr1l = 250;            // do a 100% duty cycle frame
    ;      pulse -= 250;            // update 'pulse'
    ;    }
    ;    else                       //
    ;    { ccpr1l = pulse;          // do variable duty cycle
    ;      pulse = 0;               // force remaining frames to 0%
    ;    }
    ;
    ;
    ;
    ;  void Main()                  //
    ;  { cmcon0 = 7;                // comparators off
    ;    ansel = 0;                 // a2d convertor off
    ;    pir1 = 0;                  // clear all interrupt flags
    ;    pie1.TMR2IE = 1;           // enable TMR2 interrupts
    ;    ccpr1l = 0;                // set 0% duty cycle (output off)
    ;    t2con = 0b00000101;        // '0-------' unimplemented bit
    ;                               // '-0000---' TOUTPS<3:0>, postscale 1
    ;                               // '-----1--' TMR2ON, turn Timer 2 on
    ;                               // '------01' T2CKPS<1:0>, prescale 4
    ;    pr2 = 250-1;               // 250 x 1333-nsec 'ticks' = 333 usecs
    ;    intcon = 0b11000000;       // '1-------' GIE, enable global ints
    ;                               // '-1------' PEIE, enable peripheral ints
    ;                               // '--0-----' T0IE, TMR0 ints disabled
    ;                               // '----0---' GPIE, IOC disabled
    ;                               // '-----000' T0IF/INTF/GPIF flags
    ;    while(1)                   //
    ;    {                          //
    ;    }                          //
    ;  }
    ;
    Last edited by Mike, K8LH; - 7th February 2010 at 13:53.

  3. #3
    Join Date
    Apr 2006
    Location
    GearSweaterMountain, The Netherlands
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Low frequency PWM

    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
    Last edited by ultiblade; - 17th February 2010 at 07:14. Reason: Code formatting was off

Similar Threads

  1. Old and beyond help ?
    By DavidFMarks in forum mel PIC BASIC Pro
    Replies: 46
    Last Post: - 11th December 2008, 15:23
  2. confused problem with interrupt in a working program
    By illuminator4 in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 14th November 2008, 17:01
  3. problem with PWM
    By mimmmis in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 12th September 2008, 13:36
  4. Microcontroller with 2 way paging application problem
    By oneohthree in forum mel PIC BASIC Pro
    Replies: 30
    Last Post: - 20th April 2007, 17:27
  5. 4-line LCD Help - using PortA instead of B
    By Tom Gonser in forum mel PIC BASIC Pro
    Replies: 28
    Last Post: - 31st March 2005, 03:14

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts