TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: Delphus en 15 de Septiembre de 2011, 20:38:00
-
Hola a todos, estoy comenzando con lo de los pics y tengo una consulta si me pueden ayudar:
Debo implementar un contador de tiempo, el cual se debe poder pausar con un pulsador, si se presiona nuevamente el boton, el contador cuenta hacia atrás, luego se pausa de nuevo y luego cuenta hacia adelante, lo anterior lo debo hacer usando interrupciones, he definido el puerto A como entrada para el pulsador y B com las salidas, mi idea para la interrupcion es así:
#int_RA
pausar_pic()
{
sleep();
}
1. Aquí no se si usar int_ext o int_RA, pues se supone que int_ext es para cambios en el puerto B
2. El otro problema es que al presionar nuevamente el pulsador se debe salir de la interrupcion e ir a una funcion que seleccione entre aumentar o decrementar el contador algo como
void seleccion()
{
if a=1
incrementar;
if a=2
decrementar
}
esto es lo que no sé como hacer, pues lo normal es que la interrupcion termine luego que acabe su tarea segun lo que he leido.
Esa es mi duda, de antemano gracias por las respuestas.
-
ese sleep es para dormir el pic, lo mejor que harias seria a=0 y asi ni incrementa ni decrementa.
osea, cuando entres en int_
switch(a) {
case 1:
a=2;
break;
case 2:
a=0;
break;
case 0:
a=1;
break;
}
o bien:
a++;
if(a>2) a=0;
ahora en el codigo main()
en el bucle principal
switch(a) {
case 1:
incrementa();
break;
case 2:
decrementa();
break;
}
de la interrupcion se sale solo y vuelve a donde estaba, osea al bucle principal.
-
Hola Merlinz gracias por tu respuesta, el problema es que debo usar una interrupcion es una tarea de mi carrera, por eso uso sleep, para pausarlo, el pic que uso es un 16f88.
Saludos
-
Para ser más claro lo que necesito es que cuando el pic reciba señal por el pin 0 de A, se despierte y me mande al selector incrementar/decrementar
-
si, como yo te he dicho usas una interrupcion
-
ah, creo que ya te entiendo el switch se pone dentro de la interrupcion y luego me voy al selector, listo , muy ingenioso, lo probaré, pero quería saber también si es correcto como estoy asignando la interrupcion con #int_RA o es si debo usar int_ext puesto que la entrada de datos será por el puerto A?
Gracias por tu respuesta Merlinz
-
he mirado el datasheet de tu pic y para INT solo tiene el RB0.
Aparte tiene para todo el PORTB en cambios de estado.
Yo usaria INT0, y le pones el flanco que desees, osea que se active cuando cambie de 0 a 1, o bien de 1 a 0, para esto usas el OPTION_REG.INTEDG
Para que funcione tendras que configurar la interrupcion en enable y tal.
-
hola, no habia pasado por acá hace rato jeje ya entendí esto de las interrupciones, Al final el programa quedó así, para los que les interese:
El programa enciende tres leds un led por vez en una direccion y al recibir un cambio de 0 a 1 con un pulsador, invierte el sentido de recorrido.
#include <16F88.h>
#FUSES INTRC, NOWDT, NOLVP, NOCPD, NOWRT, NODEBUG, NOPROTECT, NOFCMEN, NOIESO, MCLR, NOBROWNOUT, CCPB3 //para usar reloj externo
#use delay(clock=4000000)
#use fast_io(B)
#use fast_io(a)
static int i,inc,c,d;
#int_ext //esta es la interrupcion por el puerto RBO
invertir() //la interrupcion ejecuta la funcion invertir()
{
d=d+1;
if (d==1)
{
inc=-1;
c=2;
}
if (d==2)
{
inc=1;
c=0;
d=0;
}
}
byte const arreglo[3]={0b0010,0b0100,0b1000 };
void main()
{
set_tris_a(0x00); // a como salida
set_tris_b(0b0001); // b como salida y entrada en el pin 0
enable_interrupts(int_ext); // Habilito interrupción
ext_int_edge(l_to_h);
enable_interrupts(global);
inc=1; i=0;d=0;
while (TRUE) //Aqui comienza el alumbrado
{
i=c;
while (i<3)
{
output_b(arreglo);
i=i+inc;
delay_ms(1000);
}
}
}