TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: pablo en 24 de Octubre de 2008, 09:48:13
-
Hola gente:
Me estoy enloqueciendo con un una practica que estaba intentando hacer con un servo.
Estoy armando un PWM con timer para hacer girar el servo para un lado 1 segundo y luego para el otro.
Si lo hago de esta forma funciona, pero todo lo tengo que hacer dentro del timer.
#include <18f4550.h>
#use delay(clock=4000000)
#fuses XT,NOLVP,NOWDT
#define DERECHA 5
#define IZQUIERDA 25
int16 cant=0;
int16 cant2=0;
int GIRO=DERECHA;
#int_RTCC
void reloj(void) {
if(cant==0) {
output_bit(PIN_B6,1);
}
if(cant==GIRO) {
output_bit(PIN_B6,0);
}
cant++;
if(cant==225) {
cant=0;
}
cant2++;
if(cant2==20000) {
cant2=0;
if(GIRO==5)
GIRO=25;
else
GIRO=5;
}
Set_timer0(247);
}
void main(void) {
setup_timer_0(RTCC_DIV_1 | RTCC_8_BIT);
enable_interrupts(int_RTCC);
enable_interrupts(global);
while(true) {
}
Ahora el tema es que si pongo un delay dentro del programa principal es como si se fuera de este y no volviera a entrar.
Estoy trabadicimo y no se cual es el problema.
Puedo poner delay dentro de un while principal cuando tengo configurado un timer no??
El timer esta configurado para que entre cada 0.1ms.
Codigo que no funciona.
#include <18f4550.h>
#use delay(clock=4000000)
#fuses XT,NOLVP,NOWDT
#define DERECHA 5
#define IZQUIERDA 25
int16 cant=0;
int16 cant2=0;
int GIRO=DERECHA;
#int_RTCC
void reloj(void) {
if(cant==0) {
output_bit(PIN_B6,1);
}
if(cant==GIRO) {
output_bit(PIN_B6,0);
}
cant++;
if(cant==225) {
cant=0;
}
Set_timer0(247);
}
void main(void) {
setup_timer_0(RTCC_DIV_1 | RTCC_8_BIT);
enable_interrupts(int_RTCC);
enable_interrupts(global);
while(true) {
delay_ms(1000);
if(GIRO==5)
GIRO=25;
else
GIRO=5;
}
}
Desde ya les agradesco mucho.
Saludos.
Pablo
-
Mientras se ejecuta el delay_ms(1000) la interrupción continua ocurriendo, si quieres que te funcione el código de esa forma, apaga la interrupción antes del delay y al salir vuelvela a encender.
Saludos
-
Lo que yo necesito es que mientras haga el delay diga corriendo la interrupccion porque de esta forma sigue girando hasta llegar a una posicion determinada.
Si mal no entiendo tengo que hacer esto?
Si es asi sigue sin funcionar.
GRacias.
#include <18f4550.h>
#use delay(clock=4000000)
#fuses XT,NOLVP,NOWDT
#define DERECHA 5
#define IZQUIERDA 25
int16 cant=0;
int16 cant2=0;
int GIRO=DERECHA;
#int_RTCC
void reloj(void) {
if(cant==0) {
output_bit(PIN_B6,1);
}
if(cant==GIRO) {
output_bit(PIN_B6,0);
}
cant++;
if(cant==225) {
cant=0;
}
Set_timer0(247);
}
void main(void) {
setup_timer_0(RTCC_DIV_1 | RTCC_8_BIT);
enable_interrupts(int_RTCC);
enable_interrupts(global);
while(true) {
disable_interrupts(int_RTCC);
delay_ms(1000);
enable_interrupts(int_RTCC);
if(GIRO==5)
GIRO=25;
else
GIRO=5;
}
}
-
Hola
una pregunta: ¿el timer es de uso exclusivo para el retardo de 1S?
porque no sacas toda la rutina de reloj(void) y creas una base de tiempos y después trabajas con banderas afuera en el bucle principal.
-
hasta donde tengo entendido, el delay_ms y el delay_us lo que hace son loops de ciclos nop.
lo que quiere decir, que mientras se lleva a cabo el delay, el pic esta muerto. si estoy mal
acepto correciones.
Te sugiero que ya que usas un pic poderoso como el 18f4550, uses una interrupcion para
mover el motor . y otra para un conteo de 1 segundo.
en lo posible recomiendo no colocar mucho codigo dentro de las interrupciones.
solo cambio de banderas o incrementos.
Puedes cambiar la susecion de if { } , por un switch, y asi ahorras unas instrucciones.
#int_RTCC
void reloj(void) {
switch(cant){
case 0:
output_bit(PIN_B6,1);
break;
case GIRO:
output_bit(PIN_B6,0);
cant++;
break;
case 225:
cant=0;
break;
}
Set_timer0(247);
}
saludos a todos. !
-
Lo que yo necesito es que mientras haga el delay diga corriendo la interrupccion porque de esta forma sigue girando hasta llegar a una posicion determinada.
Cada cuanto se ejecuta tu interrupción? puede que se ejecute todo varias veces y tu aún no te has enterado que ocurrió. Lo que sucede es que no uso ese compilador y por ende no puedo probar tu codigo así que te voy tirando ideas nomás.
hasta donde tengo entendido, el delay_ms y el delay_us lo que hace son loops de ciclos nop.
lo que quiere decir, que mientras se lleva a cabo el delay, el pic esta muerto. si estoy mal
acepto correciones.
En general las rutinas de delay de los compiladores C, hacen eso, un bucle de nops o de una variable descontándose N veces hasta lograr el tiempo pactado. El pic no se muere, para nada, está haciendo eso, contando ciclos. Incluso si fueran nops, no estaría "muerto", estaria contando nops y las interrupciones seguirían estando y actuando.
-
La interrupcion se ejecuta cada 0.1ms. El servo trabaja con giro a la derecha manteniendo 0.5ms en alto y 20ms en 0, para la izquierda 2.5ms en 1 y 20ms en 0.
Lo pruebo con el proteus y le pongo un breakpoint despues del delay de la funcion principal y no vuelve mas.
Es como si el delay fuera eterno.
Como la interrupcion sigue funcionando si o si cada 0.1ms el servo se posiciona en forma normal pero al no volver al programa principal no puedo cambiar el estado de posicion.
Con respecto a los consejos de como programar en la interrupcion (programar lo menos posible) lo voy a tener en cuenta.
Ahora averiguo que son nops asi me pongo a tono con lo que me comentan.
Abrazo y gracias.