Ey que tal? Bueno aqui el codigo el cual ha sido probado fisicamente con osciloscopio y funciona "a medias". Digo a medias xq el pic me hace todo correctamente. Al final configure tmr1 para que salte a interrupcion cada 20ms (por eso de los pulsos del servo) y en la rutina de interrupcion le digo ya el tiempo que debe estar a on el pulso (duty). Funciona to muy bien la única pega es que para los pulsos del servo necesito meter en el delay un numero en microsegundos y no me lo coge, en el osciloscopio sale nada un pulso de apenas microseg cuando si realmente le estoy diciendo que me meta un delay de 1200 us no me lo hace.
Lo gracioso es que en el delay cuando en vez de poner us lo pongo en ms y pongo varios anchos de pulso (1 2 3....)ms me lo hace perfecto.
He probado mil cosas, meterle un float y meterselo en milisegundos y nada el rollo parece darselo en milis pero no veo la forma de que funcione y no se muy bien xq no funciona la verdad.
Te agradeceria si le podias echar un vistazo y si hay alguna restriccion en la funcion delay u otra forma de poder darle ese retardo (1200us, 600us etc). Si lo pongo en ms como float no me funciona, y debo ponerlo como float xq quiero pulsos de 1.2 0.6 etc. Si lo pongo en microsegundos como 1200... no me funciona.
¿Alguien sabe porque?????
#include <16F876.H>
#fuses XT, NOPROTECT, NOPUT, NOWDT, NOBROWNOUT, NOLVP, NOCPD, WRT
#use Delay(Clock=4000000)
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#byte port_a = 5 // Identificador asociado al registro de dirección 5
#byte port_b = 6 // Identificador asociado al registro de dirección 6
#byte port_c = 7 // Identificador asociado al registro de dirección 7
//int y,x, retardo;//
void main() {
int pe, dutycalculado, xx;
set_tris_a(0x00); // Puerto A como salida
set_tris_b(0xFF); // Puerto B entrada
set_tris_c(0x00);
output_a(0x00); // Todos los pines de PORTA en 0
output_b(0x00); // Idem con PORTB
output_c(0x00);
setup_timer_2(T2_DIV_BY_16,249,1) ; // Div=16 ; PR2=249 ; Postscale=1
setup_CCP1 (CCP_PWM); //Configuracion PWM
enable_interrupts(GLOBAL); // Activamos interrupciones globales
enable_interrupts(INT_TIMER1); // ... y la interrupcion por TMR1
setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_1); //Configuracion TMR1 y preescaler
set_timer1(45536); // Cada 20 ms salto a interrupcion 65536-(temporizacion*Fosc/4*preescaler)
while(1) {
set_pwm1_duty(0);
delay_ms(3000);
pe=0b11110000 & port_b;
while ((pe)==((0b11110000)&(port_b))) //mientras no cambio en posicion del servo...
{
xx= 0b00001111 & port_b; //velocidad (1=10%, 2=20%......10=100%)
if(xx>10) //
{
xx=0;
set_pwm1_duty(0); //Si es mayor a 10 duty=0
}
else
{
dutycalculado= 25 * xx ; // Valor a cargar en duty
set_pwm1_duty(dutycalculado);
}
switch(input(pin_c6))
{
case 0: //motor alante
output_high(pin_c7);
break;
case 1: // motor atras
output_low(pin_c7);
break;
}
}
}
}
#INT_TIMER1
void interrupcion()
{
long retardo;
int y, x;
set_timer1(45536);
x=port_b;
y=0b11110000 & x;
switch(y){
case 0: // 0000 servo recto
// retardo=1200; //recto
retardo=1;
break;
case 16:
//retardo=1466;
retardo=2; //giro derecha abierto 0001
break;
case 48:
//retardo=1800;
retardo=3; //giro derecha cerado 0011
break;
case 64:
//retardo=933;
retardo=4; // giro izquierda abierto 0100
break;
case 192:
//retardo=600;
retardo=5; // giro izquierda cerrado 1100
break;
}
output_high(pin_c0);
delay_ms(retardo);
output_low(pin_c0);
}
Muchas gracias y espero que me hayas entendido.
Gracias maestro!!
Un saludo.