help

Discussion in 'Programmer's Corner' started by minmx, May 3, 2010.

  1. minmx

    Thread Starter New Member

    May 3, 2010
    1
    0
    someone can give the algorithm to control a servo with PWM on pic16f84a please
     
  2. R!f@@

    AAC Fanatic!

    Apr 2, 2009
    8,754
    760
    or dear...
    i don't think any one has any thing to give.
    but we can discuss
     
  3. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    You need to send a 1-2ms pulse @ 5V every 20ms.
    The width of the pulse controls the position of the servo.

    If you haven't already bought it, consider a more recent, better and probably cheaper PIC like the 16F628.
     
  4. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    Just found this old file of mine that controls 4 servos with a pretty crazy method. It does work, but understanding how it does might be tricky.

    Code ( (Unknown Language)):
    1.  
    2.     list    p=16F84a
    3.     radix    hex
    4.     title "SERVO"
    5.         #include <p16f84a.inc>
    6.     __config _CP_OFF & _PWRTE_OFF & _WDT_OFF & _HS_OSC
    7.  
    8. ;    servo control 1-2ms pulse every 20ms
    9.     cblock 0x0C
    10.     W_TEMP
    11.     STATUS_TEMP
    12.  
    13.     servo0            ;pin rb0 position 0-255
    14.     servo1
    15.     servo2
    16.     servo3            ;pin rb3
    17.     intservogoto
    18.    
    19.     endc
    20.    
    21.  
    22. ;    org 0x2100        ;initial values for timer H and L bytes (10 seconds)
    23. ;    de 0x00,0x0a    ;first 2 bytes of eeprom
    24.  
    25. ;----------------------------------------------------------------------
    26.  
    27.     org    0x000
    28.     goto init
    29.     org 0x004    ;interrupt goes here
    30.     MOVWF W_TEMP ; Copy W to TEMP register,
    31.     SWAPF STATUS, W ; Swap status to be saved into W
    32.     MOVWF STATUS_TEMP ; Save status to STATUS_TEMP register
    33.          ; Interrupt Service Routine
    34.    
    35. ;writes intservergoto to program counter to send timing pulses to 4 servos in sequence
    36. ;without any messy logic. Initial value of intservergoto 09h. Timing is for 4MHz clock
    37. ;0 in servo variables gives about 2ms pulse, 254 gives about 1ms
    38. ;Don't use 255 for servo value
    39. ;Advantages: fast, not many files used
    40. ;Disadvantages: uses lots of program memory, hard to modify
    41.  
    42.     movfw intservogoto    
    43.     movwf PCL
    44.     call prescaler4        ;PCL 09h        servo0
    45.     bsf PORTB,0            ;start pulse and next interrupt after 1ms
    46.     movlw 0E
    47.     movwf intservogoto
    48.     goto endint
    49.     movfw servo0        ;PCL 0E
    50.     movwf TMR0            ;variable part of pulse 0-1ms
    51.     movlw 13
    52.     movwf intservogoto
    53.     goto endint
    54.     call prescaler16    ;PCL 13
    55.     movlw 30            ;for 3.5ms pause before next servo
    56.     movwf TMR0
    57.     bcf PORTB,0            ;end pulse
    58.     movlw 1A
    59.     movwf intservogoto
    60.     goto endint
    61.     call prescaler4        ;PCL 1A        servo1
    62.     bsf PORTB,1            ;start pulse and next interrupt after 1ms
    63.     movlw 1F
    64.     movwf intservogoto
    65.     goto endint
    66.     movfw servo1        ;PCL 1F
    67.     movwf TMR0            ;variable part of pulse 0-1ms
    68.     movlw 24
    69.     movwf intservogoto
    70.     goto endint
    71.     call prescaler16    ;PCL 24
    72.     movlw 30            ;for 3.5ms pause before next servo
    73.     movwf TMR0
    74.     bcf PORTB,1            ;end pulse
    75.     movlw 2B
    76.     movwf intservogoto
    77.     goto endint
    78.     call prescaler4        ;PCL 2B        servo2
    79.     bsf PORTB,2            ;start pulse and next interrupt after 1ms
    80.     movlw 30
    81.     movwf intservogoto
    82.     goto endint
    83.     movfw servo2        ;PCL 30
    84.     movwf TMR0            ;variable part of pulse 0-1ms
    85.     movlw 35
    86.     movwf intservogoto
    87.     goto endint
    88.     call prescaler16    ;PCL 35
    89.     movlw 30            ;for 3.5ms pause before next servo
    90.     movwf TMR0
    91.     bcf PORTB,2            ;end pulse
    92.     movlw 3C
    93.     movwf intservogoto
    94.     goto endint
    95.     call prescaler4        ;PCL 3C        servo3
    96.     bsf PORTB,3            ;start pulse and next interrupt after 1ms
    97.     movlw 41
    98.     movwf intservogoto
    99.     goto endint
    100.     movfw servo3        ;PCL 41
    101.     movwf TMR0            ;variable part of pulse 0-1ms
    102.     movlw 46
    103.     movwf intservogoto
    104.     goto endint
    105.     call prescaler16    ;PCL 46
    106.     movlw 30            ;for 3.5ms pause before next servo
    107.     movwf TMR0
    108.     bcf PORTB,3            ;end pulse
    109.     movlw 09
    110.     movwf intservogoto
    111.  
    112.  
    113.     goto endint
    114.  
    115. prescaler4
    116.     bsf     STATUS, RP0    ; bank 1
    117.     movlw   B'10000001'     ; prescaler 4
    118.     movwf   OPTION_REG      ;  
    119.     bcf     STATUS, RP0    ; bank 0
    120.     return
    121.  
    122. prescaler16
    123.     bsf     STATUS, RP0    ; bank 1
    124.     movlw   B'10000011'     ; prescaler 16
    125.     movwf   OPTION_REG      ;  
    126.     bcf     STATUS, RP0    ; bank 0
    127.     return
    128.  
    129. endint
    130.  
    131.      ; should configure Bank as required
    132.      ;
    133.     SWAPF STATUS_TEMP,W     ; Swap nibbles in STATUS_TEMP register
    134.     ; and place result into W
    135.     MOVWF STATUS             ; Move W into STATUS register
    136.     ; (sets bank to original state)
    137.     SWAPF W_TEMP, F         ; Swap nibbles in W_TEMP and place result in W_TEMP
    138.     SWAPF W_TEMP, W         ; Swap nibbles in W_TEMP and place result into W
    139.     clrf INTCON                ;clr interupts
    140.     bsf    INTCON,T0IE            ;enable timer interupt
    141.     retfie
    142.    
    143. init    ;initialise stuff here
    144.     ;sets interupts only on timer0 internal and prescaler 256
    145.    
    146.     bsf     STATUS, RP0    ; bank 1
    147.     movlw   B'10000111'     ; rtcc inc = tcylc/256 = tclk/(4*256)
    148.     movwf   OPTION_REG      ;  
    149.     bcf     STATUS, RP0    ; bank 0
    150.  
    151.     movlw 09
    152.     movwf intservogoto
    153.  
    154.     clrf    TMR0            ; reset timer (and prescaler!)
    155.     movlw   B'10100000'     ; enable timer interrupt and GIE
    156.     movwf   INTCON          ;  
    157.    
    158.     BCF STATUS, RP0 ; bank 0
    159.     CLRF PORTB                 ; Initialize PORTB by
    160.                             ; clearing output
    161.                             ; data latches
    162.     BSF STATUS, RP0         ; Select Bank 1
    163.     MOVLW B'11110000'         ; Value used to
    164.                             ; initialize data
    165.                             ; direction
    166.     MOVWF TRISB             ; Set RB<0-3> as output, all others input
    167.                             ;porta should all be inputs anyway
    168.     BCF STATUS, RP0         ;bank 0
    169.  
    170.  
    171. start
    172.    
    173.     goto start
    174.  
    175.  
    176.  
    177.  
    178.     end
    179.  
     
Loading...