gracias por las rspuestas.
maunix, si creo saber eso que mencionas, pero no entiendo en que puede ayudarme ello, o que debo hacer, ya que nbo he tenido problemas en la parte de mover
pocher: no he tenido problemas por ahora con el gets() ya que he logrado recibir los datos correctamente, bueno es algo largo el codigo, asi que tratare de resumir algunas partes y tratar de enfocar mi problema:
#include <16F877a.h>
#include <string.h>
#include <stdlib.h>
#fuses XT,NOWDT,PUT,NOPROTECT,NOLVP,NOCPD,NOBROWNOUT,NODEBUG
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, parity=N, bits=8)
#byte port_a=0x05
#byte port_b=0x06
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#define up_dc PIN_C0
#define down_dc PIN_C1
int encoder_count=0,count,dc_on=0,go_up,rda;
int16 i,pasos_1,pasos_2,step_count=0,grad1,grad2;
char dato1[2],dato2[2];
#INT_TIMER0
void tmr_handler()
{
count++;
if(count==pasos_2)
{
dc_on=0; // apago bandera del motor dc encendido, cuando se llegue a la cantidad de pasos necesitados
}
set_timer0(255);
}
void delay()
{
delay_ms(25); // retardo entre paso
}
void derecha(int16 pasos_d) // funcion para mover el motor paso a paso, la cantidad de pasos calculado con el dato recibido por rs232
{
for(i=0;i<pasos_d;i++)
{
rotate_left(&port_b,1);
step_count--;
delay();
}
}
void izquierda(int16 pasos_i) //para mover paso a paso pero a la izquierda
{
for(i=0;i<pasos_i;i++)
{
rotate_right(&port_b,1);
step_count++;
delay();
}
}
int a_entero(char c[],int16 dato) // funcion para convertir la cadena recibida a un entero, el '9' '0' por ej. a 90
{
dato=(c[0]-'0')*10;
dato=(c[1]-'0')+dato;
return dato;
}
void main()
{
SETUP_ADC_PORTS(NO_ANALOGS);
SETUP_ADC(adc_off);
setup_timer_0(RTCC_EXT_H_TO_L | RTCC_DIV_1);
enable_interrupts(global);
enable_interrupts(int_timer0);
set_tris_a(255);
set_tris_b(0);
set_tris_c(0xbc);
port_b=0xcc;
output_c(0);
while(true)
{
SET_TIMER0(255);
rda=0;
printf("\r\nMotor A:");
printf("\r\n 15' - 30' - 45' - 60' - 75' - 90'\r\n");
printf("\r\nMotor B:");
printf("\r\n 18' - 36' - 54' - 72' - 90'\r\n");
printf("\r\nIngresar cantidad de grados Motor A y B:\r\n");
gets(dato1); // obtengo primer dato y lo guardo en dato1
puts(dato1); // muestro el dato obtenido
gets(dato2); // obtengo segundo dato y guardo en dato2
puts(dato2); // muestro dato obtenido
grad1=a_entero(dato1,grad1); // convierto char (dato1) a int
grad2=a_entero(dato2,grad2); // convierto char (dato2) a int
pasos_1=grad1*3; // obtengo cantidad de pasos necesarios para girar la cantidad de grados obtenidos por dato1
pasos_2=grad2/18; // obtengo cantidad de pasos necesarios para el otro motor
if((grad1%15!=0)||(grad2%18!=0)) // si los datos no son multiplo de 15 y 18 respectivamente
printf("\r\n error \r\n"); // muestro mensaje de error
else
{
printf("\r\n ok \r\n"); // si datos estan en el rango comienzo el movimiento de los motores
while(1) // me qeudo en un ciclo infinito, porque esto debe hacerlo todo el tiempo hasta que se le envie cualqueir dato y ocurra una interrupcion en rda, talvez este redundante por el do de abajo, pero estaba funcionando
{
do
{
enable_interrupts(INT_RDA);
dc_on=1; // bandera para anunciar que el motor dc estara encendido
count=0; // contador de pasos del motor dc, via un encoder
do //arriba para el motor dc
{
if(rda==1){disable_interrupts(int_rda); break;} // si ha ocurrido la interrupcion se tiene qeu salir de este bucle
go_up=1; // bandera de marcha arriba seteada
output_high(up_dc); // pines de salida para el motor dc
output_low(down_dc);
}while(dc_on==1); // mientras bandera de encendido ed motor dc este en 1
output_low(up_dc); // motor dc apagado
output_low(down_dc);
if(rda==1){disable_interrupts(int_rda); break;} // si ha ocurrido la interrupcion se tiene qeu salir de este bucle
delay_ms(2000); // retardo para que se quede sin movimiento por 2 seg
if(rda==1){disable_interrupts(int_rda); break;} // si ha ocurrido la interrupcion se tiene qeu salir de este bucle
izquierda(pasos_1); //izquierda // marcha a la izquierda del motor paso paso, la cantidad de pasos calculado
if(rda==1){disable_interrupts(int_rda); break;} // si ha ocurrido la interrupcion se tiene qeu salir de este bucle
delay_ms(2000); // retardo para que se quede sin movimiento por 2 seg
if(rda==1){disable_interrupts(int_rda); break;} // si ha ocurrido la interrupcion se tiene qeu salir de este bucle
derecha(pasos_1); //derecha //marcha a la izquierda del motor paso paso, la cantidad de pasos calculado
if(rda==1){disable_interrupts(int_rda); break;} // si ha ocurrido la interrupcion se tiene qeu salir de este bucle
delay_ms(2000); // retardo para que se quede sin movimiento por 2 seg
dc_on=1; // bandera del motor dc encendido
count=0; // contador de pasos del motor dc
do //abajo para el motor dc
{
if(rda==1){disable_interrupts(int_rda); break;} // si ha ocurrido la interrupcion se tiene qeu salir de este bucle
go_up=0; // bandera de marcha arriba limpiada
output_high(down_dc); // pines de salida del motor dc
output_low(up_dc);
}while(dc_on==1); // mientras la bandera de motor dc este activa
output_low(up_dc); // detengo motor dc
output_low(down_dc);
if(rda==1){disable_interrupts(int_rda); break;} // si ha ocurrido la interrupcion se tiene qeu salir de este bucle
delay_ms(2000); // retardo para que se quede sin movimiento por 2 seg
}while(KBHIT()==0); // mientras no reciba nada por rs232
//disable_interrupts(int_rda); // nose si esta linea tb vendria aca, porque antes del beak ya deshabilito
dato1[0]=0; // reestablezco todos los valores a 0
dato1[1]=0;
dato2[0]=0;
dato2[0]=0;
grad1=0;
grad2=0;
break; // salgo del ciclo para comenzar de nuevo con otros datos
}
}
}
}
#INT_RDA // interrupcion por rs232
void usart_handler()
{
output_low(up_dc); // apago dc
output_low(down_dc);
delay_ms(3000); // retardo de 3 seg, mas apra saber que si ha entrado en la interrupcion
if(step_count!=0) // esto para volver al paso paso a su lugar de origen
{
do
{
derecha(1);
}while(step_count!=0);
}
delay_ms(1000); // retardo
//pasos_2=pasos_2-count;
dc_on=1; // bandera del motor dc encendido
do
{
go_up=0;
output_high(down_dc);
output_low(up_dc);
if(get_timer0()==(count-1))
dc_on=0;
}while(dc_on==1); // bajo la cantidad de pasaos necesarios
output_low(down_dc); // apago motor dc
rda=1; // bandera de que ha ocurrido interrupcion
pasos_1=0; // reestablezco valores
pasos_2=0;
}
ahi esta el codigo completo no pude suprimir muchas lineas, espero se entienda.
lo que ha pasado ahora es que no ha salido de la rutina de interrupcion nunca, en simulacion tb se quedaba plantado en la int_rda, esto lo he visto con el .cof en proteus
un saludo y si no se entendio algo pues se los aclaro