1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

Junebug Servo C18 code.

Discussion in 'Microcontrollers' started by Pommie, Feb 6, 2008.

  1. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,007
    Likes:
    316
    Location:
    Brisbane Australia
    On another thread someone asked about C18 servo code and I wrote a simple version. It occurred to me that it wouldn't be too difficult to make this work on the Junebug and so here it is. This code reads the potentiometer on AN1 (VR1) and sets the position of a servo on RB3 to match it.

    Switches 1,2,3 & 8 on.
    Code (text):

    #include <p18f1320.h>
    #pragma config WDT = OFF, LVP = OFF, OSC = INTIO2
    #define ServoPin LATBbits.LATB3
    #define ServoTris TRISBbits.TRISB3

    void main(void){
    int ServoPos;
        OSCCON=0x70;                //Osc=8MHz
        ADCON0=0b00000101;          //A2D on and select AN1
        ADCON1=0x7d;                //A1 = analogue
        ADCON2=0b10110101;          //Right justify - Fosc/16
        ServoTris=0;                //make servo pin output
        ServoPin=0;                 //Servo output off
        CCP1CON=0b00001011;         //Special event trigger
        T1CON=0b10010001;           //Timer 1 on with Pre=2
        ServoPos=1500;              //set servo to mid position
        CCPR1=ServoPos;             //set CCP initial value  
        while(1){
            while(!PIR1bits.CCP1IF);    //wait for CCP interrupt bit
            ServoPin=0;                 //end pulse
            CCPR1=20000-ServoPos;       //Off time = 20mS - Servo Time
            PIR1bits.CCP1IF=0;          //clear int flag
            ADCON0bits.GO=1;            //start conversion
            while(ADCON0bits.GO);       //Wait for it to complete
            ServoPos=ADRES+1000;        //Pos will be 1mS to 2.023mS
            while(!PIR1bits.CCP1IF);    //wait for int flag
            ServoPin=1;                 //start pulse
            CCPR1=ServoPos;             //Servo time in uS
            PIR1bits.CCP1IF=0;          //clear int flag
        }
    }
    Have fun.

    Mike.
    Project file attached.
     
    Last edited: Jul 6, 2008
  2. blueroomelectronics

    blueroomelectronics Well-Known Member

    Joined:
    Jan 21, 2007
    Messages:
    12,536
    Likes:
    168
    Location:
    Toronto, Canada
    Your code looks great, I'm starting to be able to read and understand C18.

    I've noticed many C18 programs use
    #include <p18Cxxxx.h>
     
    Last edited by a moderator: Dec 4, 2011
  3. Nigel Goodwin

    Nigel Goodwin Super Moderator Most Helpful Member

    Joined:
    Nov 17, 2003
    Messages:
    39,203
    Likes:
    640
    Location:
    Derbyshire, UK
    I don't do C, but assembler programs use an include file for the same reason.
     
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. August Treubig

    August Treubig Member

    Joined:
    Nov 28, 2007
    Messages:
    95
    Likes:
    2
    Location:
    Arkansas

    What are C header files for?

    The inclusion of 18cxxxx is done to get the proper definitions for your target pic (given that it is an 18).

    This is the first few lines of 18cxxxx.h

    Code (c18):
    #ifndef _P18CXXX_H
    #define _P18CXXX_H

    #if defined(__18C242)
    #include <p18c242.h>
    #elif defined(__18C252)
    #include <p18c252.h>
    #elif defined(__18C442)
    #include <p18c442.h>
    #elif defined(__18C452)
    #include <p18c452.h>
    So, by picking your target as say and 18F1320, then p18f1320.h will get included. Why don't we just include p18f1320.h directly.
    Well suppose you change targets to "say" a 18F4620, then you have to edit the include line. This is just the way it is done for proper coding. ;)

    So what is in p18f1320.h

    It will hold the definitions for all the memory locations (TRISA, LATA, etc) that you will be using in the program. With the header files, the compiler doesn't have to have "hard coded" things built in. Microchip can build a new pic with things in slightly different places and they just create a new header file and the compiler can find where they are.

    I highly recommend that you go view the header files. Mine are in c:\MCC18\h

    :)
     
    Last edited by a moderator: Dec 4, 2011
    • Like Like x 1
  6. Odin

    Odin Member

    Joined:
    Jun 29, 2004
    Messages:
    43
    Likes:
    1
    Location:
    Norway
    I had some trouble with my MPlab when I tested the code. The project wouldn't build due to some linker script error. Gonna try on another laptop. I've just built a servo tester with a 16F684, and asm code from a Myke Predko book. Not much more than a pot and the pic. I'm in the process of building a R/C helicopter, and needed something to center the servoes, in the absence of a radio system. A switch to make the circuit output exactly 1,5 ms for center position would be nice. A two position switch, to choose between center lock and normal operation. Would also be good if the pic outputs 1,5 ms until the pot reaches center position. That would avoid wrecking the servo gears if the switch is moved when the pot is at either end. (if the servo stalls because of mechanical limitis in the model)

    Another use is for sending signals to an electronic speed controller (ESC). I've done that with an ESC for a brushless motor. Most ESCs woun't arm before you send them a zero throttle signal, 1,0 ms. Wouldn't harm if the servo tester just sent 1,0 ms until the pot is at zero throttle after boot up. And maybe a blinking LED if the pot is at > zero throttle.
    My sport R/C helicopter turned into a attack helicopter the other day. Spinning up at full speed on top of a table inside my garage. Falling down, chopping a big chunk of the table plate, while I was running for my life...
     
    Last edited by a moderator: Dec 4, 2011
  7. blueroomelectronics

    blueroomelectronics Well-Known Member

    Joined:
    Jan 21, 2007
    Messages:
    12,536
    Likes:
    168
    Location:
    Toronto, Canada
    Watch out with powering the Servo with your USB port. Using a powered hub will help as they can deliver the current a servo motor will need.
     
  8. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,637
    Likes:
    109
    Location:
    Michigan, USA
    Mike,

    May I suggest an interrupt version of that code for newcomers to study? The ISR vector setup isn't quite as intuitive as it is in some other languages.

    Regards...
     
  9. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,007
    Likes:
    316
    Location:
    Brisbane Australia
    Might have a go at that tomorrow. Good to see you back, been anywhere nice?

    Mike.
     
  10. hosh

    hosh New Member

    Joined:
    Oct 9, 2007
    Messages:
    16
    Likes:
    0
    Location:
    skiatook
    Pommie,

    Thanks for the code. I have ordered a junebug and one of my future projects will need this exact code.

    Corse, I still need to go through the tuts and learn C! But it still lets me see actual code and I tend to learn better from examples that I can dissect.
     
  11. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,007
    Likes:
    316
    Location:
    Brisbane Australia
    Here is a version that will go fully left if button 1 pressed, center if button 2 pressed and fully right if button 3 pressed. If you press all 3 buttons together it will take up the position defined by the pot.

    I also changed it to use interrupts because, as Mike said, it isn't as intuitive as one would imagine.

    Mike.
    Code (text):

    #include <p18f1320.h>
    #pragma config WDT = OFF, LVP = OFF, OSC = INTIO2

    #define ServoPin LATBbits.LATB3
    #define ServoTris TRISBbits.TRISB3

    void ccp1_isr();                    

    volatile int ServoPos;          //used to hold the servo position

    #pragma code low_vector=0x18    //setup the ISR vector
    void low_interrupt (){
      _asm GOTO ccp1_isr _endasm    //jump to interrupt handler
    }
    #pragma code

    #pragma interruptlow ccp1_isr   //the ISR
    void ccp1_isr(){
        if(ServoPin==1){            //will be 1 if we are at end of pulse
            ServoPin=0;             //turn off servo output
            CCPR1=20000-ServoPos;   //Off time = 20mS - Servo Time
        }
        else{
            ServoPin=1;             //turn on servo output
            CCPR1=ServoPos;         //On time
        }
        PIR1bits.CCP1IF=0;          //clear int flag
    }
    #pragma code

    void main(){
        OSCCON=0x70;                //Osc=8MHz
        ADCON0=0b00000101;          //A2D on and select AN1
        ADCON1=0x7d;                //A1 = analogue
        ADCON2=0b10110101;          //Right justify - Fosc/16
        ServoTris=0;                //make bit 0 output
        ServoPin=0;                 //Servo output off
        CCP1CON=0b00001011;         //Special event trigger
        T1CON=0b10010001;           //Timer 1 on with Pre=2
        ServoPos=1500;              //set servo to mid position
        CCPR1=ServoPos;             //set CCP initial value  
        PIE1bits.CCP1IE=1;          //enable CCP1 interrupt
        INTCONbits.PEIE=1;          //enable peripheral interrupts
        INTCONbits.GIE=1;           //enable glogal interrupts
        INTCON2bits.RBPU=0;         //enable port b week pullups
        while(1){                   //loop forever
        static char Mode=0;             //0 = use ADC, 1=fixed pos
        static char Keys;               //holds previous key values
        char OldKeys,Edges;             //local variables
            while(!ServoPin);           //Wait for start of servo pulse
            while(ServoPin);            //wait for end - makes for good debounce
            OldKeys=Keys;               //make a copy of keys
            Keys=PORTB&0b00100101;      //get switch state
            Keys^=0b00100101;           //make pressed keys = 1
            if(Keys==0b00100101)        //all 3 pressed?
                Mode=0;                 //yes, set to use ADC input
            Edges=(Keys^OldKeys);       //keep only keys that have changed
            Edges&=Keys;                //keep only new key presses - not key releases
            if(Mode==0){                //are we using the pot?
                ADCON0bits.GO=1;        //yes, start conversion
                while(ADCON0bits.GO);   //Wait for it to complete
                ServoPos=ADRES+1000;    //Pos will be 1mS to 2.023mS
            }
            if(Edges!=0)                //any key pressed
                Mode=1;                 //switch to fixed mode
            if(Edges==0b00000001)       //Key 1 pressed
                ServoPos=1000;          //set servo fully left
            if(Edges==0b00000100)       //key 2?
                ServoPos=1500;          //set center
            if(Edges==0b00100000)       //key 3?
                ServoPos=2000;          //set fully right
        }
    }
     
    Last edited: Feb 8, 2008
  12. blueroomelectronics

    blueroomelectronics Well-Known Member

    Joined:
    Jan 21, 2007
    Messages:
    12,536
    Likes:
    168
    Location:
    Toronto, Canada
    Thanks Pommie, I'm starting to C the light. :)

    Now I've got to learn what pragma do, I originally thought it was for CONFIG now it also seems to be like ORG
     
  13. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,637
    Likes:
    109
    Location:
    Michigan, USA
    Very nice Mike (Pommie). Again, excellent comments for newcomer and veteran alike.

    The 18F1320 Data Sheet seems to indicate that the CCP/ECCP module "special event trigger" mode automatically starts an ADC acquisition and conversion by setting the ADCON0bits.GO bit for you if the ADC module is turned on. Does that mean you could eliminate setting the ADCON0bits.GO bit? Would that require moving the ADC conversion into the ISR (to avoid timing problems)? Would there be any advantage doing it that way (in the ISR)?

    Code (text):

    void ccp1_isr()
    { if(ServoPin = !ServoPin)    // if toggled ServoPin = 1
        CCPR1 = ServoPos;         // setup "on" time match value
      else                        // else
        CCPR1 = 20000 - ServoPos  // setup "off" time match value
      while(ADCON0bits.GO);       // wait for ADC conversion
      ServoPot=ADRES+1000;        // <-- new variable
      PIR1bits.CCP1IF=0;          // clear CCP1 interrupt flag bit
    }
     
     
    Last edited: Feb 10, 2008
  14. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,007
    Likes:
    316
    Location:
    Brisbane Australia
    I hadn't realised that the ADC would automatically be triggered. On the 16 series this only happens on CCP2 (when 2 CCP modules are available) and I had assumed it would be the same for the 18 series.

    I just commented out the setting of the Go bit and it still works. The "special event trigger" does start the conversion.

    Mike.
     
  15. blueroomelectronics

    blueroomelectronics Well-Known Member

    Joined:
    Jan 21, 2007
    Messages:
    12,536
    Likes:
    168
    Location:
    Toronto, Canada
    The 18 series also supports an automatic acquisition delay. Such nice PICs.
     
  16. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,007
    Likes:
    316
    Location:
    Brisbane Australia
    I know, I set it to 16 Tad.:D

    Mike.
     
  17. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.
    Work has been hectic lately and I haven't had much time to play. Saw the post, but couldn't do anything with it till today.

    Here's an asm port of Pommie's first posted program:
    Code (text):
        list    p=18F1320
        include <p18F1320.inc>
        CONFIG  OSC=INTIO2,WDT=OFF,MCLRE=ON,LVP=OFF

        cblock  0x00
            ServoPosH,ServoPosL,src1,src2,dst1,dst2
        endc

        org 0x0000
    init    movlw   0x70
        movwf   OSCCON          ;Osc=8MHz
        movlw   b'00000101'     ;A2D on and select AN1
        movwf   ADCON0
        movlw   b'01111101'     ;A1 = analog
        movwf   ADCON1
        movlw   b'10110101'     ;Right justify - Fosc/16
        movwf   ADCON2
        bcf TRISB,3         ;make servo pin output
        bcf LATB,3          ;Servo output off
        movlw   b'00001011'     ;Special event trigger
        movwf   CCP1CON
        movlw   b'10010001'     ;Timer 1 on with Pre=2
        movwf   T1CON
        movlw   0x05            ;set servo to mid position
        movwf   ServoPosH
        movwf   CCPR1H          ;and set CCP initial value
        movlw   0xdc
        movwf   ServoPosL
        movwf   CCPR1L
       
    main    btfss   PIR1,CCP1IF     ;wait for CCP interrupt bit
        goto    main
        bcf LATB,3          ;end pulse
        movlw   0x4e            ;Off time = 20ms - Servo Time
        movwf   src1
        movlw   0x20
        movwf   src2
        movff   ServoPosH,dst1
        movff   ServoPosL,dst2
        call    sub16
        movff   dst1,CCPR1H
        movff   dst2,CCPR1L
        bcf PIR1,CCP1IF     ;clear int flag
        bsf ADCON0,GO       ;start conversion
    conv    btfsc   ADCON0,DONE     ;Wait for it to complete
        goto    conv
        movff   ADRESH,src1     ;Pos will be 1ms to 2.023ms
        movff   ADRESL,src2
        movlw   0x03
        movwf   dst1
        movlw   0xe8
        movwf   dst2
        call    add16
        movff   dst1,ServoPosH
        movff   dst2,ServoPosL
    wait    btfss   PIR1,CCP1IF     ;wait for int flag
        goto    wait
        bsf LATB,3          ;start pulse
        movff   ServoPosH,CCPR1H    ;Servo time in uS
        movff   ServoPosL,CCPR1L
        bcf PIR1,CCP1IF     ;clear int flag
        goto    main

    sub16   movf    src2,W
        subwf   dst2,F
        movf    src1,W
        btfss   STATUS,C
        incf    src1,W
        subwf   dst1,F
        return

    add16   movf    src2,W
        addwf   dst2,F
        movf    src1,W
        btfsc   STATUS,C
        incf    src1,W
        addwf   dst1,F
        return

        end
     
    Last edited: Feb 9, 2008
  18. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,007
    Likes:
    316
    Location:
    Brisbane Australia
    Nicely done Futz. Are you going to do the interrupt version as well?

    One little suggestion to make it more readable. Use word variables with Lo and Hi on the end instead of 1 & 2, use the . with decimal numbers and make use of the low and high directives.
    Code (text):

    ;so this
        movlw   0x03
        movwf   dst1
        movlw   0xe8
        movwf   dst2
        call    add16
    ;becomes
        movlw   low(.1000)
        movwf   dstLo
        movlw   high(.1000)
        movwf   dstHi
        call    add16
     
    Mike.
     
  19. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.
    The port is done, but the buttons aren't working yet. I have to go through it (maybe tomorrow) and see what I did wrong. Most likely I got one of the bit tests backward and it's branching the wrong way. The potentiometer/servo part works fine though.

    Those 1 & 2 things came from Chuck McMannis, the guy I stole those 16-bit add/subtract code snips from. I didn't change a thing. I prefer to use H and L suffixes. I'll change that in the second port.

    I used a decimal number? :eek: If so, I sure didn't mean to. I usually think in hex. :D
    EDIT: Ah, I see what you're talking about.

    Good stuff. I'll put those suggestions into future programs. Thanks! :D
     
    Last edited: Feb 10, 2008
  20. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.
    Finally found the problem. Here's the asm port of Pommie's second program:
    Code (text):
        list    p=18F1320
        include <p18F1320.inc>
        CONFIG  OSC=INTIO2,WDT=OFF,MCLRE=ON,LVP=OFF

        cblock  0x00
            Mode,Keys,OldKeys,Edges,ServoPosH,ServoPosL
            srcH,srcL,dstH,dstL
        endc

        org 0x00
        goto    init

        org 0x18
    isr btfss   PORTB,3         ;the ISR
        goto    else1
        bcf LATB,3          ;turn off servo output
        movlw   high(.20000)        ;Off time = 20ms - Servo Time
        movwf   srcH
        movlw   low(.20000)
        movwf   srcL
        movff   ServoPosH,dstH
        movff   ServoPosL,dstL
        call    sub16
        movff   dstH,CCPR1H
        movff   dstL,CCPR1L
        goto    isr_done
    else1   bsf LATB,3          ;turn on servo output
        movff   ServoPosH,CCPR1H    ;On time
        movff   ServoPosL,CCPR1L
    isr_done
        bcf PIR1,CCP1IF     ;clear int flag
        retfie  FAST
       
    init    movlw   0x70
        movwf   OSCCON          ;Osc=8MHz
        movlw   b'00000101'     ;A2D on and select AN1
        movwf   ADCON0
        movlw   b'01111101'     ;A1 = analog
        movwf   ADCON1
        movlw   b'10110101'     ;Right justify - Fosc/16
        movwf   ADCON2
        bcf TRISB,3         ;make servo pin output
        bcf LATB,3          ;Servo output off
        movlw   b'00001011'     ;Special event trigger
        movwf   CCP1CON
        movlw   b'10010001'     ;Timer 1 on with Pre=2
        movwf   T1CON
        movlw   high(.1500)     ;set servo to mid position
        movwf   ServoPosH
        movwf   CCPR1H          ;and set CCP initial value
        movlw   low(.1500)
        movwf   ServoPosL
        movwf   CCPR1L
        bsf PIE1,CCP1IE     ;enable CCP1 interrupt
        bsf INTCON,PEIE     ;enable peripheral interrupts
        bsf INTCON,GIE      ;enable global interrupts
        bcf INTCON2,RBPU        ;enable PORTB weak pullups
       
    main    btfss   PORTB,3         ;Wait for start of servo pulse
        goto    main
    wait2   btfsc   PORTB,3         ;wait for end - makes for good debounce
        goto    wait2
        movff   Keys,OldKeys        ;make a copy of keys
        movf    PORTB,W         ;get switch state
        andlw   b'00100101'
        movwf   Keys
        movlw   b'00100101'     ;make pressed keys = 1
        xorwf   Keys,F
        movlw   b'00100101'     ;all 3 pressed?
        cpfseq  Keys
        goto    not3
        clrf    Mode            ;yes, set to use ADC input
    not3    movf    Keys,W          ;keep only keys that have changed
        xorwf   OldKeys,W
        movwf   Edges
        andwf   Keys,W          ;keep only new key presses - not key releases
        movwf   Edges
        tstfsz  Mode            ;are we using the pot?
        goto    nomode
        bsf ADCON0,GO       ;yes, start conversion
    waitcv  btfsc   ADCON0,DONE     ;wait for it to complete
        goto    waitcv
        movff   ADRESH,srcH     ;Pos will be 1ms to 2.023ms
        movff   ADRESL,srcL
        movlw   high(.1000)
        movwf   dstH
        movlw   low(.1000)
        movwf   dstL
        call    add16
        movff   dstH,ServoPosH
        movff   dstL,ServoPosL
    nomode  tstfsz  Edges           ;any key pressed
        goto    mode1           ;go switch to fixed mode
        goto    mode0
    mode1   movlw   1           ;switch to fixed mode
        movwf   Mode
    mode0   movlw   1
        subwf   Edges,W         ;key 1 pressed
        btfss   STATUS,Z
        goto    key2
        movlw   high(.1000)     ;set servo fully left
        movwf   ServoPosH
        movlw   low(.1000)
        movwf   ServoPosL
        goto    again
    key2    movlw   0x04            ;key 2?
        subwf   Edges,W
        btfss   STATUS,Z
        goto    key3
        movlw   high(.1500)     ;set center
        movwf   ServoPosH
        movlw   low(.1500)
        movwf   ServoPosL
        goto    again
    key3    movlw   0x20            ;key 3?
        subwf   Edges,W
        btfss   STATUS,Z
        goto    again
        movlw   high(.2000)     ;set fully right
        movwf   ServoPosH
        movlw   low(.2000)
        movwf   ServoPosL  
    again   goto    main

    sub16   movf    srcL,W
        subwf   dstL,F
        movf    srcH,W
        btfss   STATUS,C
        incf    srcH,W
        subwf   dstH,F
        return

    add16   movf    srcL,W
        addwf   dstL,F
        movf    srcH,W
        btfsc   STATUS,C
        incf    srcH,W
        addwf   dstH,F
        return

        end
    and here's the first one again, modified with the suggestions from a few posts ago:
    Code (text):
        list    p=18F1320
        include <p18F1320.inc>
        CONFIG  OSC=INTIO2,WDT=OFF,MCLRE=ON,LVP=OFF

        cblock  0x00
            ServoPosH,ServoPosL,srcH,srcL,dstH,dstL
        endc

        org     0x0000
    init    movlw   0x70
        movwf   OSCCON          ;Osc=8MHz
        movlw   b'00000101'     ;A2D on and select AN1
        movwf   ADCON0
        movlw   b'01111101'     ;A1 = analog
        movwf   ADCON1
        movlw   b'10110101'     ;Right justify - Fosc/16
        movwf   ADCON2
        bcf TRISB,3         ;make servo pin output
        bcf LATB,3          ;Servo output off
        movlw   b'00001011'     ;Special event trigger
        movwf   CCP1CON
        movlw   b'10010001'     ;Timer 1 on with Pre=2
        movwf   T1CON
        movlw   high(.1500)     ;set servo to mid position
        movwf   ServoPosH
        movwf   CCPR1H          ;and set CCP initial value
        movlw   low(.1500)
        movwf   ServoPosL
        movwf   CCPR1L
       
    main    btfss   PIR1,CCP1IF     ;wait for CCP interrupt bit
        goto    main
        bcf LATB,3          ;end pulse
        movlw   high(.20000)        ;Off time = 20ms - Servo Time
        movwf   srcH
        movlw   low(.20000)
        movwf   srcL
        movff   ServoPosH,dstH
        movff   ServoPosL,dstL
        call    sub16
        movff   dstH,CCPR1H
        movff   dstL,CCPR1L
        bcf PIR1,CCP1IF     ;clear int flag
        bsf ADCON0,GO       ;start conversion
    conv    btfsc   ADCON0,DONE     ;Wait for it to complete
        goto    conv
        movff   ADRESH,srcH     ;Pos will be 1ms to 2.023ms
        movff   ADRESL,srcL
        movlw   high(.1000)
        movwf   dstH
        movlw   low(.1000)
        movwf   dstL
        call    add16
        movff   dstH,ServoPosH
        movff   dstL,ServoPosL
    wait    btfss   PIR1,CCP1IF     ;wait for int flag
        goto    wait
        bsf LATB,3          ;start pulse
        movff   ServoPosH,CCPR1H    ;Servo time in uS
        movff   ServoPosL,CCPR1L
        bcf PIR1,CCP1IF     ;clear int flag
        goto    main

    sub16   movf    srcL,W
        subwf   dstL,F
        movf    srcH,W
        btfss   STATUS,C
        incf    srcH,W
        subwf   dstH,F
        return

    add16   movf    srcL,W
        addwf   dstL,F
        movf    srcH,W
        btfsc   STATUS,C
        incf    srcH,W
        addwf   dstH,F
        return

        end
     
    Last edited: Feb 10, 2008
  21. Odin

    Odin Member

    Joined:
    Jun 29, 2004
    Messages:
    43
    Likes:
    1
    Location:
    Norway
    Found out the hard way... No damage though. I'm using a separate 5 V powersupply for the servo now.
     

Share This Page