Menu

Programmable Period Timer / Servo Control Example

2016-01-21
2016-01-24
  • William Roth

    William Roth - 2016-01-21

    Sometimes we need to generate Pulse or execute code at regular and accurate intervals. For example, servo control where a servo pulse must be generated every 20 ms.

    A relatively easy and efficient way to do this is by using a Timer and a Capture/Compare (CCP) module.

    In this example a PIC 18F25K22 was used, but any PIC with Timer1 and A CCP module will work in a similar manner.

    When in Compare Mode, the 16 bit value of the CCPRx register is compared with the 16-bit value of the TMRX register. When the values match we can tell the PIC to do something. We can toggle the CCPx Pin, set or clear the pin, or trigger a "special event". What is done depends upon the settings of the CCPxCon register.

    To create a period timer set the CCP1 module to Compare Mode: Special Event Trigger by setting CCP1CON bits 3:0 to "1101" <CCP1CON =="" 0x0D="">. In this mode when the TMR1 Value matches the value programmed in the CCPR1 Register an interrupt flag is set and the timer is cleared.

    To make it easy to calculate the time base I have configured the PIC18F25K22 for 16Mhz clock and timer1 for a prescale of 1:4. This means that each timer tick is 1 microsecond.

    With this method, several more servos could be controlled in the servo subroutine.
    This could be the basis for a very nice PIC based servo controller using Great Cow Basic.

    Here is some demo code to show how to set up a 20ms period timer and control a servo.

    #chip 18F25K22, 16
    #config OSC = INTIO67
    
    #define Servo_Pin PORTC.0   '// Servo signal On PIN 11
    Dir PortC.0  Out
    
    Dim Servo_Pos as WORD
    Dim TIME_BASE alias CCPR1H,CCPR1L AS WORD   '// Programmable "Compare" Value
    CCP1CON = b'00001011'     '// Config CCP1 for Compare:Spcl Event trigger
    
    TIME_BASE = 20000    '// Make period timer = 20ms (2000us)
    
    On Interrupt CCP1 Call Servo_Pulse
    
    InitTimer1 OSC,PS1_4    '// Configure timer1 with Prescale of 1:4
    ClearTimer 1            '//Make Sure timer is cleared to 0
    StartTimer 1            '// Start the timer
    
    '-------  Main Loop  -------
     Do
        '//  We could read adc here or even receive servo position'
        '// data from other sources such  as an RF receiver.
    
        Servo_POS = 900
         Wait 1 s
    
         Servo_Pos = 1500
         Wait 1 s
    
         Servo_Pos = 2200
         Wait 1 s
    
         Servo_Pos = 1500
         wait 1 s
    Loop
    '----------------------------
    
    Sub Servo_Pulse
       PulseOut Servo_Pin, Servo_Pos us
    End Sub
    

    Enjoy

     

    Last edit: William Roth 2016-01-21
  • William Roth

    William Roth - 2016-01-22

    I went ahead and built and tested a 4 channel Servo Controller using the technique previously described. It should be possible to have as many as seven servos in the loop.

    Attached is the working code and a schematic. Modify to suit your chip selection.

     
  • viscomjim

    viscomjim - 2016-01-24

    Hi William, this is a very cool example. Really helps show how to use the ccp and timer. Thank You!!!!

     
  • stan cartwright

    stan cartwright - 2017-02-14

    I was looking for a servo routine. Thank you. I was going to use timer 0.

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.