Interupt driven servo PWM output


Results 1 to 10 of 10

Threaded View

  1. #1

    Default Interupt driven servo PWM output

    18F46K22 PBP2.6C

    Ok, wanting to command a servo... but, want to use interupts so that the pic can do other things and/or drive multiple servo's...

    So, first of all, i started off doing it with PAUSEUS to make sure i get the timings right...

    Code:
    SERVO1 VAR LATD.0
    SERVO1POS VAR BYTE
    
    MAIN:
    SERVO1POS = 128
    FOR ALOOP = 1 to 250
    SERVO1 = 1
    PAUSEUS 988
    PAUSEUS (SERVO1POS * 4)
    SERVO1 = 0
    PAUSEUS (20000 - (988 + (SERVO1POS * 4)))
    NEXT ALOOP
    
    SERVO1POS = 1
    
    FOR ALOOP = 1 to 250
    SERVO1 = 1
    PAUSEUS 988
    PAUSEUS (SERVO1POS * 4)
    SERVO1 = 0
    PAUSEUS (20000 - (988 + (SERVO1POS * 4)))
    NEXT ALOOP
    
    SERVO1POS = 255
    
    FOR ALOOP = 1 to 250
    SERVO1 = 1
    PAUSEUS 988
    PAUSEUS (SERVO1POS * 4)
    SERVO1 = 0
    PAUSEUS (20000 - (988 + (SERVO1POS * 4)))
    NEXT ALOOP
    GOTO MAIN
    Simples... works perfectly...
    So now i start doing the math and working out the preloads for timers with the help of an excell spreadsheet.

    Code:
    SERVO1 VAR LATD.0
    SERVO1POS VAR BYTE
    PRELOAD1 VAR WORD
    PRELOAD2 VAR WORD
    PRELOAD3 VAR WORD
    SERVOCMDMODE VAR BYTE
    SERVOPWMCOUNTER VAR WORD
    
    PRELOAD1 = 63556                                                                ' 990us   '63556
    TMR0_CON_PL1 CON %10000010                                                      ' 1:8
    PRELOAD2 = 65528                                                                ' 4us     '65528
    TMR0_CON_PL2 CON %10000010                                                      ' 1:8
    PRELOAD3 = 29556                                                                ' 17990us '29556
    TMR0_CON_PL3 CON %10000010                                                      ' 1:8
    
    @ INT_ENABLE TMR0_INT
    TMR0L = PRELOAD3.LOWBYTE
    TMR0H = PRELOAD3.HIGHBYTE
    T0CON = TMR0_CON_PL3
    SERVOCMDMODE = 1
    
    MAIN:
    SERVO1POS = 0
    PAUSE 5000
    SERVO1POS = 128
    PAUSE 5000
    SERVO1POS = 255
    PAUSE 5000
    GOTO MAIN
    
    SERVO_HANDLER:
    IF SERVOCMDMODE = 2 Then
        IF SERVOPWMCOUNTER < 256 THEN
            T0CON = TMR0_CON_PL2
            TMR0L = PRELOAD2.LOWBYTE
            TMR0H = PRELOAD2.HIGHBYTE
            IF SERVO1POS < SERVOPWMCOUNTER THEN
                SERVO1 = 0
                LATD.1 = 0
                LATD.2 = 0
                LATD.3 = 0
            ELSE
                SERVO1 = 1
                LATD.1 = 0
                LATD.2 = 1
                LATD.3 = 0            
            ENDIF
            SERVOPWMCOUNTER = SERVOPWMCOUNTER + 1
        ELSE
            T0CON = TMR0_CON_PL3
            TMR0L = PRELOAD3.LOWBYTE
            TMR0H = PRELOAD3.HIGHBYTE
            SERVO1 = 0
                LATD.1 = 0
                LATD.2 = 0
                LATD.3 = 1
            SERVOCMDMODE = 1
        ENDIF
    @ INT_RETURN
    ENDIF
    
    IF SERVOCMDMODE = 1 Then
        T0CON = TMR0_CON_PL1
        TMR0L = PRELOAD1.LOWBYTE
        TMR0H = PRELOAD1.HIGHBYTE
        SERVOCMDMODE = 2
        SERVO1 = 1
        LATD.1 = 1
        LATD.2 = 0
        LATD.3 = 0
        SERVOPWMCOUNTER = 1
    @ INT_RETURN
    ENDIF
    
    @ INT_RETURN
    And thats where i now have a problem and i don't understand why.
    For debug purposes i added the three LATD outputs so that i could find where i was having issues.

    First off, the frequency is 46.75... ok, i'm sure it can still handle it, and i can adjust this later.
    Secondly, the duty cycle goes from 84.0% to 93.9% to 99.6%...
    It should be 5%, 7.5% and 10%...
    Debug output shows LATD1 at 84.4%...

    LATD1 is for pre-duty phase, when in my code is SERVOCMDMODE = 1
    It's on for 84% of the time and it shouldn't, it should be 5%...

    I'm looking at my code thinking 'that is not possible'...

    So, I've got to have made a stupid mistake somewhere and i can't see it. Can some wonderful person tell me what my stupid mistake is?
    Thanks
    Last edited by comwarrior; - 15th August 2013 at 00:16.

Similar Threads

  1. Servo and pwm
    By Meriachee in forum mel PIC BASIC Pro
    Replies: 10
    Last Post: - 29th May 2009, 14:26
  2. how to change servo motor PWM
    By dboy in forum mel PIC BASIC Pro
    Replies: 15
    Last Post: - 21st September 2008, 07:02
  3. Help needed - MOSFET driven by PWM
    By bcd in forum mel PIC BASIC Pro
    Replies: 8
    Last Post: - 2nd April 2008, 05:02
  4. 16F877a Interupt driven Hserin
    By RFsolution in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 3rd November 2006, 00:38
  5. 16f73 pwm capture interupt
    By EDWARD in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 22nd July 2005, 22:22

Members who have read this thread : 0

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

Tags for this Thread

Posting Permissions

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