TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: Algec en 07 de Junio de 2007, 09:50:41
-
Tengo un problema con un programita en C, y necesito ayuda experta
Tengo un encoder del tipo potenciometro de volumen digital, ya sabeis, dos trenes de pulsos desfasados.
Conectado a RB0 y RB1
Se debe generar una interrupcion cuando haya un cambio de estado en RB0 es decir pase de 1 a 0 o de 0 a 1
para ello uso la interrupcion EXT
El programa seria algo asi
#include <16F876.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,NODEBUG,BROWNOUT,NOCPD,NOWRT
#use delay(clock=1000000)
#INT_EXT
void giro (void){
disable_interrupts(global); // desabilito para que no salte de nuevo
// hace lo que debe aqui que no es mas que encender y apagar leds
enable_interrupts(INT_EXT);
enable_interrupts(global);// vuelvo a habilitarla
}
void main()
{
enable_interrupts(INT_EXT);
enable_interrupts(global);
while(TRUE)
{
// aqui hace otras funciones como es logico
}
}
El problema es que cuando paro el encoder y se queda la salida que esta conectada en RB0 a 1 se queda la interrupcion siempre ejecutandose sin parar
En cambio si esa salida del encoder queda a cero no se ejecuta mas que una vez, al cambio de estado
¿En que me equivoco?
-
uyyyyyyyyyyy ... y porque tiene que ser experta la ayuda?
Tengo un problema con un programita en C, y necesito ayuda experta
-
Porque aqui casi todos los sois, al menos mucho mas que yo.
Espero no haber molestado con el comentario, al contrario solo era un halago.
-
No parece lógico que al parar en nivel alto la interrupción se quede lanzada, porque la INT_EXT trabaja por detección de flancos. Tanto es así que puedes configurarla para que salte en el flanco de subida o en el de bajada con estas instrucciones:
ext_int_edge(L_TO_H);
ext_int_edge(H_TO_L);
Una cosa más, si el proceso que ejecutas en la interrupción no es muy duradero, no tienes que desactivarla y volverla a activar. Lo ideal es que la interrupción se ejecute muy rápidamente.
-
A mi me ocurrio lo mismo. Miar este hilo y su solución:
http://www.todopic.com.ar/foros/index.php?topic=4889.msg36393#msg36393
Un saludo.
-
Jesús, la interrupción que tú mencionas es la de puerto B, y la de Algec es la externa. ¿Será válida la solución?
-
Es cierto Manolo, esto me pasa por leer demaseado deprisa. De todas formas se puede comprobar haber si es el mismo problema o no.
Un saludo
-
Veamos trate de hacer lo que me decis pero el compilador CCS no entiende la linea de asm
Me da error porque no esta definido PORTB
No seria igual escribir en CSS
output_low(PIN_B0);
output_low(PIN_B1);
de esta forma pongo a cero los dos pines, pero si hago esto resulta que no funciona.
Un cuestion mas por el comentario de Nocturno (como siempre Nocturno al rescate en mis dudas, mil gracias)
Si la interrupcion es un proceso largo, pero lo que no quiero es que se vuelva a reiniciar por que llegue un segundo pulso del encoder y a si sucesivamente y que nunca termine de ejecutarse completamente, por eso pense desabilitarla y volverla a habilitar al salir de ella.
Por cierto en Proteus tal y como esta funciona bien, ha sido al llevarla a la practica que me falla. ¿Podria ser del Hardware?
-
He seguido investigando y parece ser un error de hard, puede que se queden las entradas sin tension definida cuando el encoder deje el switch correspondiente abierto y por eso el PIC haga cosas raras. Voy a probarlo y os comento, eso pasa por confiar en los manuales del Hard similar sin haber consultado el del encoder exacto que uso.
-
Efectivamente mi error era de hard, ahora trabaja correctamente.
Mil gracias de nuevo y perdonad las molestias.
Aun asi me gustaria aclarar ese punto que Nocturno apuntaba el el post sobre la necesidad de desactivar la interrupcion o no, si lo que se ejecuta es largo.
Segun tengo entendido (me decis si me equivoco), la interrupcion seguira activa aun si se se esta ejecutando la interrupcion misma, es decir, si hay de nuevo un cambio de flanco volvera a ejecutarse desde el principio, y cuando acabe una vez terminara la anterior y volvera al main(), por lo que es posible que si se generan muchas interrupciones, nunca acabe de ejecutar ninguna porque este en un bucle de inicio y reinicio de la funcion de interrupcion.
¿Es asi? o por el contrario ¿una vez dentro de la funcion de interrupcion no atendera al flaco si se produce hasta que no termine la que esta ejecutando?
-
Si estamos hablando de CCS, cuando entras en la interrupción se inhabilita y cuando sale de la interrupción la habilita de forma automática el compilador.
Un saludo
-
Es decir me puedo ahorrar el habilitarla y deshabilitarla.
Mil gracias de nuevo a todos