////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// multi.c //
// Descripcion: programa fuente de optimizacion de codigo para mover 8 sevos von 1 solo timer //
// Autor: Juan Jose Perales Serrano //
// Web: www.microrobotica.net //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <18F2550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)
//////////////////////////////////////////////////////////////////////////////
#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)
{
}
}
Aquí tienes un ejemplo en CCS de usar 8 servos con el método de la ventanas de 20ms, no se necesita ningun float ni punto decimal ni fracción ni nada.
para posicionar los servos solo debes cargar el vector "Servo_PWM[8]" y habilitar el número de servos que necesitas. el programa se encarga del resto.
un saludo