El código que mostramos a continuación se basa en las interrupciones del Timer 0. El mismo timer se utiliza para generar los intervalos de tiempo corto 300 us y los periodos de tiempo largo 2040us.
Para afinar los tiempos de ciclo correcto seria necesario adaptar todos los intervalos para que el resultado se aproximase lo mas posible a los 20 ms. Las pruebas que he realizado realizan el recorrido de 180º de un servo futaba S3003 con estos valores:
Minimo: 300us
Maximo: 2040us
Lo que nos da un calculo total de:
Timming = (8 x (300+2040)) = 18.720us
Tal y como mostramos en el gráfico de abajo, unos valores de 400 y 2100 establecerían los 20ms exactos para el ciclo de cada servo. Es posible modificar el código para adaptarlo a los tiempos de trabajo del servo que se utilice.

Con el timer 0 configurado a un prescaler de 1:16 y a la velocidad de trabajo (8Mhz) conseguimos unos 8us entre cada desbordamiento. Si esto lo multiplicamos por el rango de trabajo de cada servo tenemos un timming máximo de poco mas de 2ms. 8us x 255 = 2040us los 300us los conseguimos fijando el valor del registro TMR0 a 218.
Codigos:
'*******************************************************************************
' Control de 8 servos
'
' Implementado por Julio Montagut - www.jvmbots.com Agosto/2010
'
' Mikrobasic-PRO v: 3.80
'
' Descripcion:
'
' Este codigo se basa en las interrupciones creadas por el Timer 0 trabajando
' con un prescaler a 8Mhz de 1:16 lo que hace que desborde a 2 ms maximo. Esto nos
' proporciona el valor de recorrido maximo para cada Servo, utilizamos tambien
' el timer para generar los 0'3 ms necesarios de PWM a cada Servo.
'
' HARDWARE
'
' - PIC16F648 - 8 Mhz (HS)
'
' PORTA.0 --------------> Servo 1
' PORTA.1 --------------> Servo 2
' PORTA.2 --------------> Servo 3
' PORTA.3 --------------> Servo 4
' PORTB.4 --------------> Servo 5
' PORTB.5 --------------> Servo 6
' PORTB.6 --------------> Servo 7
' PORTB.7 --------------> Servo 8
'
'*******************************************************************************
program SERVOS8_V1
dim Servo as byte[8]
Salidas as byte
Index as byte
Paso as byte
n_servo as byte
MaskPort as byte
PosServos as byte
sub procedure interrupt
'TIMER 0
if INTCON.T0IF=1 then
if paso=0 then
MaskPort=salidas and n_servo ' Mascara para las salidas
PORTA.0=MaskPort.0 ' Servo 1
PORTA.1=MaskPort.1 ' Servo 2
PORTA.2=MaskPort.2 ' Servo 3
PORTA.3=MaskPort.3 ' Servo 4
PORTB.4=MaskPort.4 ' Servo 5
PORTB.5=MaskPort.5 ' Servo 6
PORTB.6=MaskPort.6 ' Servo 7
PORTB.7=MaskPort.7 ' Servo 8
TMR0=218 ' 0.3ms - 8Mhz - prescaler 1:16
Inc(paso)
else
if paso=1 then
TMR0=Servo[index] ' Anchura de pulso del servo
Inc(paso)
else
if paso=2 then
PORTA=0
PORTB=0
TMR0=Servo[index] ' Valor menos periodo de servo
paso=0
n_servo=n_servo<<1 ' Siguiente servo
inc(index)
if n_servo=0 then
n_servo=1
index=0
end if
end if
end if
end if
INTCON.T0IF =0 ' Reseteamos la bandera de la interrupcion
end if
end sub
main:
CMCON=0x07 ' Desactivacion de Comparadores
TRISA=0x00 ' Configuracion del puerto A
TRISB=0x04 ' Configuracion del puerto B
PORTA=0
PORTB=0
Index =0
Paso =0
N_servo =0
PosServos=127
Servo[0]=127 ' Posicion inicial de Servo 1 (centro)
Servo[1]=127 ' Posicion inicial de Servo 2 (centro)
Servo[2]=127 ' Posicion inicial de Servo 3 (centro)
Servo[3]=127 ' Posicion inicial de Servo 4 (centro)
Servo[4]=127 ' Posicion inicial de Servo 5 (centro)
Servo[5]=127 ' Posicion inicial de Servo 6 (centro)
Servo[6]=127 ' Posicion inicial de Servo 7 (centro)
Servo[7]=127 ' Posicion inicial de Servo 8 (centro)
OPTION_REG=0x83 ' Prescaler timer 0 a 1:16
INTCON=0 ' Reset del registro INTCON
INTCON.T0IF=0 ' TOIF=0 borra flag interrupcion del timer
INTCON.T0IE=1 ' TOIE=1 activa interrupciones del timer 0
TMR0=0
INTCON.GIE=1 ' Interrupciones globales a on
salidas=0xff ' Mascara de servos a On o a Off
While true
Inc(PosServos) ' Modificamos la posicion de los servos
Servo[0]=PosServos ' asignamos
Servo[1]=PosServos
Servo[2]=PosServos
Servo[3]=PosServos
Servo[4]=PosServos
Servo[5]=PosServos
Servo[6]=PosServos
Servo[7]=PosServos
Delay_ms(50) ' Retardo de 50ms (velocidad)
wend
End.





