de esta manera (esto es para servos pero la idea es la misma), dependiendo de la frecuencia que le quieras dar a tu pwm (en el caso del ejemplo 20 mseg) y lo divides por el numero de ventanas que quieras usar (en el ejemplo 8 de 2,5 ms), nada mas empezar el timer pones un pin a 1 y lo mantienes el tiempo que quieras en alto, digamos 1 mseg por ejemplo, y luego lo apagas, calculas lo que resta de ventana, 2,5-1 = 1,5 mseg, despues de ese tiempo pones en alto el segundo pin el tiempo que desees y lo bajas de nuevo, y asi las 8 ventanas, cuando se completan los 20mseg comienzas de nuevo con el primero y asi todo el rato.
tu debes calcular tus frecuencias y tus ventanas y cambiar los calculos para tu aplicación, y mucho cuidado de no usar delay en ningun lado.
////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// multi.c //
// Descripcion: programa fuente de optimizacion de codigo para mover 8 sevos von 1 solo timer //
// Autor: Juan Jose Perales Serrano //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <18F2550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)
/////////////////////////////////////////////////////////////////////////////
//
// Definicion de espacio para la carga del bootloader
//
/////////////////////////////////////////////////////////////////////////////
#build (reset=0x1000,interrupt=0x1008)
#org 0x0000,0x0FFF{}
//////////////////////////////////////////////////////////////////////////////
#priority timer1//,demas interrupciones, para dar prioridad a los servos
#use standard_io(A) //habilitamos los puertos como entrada salida
#use standard_io(B)
#use standard_io(C)
#define LED PIN_C1
#define SW1 PIN_C2
///////////////////////////DEFINICION DE TODOS LOS SERVOS///////////////////////
#define SERVO1 PIN_B7
#define SERVO2 PIN_B6
#define SERVO3 PIN_B5
#define SERVO4 PIN_B4
#define SERVO5 PIN_B3
#define SERVO6 PIN_B2
#define SERVO7 PIN_B1
#define SERVO8 PIN_B0
////////////////////////////////////////////////////////////////////////////////
const int16 TicksVENTANA=7500; // PWM para un servo = 2.5 ms x 8 = 20 ms
const int16 TicksMINIMA=2100; // PWM Position 0 = 0.7 ms
const int16 TicksCENTRO= 4500; // PWM Position 90= 1.5 ms
const int16 TicksMAXIMA=6300; // PWM Position 180= 2.1 ms
static int16 Servo_PWM[8]={TicksMINIMA,TicksMINIMA,TicksMINIMA,0,0,0,0,0}; //en este vector cargamos las posiciones de cada uno de los servos
static int8 SERVO_N=0; //variable para seleccionar el servo
static int1 SERVO1_ON=1; //variables para activar los servos
static int1 SERVO2_ON=1;
static int1 SERVO3_ON=1;
static int1 SERVO4_ON=0;
static int1 SERVO5_ON=0;
static int1 SERVO6_ON=0;
static int1 SERVO7_ON=0;
static int1 SERVO8_ON=0;
static int1 flag_Phase;
static int16 TicksPROXIMAINTERRUPCION=53036; //cuenta para la proxima interrupcion, VALOR ALEATORIO PARA LA PRIMERA INTERRUPCION
int8 bandera=0;
#int_timer1
void timer1_isr(void){
if(flag_Phase==0){
if(SERVO_N==0 && SERVO1_ON) {output_high(SERVO1);} //activacion de los servos en interrupciones impares
if(SERVO_N==1 && SERVO2_ON) {output_high(SERVO2);}
if(SERVO_N==2 && SERVO3_ON) {output_high(SERVO3);}
if(SERVO_N==3 && SERVO4_ON) {output_high(SERVO4);}
if(SERVO_N==4 && SERVO5_ON) {output_high(SERVO5);}
if(SERVO_N==5 && SERVO6_ON) {output_high(SERVO6);}
if(SERVO_N==6 && SERVO7_ON) {output_high(SERVO7);}
if(SERVO_N==7 && SERVO8_ON) {output_high(SERVO8);}
TicksPROXIMAINTERRUPCION = 65535 - Servo_PWM[SERVO_N]; //cargamos el timer con el valor en alto del servo
set_timer1(TicksPROXIMAINTERRUPCION);
}
if(flag_Phase==1){
if(SERVO_N==0 && SERVO1_ON) {output_low(SERVO1);} //desactivacion de los servos en posiciones pares
if(SERVO_N==1 && SERVO2_ON) {output_low(SERVO2);}
if(SERVO_N==2 && SERVO3_ON) {output_low(SERVO3);}
if(SERVO_N==3 && SERVO4_ON) {output_low(SERVO4);}
if(SERVO_N==4 && SERVO5_ON) {output_low(SERVO5);}
if(SERVO_N==5 && SERVO6_ON) {output_low(SERVO6);}
if(SERVO_N==6 && SERVO7_ON) {output_low(SERVO7);}
if(SERVO_N==7 && SERVO8_ON) {output_low(SERVO8);}
TicksPROXIMAINTERRUPCION = 65535 - TicksVENTANA - Servo_PWM[SERVO_N]; //cargamos el timer con el valor asta completar una ventana
set_timer1(TicksPROXIMAINTERRUPCION);
if(++SERVO_N>7) SERVO_N=0;
}
++flag_Phase;
}
void main(void)
{
int8 i=0,u=0;
disable_interrupts(GLOBAL); //CONFIGURACIÓN INICIAL
setup_timer_1(T1_INTERNAL | T1_DIV_BY_4);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
delay_ms(50);
output_low(SERVO1);
output_low(SERVO2);
output_low(SERVO3);
output_low(SERVO4);
output_low(SERVO5);
output_low(SERVO6);
output_low(SERVO7);
output_low(SERVO8);
set_timer1(TicksPROXIMAINTERRUPCION);
while(TRUE)
{
//tu codigo
}
}
te dejo el programa para que te hagas una idea y a ver si lo puedes utilizar, cuidado con el por que es de hace mucho y yo era un novatillo jeje.
al principio le dices cuantos servos vas a tener y cargando el vector "static int16 Servo_PWM[8]={TicksMINIMA,TicksMINIMA,TicksMINIMA,0,0,0,0,0}; " los tiempos de los servos para su posición y el programa lo hace todo.
para variar la posicion vas variando los valores de ese vector y ya esta.
ojala te sirva para tu aplicacion
un saludo