Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:
Hola a todos;
Me gustaría pediros q si veis el fallo tan obvio de esta programación me aviseis pq yo no soy capaz de ver q falla y no me funciona ni para atrás:
Lo q intento es tener interrupciones cargando el timer0 del 16f876a a 245 con lo q me quedan 10 desbordamientos del contador y puesto q lo tengo con predivisor 1:2 y un xtal de 4Mhz se supone q tengo un desbordamientos cada 0,002 ms con lo q tras pasar por el timer tengo una interrupción del rtcc cada 0,02 ms.
Bien entonces lo q hago es contrar 875 RTCC manteniendo la salida a nivel bajo, cuando llego a estos 875 (17,5 ms) pongo la salida en high y cuando llego a 900 (con lo q han transcurrido 0,5ms ) empiezo a contar RTCC con el fin de bajar la salida dependiendo de la posición deseada del servo… entre esos 0,5 ms y 2,5 ms (900 RTCC y 1000RTCC) con lo q tendría completo el ciclo o periodo de 20ms.
¿alguien ve pq no funciona esto?
Gracias de antemano.
Código:
___________________________________________________________________________________________________________________________-
// Ctrl_2servos_pwm_232
// Ejemplo con dos servos FUTABA S3003
// Alimentación y pulsos a 5V
// Cuadro de Tiempos :
// Periodo 20 ms (Frecuencia 50 Hz)
// Ancho Pulso minimo 0.5 ms
// Ancho pulso medio 1.5 ms
// Ancho pulso maximo 2.5 ms
// TMR0 a 1:2 -> 1 RTCC cada (cargando el tmr0 a 245)0,02 ms
// -> 1 Tick cada = 0.002 ms
// -> 20 ms = (1000 x RTCC completas)
// -> 0,5 ms = 25 x RTCC
#include <16f876a.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
#use delay(clock=4000000)
#use standard_io(b)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#define PIN_SERVO1 PIN_B0
#define PIN_SERVO2 PIN_B1
//#define PIN_SERVON PIN_BN
const int AJUSTE_FINO_DE_RTCC = 245;
const int ticks_PULSO_0 = 0; //0 grados
const int ticks_PULSO_1 = 25; //
const int ticks_PULSO_2 = 50; //
const int ticks_PULSO_3 = 75; //
const int ticks_PULSO_4 = 100; //180 grados 2,5 ms
//const int ticks_PULSO_5 = 125; //
//int1 flagRTCC = 0;
int1 flagCICLOBAJO =0;
int1 flagPULSOpwm=0;
int contRTCC = 0;
int contRTCC_alto = 0;
int gCOUNT = 0;
int gSERVO1 = ticks_PULSO_1;
int gSERVO2 = ticks_PULSO_1;
int tSERV1_pls = ticks_PULSO_4;
int tSERV2_pls = ticks_PULSO_4;
int tSERV1_mns = ticks_PULSO_1;
int tSERV2_mns = ticks_PULSO_1;
//int tSERVON = ticks_PULSO_X;
char Keypress=0x00;
void eco_servos(void);
#int_rda
void rda_isr() {
Keypress=0x00;
if(kbhit()){
Keypress=getc();
}
}
#int_RTCC
RTCC_isr(){
++contRTCC;
set_TIMER0(AJUSTE_FINO_DE_RTCC);
//el periodo bajo del pwm dura 17,5ms es decir 875 rtcc's cargando el tmr0 a 245
if(contRTCC==875){
// DISPARO DEL PULSO PWM
output_high(PIN_SERVO1);
output_high(PIN_SERVO2);
}
//durante el periodo alto del pulso comprobamos la duración deseada para el servo y ajustamos el tmr0 a 250
if (flagPULSOpwm==1){
if(gCOUNT>=gSERVO1){
output_low(PIN_SERVO1);
flagPULSOpwm=0;
}
if(gCOUNT>=gSERVO2){
output_low(PIN_SERVO2);
flagPULSOpwm=0;
}
++gCOUNT;
}
if (contRTCC==900){
flagPULSOpwm=1;
gCOUNT=0;
}
if (contRTCC==1000){
contRTCC=0;
}
}
void main() {
//int ValTIMER0;
setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
enable_interrupts(int_rda);
enable_interrupts(global);
printf("rnSERVO CAMERA Commanderrnrn");
eco_servos();
set_TIMER0(AJUSTE_FINO_DE_RTCC);
enable_interrupts(INT_RTCC);
flagCICLOBAJO=0;
flagPULSOpwm=0;
flagCICLOBAJO=1;
gSERVO1=0;
gSERVO2=0;
do {
/*if(flagSERVON==1){
valTIMER0 = get_TIMER0();
if(valTIMER0>tSERVON){
flagSERVON=0;
output_low(PIN_SERVON);
}
}*/
// CONTROL DESDE LA RS-232
if(Keypress!=0x00){
switch(Keypress){
// Periodos Prefijados
case '0': gSERVO1=ticks_PULSO_0;
break;
case '1': gSERVO1=ticks_PULSO_1;
break;
case '2': gSERVO1=ticks_PULSO_2;
break;
case '3': gSERVO1=ticks_PULSO_3;
break;
case '4': gSERVO1=ticks_PULSO_4;
break;
// case '5': gSERVO1=ticks_PULSO_5;
// break;
//case '6': gSERVO1=ticks_PULSO_6;
// break;
//case '7': gSERVO1=ticks_PULSO_7;
// break;
// case '8': gSERVO1=ticks_PULSO_8;
// break;
case '+': tSERV1_pls=gSERVO1+1;
if(tSERV1_pls>ticks_PULSO_4){
gSERVO1=ticks_PULSO_4;
}
else{
++gSERVO1;
}
break;
case '-': tSERV1_mns=gSERVO1-1;
if(tSERV1_mns<ticks_PULSO_0){
gSERVO1=ticks_PULSO_0;
}
else{
--gSERVO1;
}
break;
case '*': tSERV2_pls=gSERVO2+1;
if(tSERV2_pls>ticks_PULSO_4){
gSERVO2=ticks_PULSO_4;
}
else{
++gSERVO2;
}
break;
case '/': tSERV2_mns=gSERVO2-1;
if(tSERV2_mns<ticks_PULSO_0){
gSERVO2=ticks_PULSO_0
;
}
else{
--gSERVO2;
}
break;
case 'P': eco_servos();
break;
}
//eco_servos();
Keypress=0x00;
}
} while (TRUE);
}
void eco_servos(void){
printf("S1=%u - S2=%u rn",gSERVO1,gSERVO2);
}
___________________________________________________________________________________________________________________________
________________________000__ºOº___000________________________
Tell me and I will forget
Show me and I will remember,
Involve me and I will understand
Aristotle
Yo te aconsejaria una escala de tiempo mayor, ya que estas provocando el desbordamiento del timer cada 20 instrucciones y ademas trabajas con datos de 16 bit, lo que obliga a una aritmetica ampliada, y ten en cuenta que la comparacion es una resta de 16 bit, juntando eso, puede que el pic vaya bastante justo si va de tiempo.
Otro consejo es que vayas por partes, haz que se mueva para un lado para ver que el control del servo va bien y despues metele la rutina de comunicacion serie
Ya, he visto como lo hace en asm Alejandro Alonso en un doc de controladora de 8 servos + 5 entradas analogicas y usa un preescaler de 256, es decir q lo único q cuenta son los 20 ms luego, cada 20 ms lo q hace es una rutina de "delays" para cada servo ajustando estos delays a la pos deseada.
Creo q retomaré ese camino... veo q no soy muy bueno en el tema, trataré d aprender :S
Yo tengo como futuro objetivo, hacer una controladora de servos en C, lo que pasa que es a largo plazo, y utilizare el modo compare ya que creo que puede serme muy util, a partir del timer1 puedes genera una interrupcion cada x tiempo por ejemplo 100 micros y seria como un "timer con autorecarga" que ademas te genera una interrupcion.
Creo que el modo compare funciona asi, a lo mejor me lo estoy inventando, tengo que mirarlo