Servo Jumpy with DT Interrupt


Results 1 to 10 of 10

Threaded View

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


    Did you find this post helpful? Yes | No

    Default

    Have you considered using the PWM module? Many people don't realize you can run the PWM module at very low frequencies by using a software "helper" ISR (interrupt service routine) to link together several much smaller/faster PWM period "frames" to form a much longer/slower overall period.

    This method provides many of the advantages of the PWM module (zero jitter, interrupt tolerant, very high resolution pulse width, etc.) at the cost of using a small low overhead ISR software "helper". You can also use the 1-msec interrupt interval as a basis for timer operations.

    Perhaps one of the PBP gurus can convert, test, and qualify this code for you?

    Happy Holidays!

    Mike, K8LH

    Code:
      //  setup a 1000 usec PWM period with PR2 = 249 and prescaler
      //  16:1 (16 MHz clock) or 4:1 (4 MHz clock) and then link 20
      //  of these 1000 usec PWM "frames" together to form the much
      //  longer 20-ms servo period (1-usec pulse width resolution)
    
      int servo = 1500;            // 0..20000 in 1 usec steps
      int frame = 1;               // frame number 1..20
    
      void interrupt()             //
      { int width;                 // work variable
        pir1.TMR2IF = 0;           // clear Timer 2 interrupt flag
        frame--;                   //
        if (frame == 0)            // if end of the 20 msec period
        { frame = 20;              // reset for new 20 msec period
          width = servo;           // reset 'width' work variable
        }
        if ((width > 1000)         // if width > 1000 usecs
        { ccpr1l = 250;            // do a 100% duty cycle frame
          ccp1con.CCP1Y = 0;       //
          ccp1con.CCP1X = 0;       //
          width -= 1000;           // subtract 1000 usecs
        }
        else                       // else do a 0..1000 usec frame
        { ccpr1l = (width >> 2);   // 0..250 (0..1000 usecs)
          ccp1con.CCP1Y = (width & 1);
          ccp1con.CCP1X = (width & 2);
          width = 0;               // force remaining frames to 0%
        }
      }
    Last edited by Mike, K8LH; - 1st December 2010 at 02:15.

Members who have read this thread : 0

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