PIC16F84A Servo Driver Troubles

Discussion in 'Embedded Systems and Microcontrollers' started by solpic, Sep 14, 2009.

  1. solpic

    Thread Starter Member

    Jul 23, 2009
    25
    0
    Hello everyone,

    I am writing code that should make a PIC16F84A be a driver for two servos and a dc motor. Also the code should make an LED blink, but that is just for show. I am trying to use Timer0 to make my own PWM module for the two servos and the motor. The servos have a refresh at 20 milliseconds with the longest pulse being at 2.1 milliseconds and the shortest at 1.9 milliseconds. The dc motor, is just a dc motor, but neither the dc motor or the second servo is even attached right now. Also I am using a 18.432 mHz crystal to get a high enough frequency to do PWM. I am not sure why it is not working, even the LED does not light up. Any comments would be great, here is the code:
    (all the delay routines right now are just for testing, when it is really running it will accept input from the other pins)
    Code ( (Unknown Language)):
    1. #include "p16f84a.inc"
    2.  
    3. cblock    0x0C
    4.     servo1
    5.     servo2
    6.     motor1
    7.     servo1c
    8.     servo2c
    9.     motor1c
    10.     temp
    11.     count1
    12.     count2
    13. endc
    14.  
    15.     org    0x0000
    16.     goto    main
    17.  
    18.     org    0x0004
    19.     ;interrupt routine
    20.     movwf    temp
    21.     call    servo1R
    22.     call    servo2R
    23.     call    motor1R
    24.     movf    temp, 0
    25.     bcf    INTCON, 2
    26.     bcf    INTCON, 1
    27.     retfie
    28.  
    29.  
    30.  
    31. servo1R
    32.  
    33.     incfsz    servo1c
    34.     goto    regS1
    35.     bsf    PORTA, 0
    36. regS1:    movf    servo1, 0
    37.     subwf    servo1c, 0
    38.     btfss    STATUS, C
    39.     goto    lsrS1        ;servo1c has not exceeded servo1
    40.     goto    gtrS1
    41. lsrS1:    return
    42. gtrS1:    bcf    PORTA, 0
    43.  
    44. return
    45.  
    46.  
    47. servo2R
    48.  
    49.     incfsz    servo2c
    50.     goto    regS2
    51.     bsf    PORTA, 1
    52. regS2:    movf    servo2, 0
    53.     subwf    servo2c, 0
    54.     btfss    STATUS, C
    55.     goto    lsrS2        ;servo2c has not exceeded servo2
    56.     goto    gtrS2
    57. lsrS2:    return
    58. gtrS2:    bcf    PORTA, 1
    59.  
    60. return
    61.  
    62.  
    63. motor1R
    64.  
    65.     incfsz    motor1c
    66.     goto    regM1
    67.     bsf    PORTA, 2
    68. regM1:    movf    motor1, 0
    69.     subwf    motor1c, 0
    70.     btfss    STATUS, C
    71.     goto    lsrM1        ;motor1c has not exceeded motor1
    72.     goto    gtrM1
    73. lsrM1:    return
    74. gtrM1:    bcf    PORTA, 2
    75.  
    76. return
    77.  
    78.  
    79. delay
    80.     movlw    0xFF
    81.     movwf    count1
    82.     movwf    count2
    83. loop    decfsz    count1, 1
    84.     goto    loop
    85.     decfsz    count2, 1
    86.     goto loop
    87. return
    88.  
    89. longdelay
    90.  
    91.     call    delay
    92.     call    delay
    93.     call    delay
    94.     call    delay
    95.     call    delay
    96.     call    delay
    97.     call    delay
    98.     call    delay
    99.     call    delay
    100.     call    delay
    101.     call    delay
    102.     call    delay
    103.     call    delay
    104.     call    delay
    105.     call    delay
    106.     call    delay
    107.     call    delay
    108.     call    delay
    109.     call    delay
    110.     call    delay
    111. return
    112.  
    113.  
    114. main:    bsf    STATUS, RP0    ;bank 1
    115.     movlw    b'00000'    
    116.     movwf    TRISA        ;configure port A
    117.     movlw    0xFF    
    118.     movwf    TRISB        ;port B as inputs
    119.     bcf    STATUS, RP0    ;bank 0
    120.     clrf    PORTA
    121.     bcf    OPTION_REG, 5    ;select timer mode
    122.     bsf    INTCON, 5    ;set bit T0IE
    123.     bcf    INTCON, 2    ;clear bit T0IF
    124.     bsf    INTCON, 7    ;enable interrupts
    125.     bcf    INTCON, 1    ;clear INTF
    126.     movlw    b'00111'
    127.     movwf    PORTA
    128. mainloop:
    129.     bsf    PORTA, 3
    130.     movlw    0x0F
    131.     movwf    servo1
    132.     call    longdelay
    133.     call    longdelay
    134.     bcf    PORTA, 3
    135.     movlw    0x25
    136.     movwf    servo1
    137.     call    longdelay
    138.     call    longdelay
    139.     goto     mainloop
    140.     end
     
  2. rom_pf05

    New Member

    Sep 15, 2009
    3
    0
    are you connecting directly thee motors to the outputs of the pic? or u have an external driver for the motors?
     
  3. blueroomelectronics

    AAC Fanatic!

    Jul 22, 2007
    1,758
    98
    The 16F84A is a 10MHz part.
    Where are your config settings?
     
  4. solpic

    Thread Starter Member

    Jul 23, 2009
    25
    0
    In answer to all your questions:

    1. No I am not directly connecting the motors to the outputs of the PIC. The two servos have their own driver circuitry in them and the standard DC motor I will attach with transistors.

    2. This is an attempt to create software PWM among other things. The servos, if you haven't used them before (which I haven't), are controlled by sending a 0.9 to 2.1 millisecond high pulse at least every 20 milliseconds to control their angle. The DC motor uses the same algorithm but will have a capacitor so it can supply a varying voltage, but I have not attached the DC motor yet. If my code is not very clear I am sorry, but in org 0x0004 (the interrupt routine), it calls each of the driver functions, which each increment an 8 bit counter (servo1c, servo2c, motor1c) and if the counter surpasses the values assigned to each motor/servo (servo1, servo2, motor1), then the pin for that part goes low and when the counter goes back to 0 the pin goes high. All the delays are for when I test it I can clearly see it moving from about -90 degrees to 90 degrees clearly. In this code I only have servo1 enabled.

    3. In the datasheet for the PIC16F84A http://ww1.microchip.com/downloads/en/devicedoc/35007b.pdf it says that the PIC is a 20mHz part, but I have never tried it with this crystal before so that could be the cause. I am pretty sure I have none of the config settings enabled, I am sure WDT is disabled, and the other two boxes in IC-Prog are unchecked as well.
     
  5. blueroomelectronics

    AAC Fanatic!

    Jul 22, 2007
    1,758
    98
    You're right, the older 16F84 is 10MHz.

    Do you have proper supply filtering and decoupling? Can you post your schematic?

    You have to set your oscillator type to HS for that crystal.
     
  6. solpic

    Thread Starter Member

    Jul 23, 2009
    25
    0
    Ah, I feel like an idiot. I had my clkIn clkOut wires connected to ground and power. Also, I did not have HS enabled. What does HS do? Is it High Speed? Furthermore, the blinking LED works but the servos do not work. I guess now I can actually look for problems with my code. Does anyone see any problems?
     
  7. blueroomelectronics

    AAC Fanatic!

    Jul 22, 2007
    1,758
    98
    HS is high speed crystal.
     
Loading...