PIC16F84A Servo Driver Troubles

Thread Starter

solpic

Joined Jul 23, 2009
25
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)
Rich (BB code):
#include "p16f84a.inc"

cblock    0x0C
    servo1
    servo2
    motor1
    servo1c
    servo2c
    motor1c
    temp
    count1
    count2
endc

    org    0x0000
    goto    main

    org    0x0004
    ;interrupt routine
    movwf    temp
    call    servo1R
    call    servo2R
    call    motor1R
    movf    temp, 0
    bcf    INTCON, 2
    bcf    INTCON, 1
    retfie



servo1R

    incfsz    servo1c
    goto    regS1
    bsf    PORTA, 0
regS1:    movf    servo1, 0
    subwf    servo1c, 0
    btfss    STATUS, C
    goto    lsrS1        ;servo1c has not exceeded servo1
    goto    gtrS1
lsrS1:    return
gtrS1:    bcf    PORTA, 0

return


servo2R

    incfsz    servo2c
    goto    regS2
    bsf    PORTA, 1
regS2:    movf    servo2, 0
    subwf    servo2c, 0
    btfss    STATUS, C
    goto    lsrS2        ;servo2c has not exceeded servo2
    goto    gtrS2
lsrS2:    return
gtrS2:    bcf    PORTA, 1

return


motor1R

    incfsz    motor1c
    goto    regM1
    bsf    PORTA, 2
regM1:    movf    motor1, 0
    subwf    motor1c, 0
    btfss    STATUS, C
    goto    lsrM1        ;motor1c has not exceeded motor1
    goto    gtrM1
lsrM1:    return
gtrM1:    bcf    PORTA, 2

return


delay
    movlw    0xFF
    movwf    count1
    movwf    count2
loop    decfsz    count1, 1
    goto    loop
    decfsz    count2, 1
    goto loop
return

longdelay

    call    delay
    call    delay
    call    delay
    call    delay
    call    delay
    call    delay
    call    delay
    call    delay
    call    delay
    call    delay
    call    delay
    call    delay
    call    delay
    call    delay
    call    delay
    call    delay
    call    delay
    call    delay
    call    delay
    call    delay
return


main:    bsf    STATUS, RP0    ;bank 1
    movlw    b'00000'    
    movwf    TRISA        ;configure port A
    movlw    0xFF    
    movwf    TRISB        ;port B as inputs
    bcf    STATUS, RP0    ;bank 0
    clrf    PORTA
    bcf    OPTION_REG, 5    ;select timer mode
    bsf    INTCON, 5    ;set bit T0IE
    bcf    INTCON, 2    ;clear bit T0IF
    bsf    INTCON, 7    ;enable interrupts
    bcf    INTCON, 1    ;clear INTF
    movlw    b'00111'
    movwf    PORTA
mainloop:
    bsf    PORTA, 3
    movlw    0x0F
    movwf    servo1
    call    longdelay
    call    longdelay
    bcf    PORTA, 3
    movlw    0x25
    movwf    servo1
    call    longdelay
    call    longdelay
    goto     mainloop
    end
 

Thread Starter

solpic

Joined Jul 23, 2009
25
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.
 
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.
 

Thread Starter

solpic

Joined Jul 23, 2009
25
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?
 
Top