Autor Tema: Interrupciones 12F no funciona (MikroC) [Resuelto]  (Leído 2110 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado beto_tech

  • PIC10
  • *
  • Mensajes: 13
Interrupciones 12F no funciona (MikroC) [Resuelto]
« en: 28 de Septiembre de 2016, 12:45:38 »
Hola amigos de TodoPic.. En esta ocasión solicito ayuda de la comunidad. Resulta que necesito realizar una interrupción en el microcontrolador 12F629 cuando los puertos GP4 y GP5 cambien de estado.
Entiendo que esto se puede realizar sin ninguna interrupción, pero me gustaría aprenderlo de igual forma.
Estoy trabajando esto en el compilador MikroC; adjunto se encuentra la imagen del circuito.
Agradezco de todo corazón tu aporte. Es para la escuela  :)


* Diagram.PNG
(16.84 kB, 646x472 - visto 720 veces)



Código: [Seleccionar]
char control=0;

void interrupt(void){
if(GPIO.F5==0 && GPIO.F4==1){control=1;}
if(GPIO.F5==1 && GPIO.F4==0){control=2;}
if(GPIO.F5==1 && GPIO.F4==1){control=3;}
 INTCON.F0=1;
}

void main() {
GPIO=0x00;
CMCON=0x07;
TRISIO=0x18;
OPTION_REG=0b10000000;
INTCON = 0b10000001;

while(1){
if(control==1){GPIO.F0=1;}
if(control==2){GPIO.F1=1;}
if(control==3){GPIO.F2=1;}
}
}
« Última modificación: 30 de Septiembre de 2016, 19:18:04 por beto_tech »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Interrupciones 12F no funciona (MikroC)
« Respuesta #1 en: 28 de Septiembre de 2016, 14:41:19 »
Proba esto, te faltaron unos registros y algunos bits:

Código: C
  1. volatile char control=0;
  2.  
  3. void interrupt(void)
  4. {
  5.         if(GPIO.F5==0 && GPIO.F4==1){control=1;}
  6.         if(GPIO.F5==1 && GPIO.F4==0){control=2;}
  7.         if(GPIO.F5==1 && GPIO.F4==1){control=3;}
  8.         INTCON.GPIF = 0;
  9. }
  10.  
  11. void main(void)
  12. {
  13.  
  14.         GPIO=0x00;
  15.         CMCON=0x07;
  16.         TRISIO=0x38;            //Error aca 0b 0011 1000 = 0x38 , pin 4 y 5 son del nibble alto
  17.         IOC=0x30;               //Permito que solo GPIO4 y 5 puedan usar la interrupcion
  18.         OPTION_REG=0b10000000;
  19.         INTCON.GPIE = 1;        // Habilito la interrupcion del puerto
  20.         INTCON.GIE = 1;         // Habilito interrupciones globales
  21.  
  22.         while(1)
  23.         {
  24.                 if(control==1){GPIO.F0=1;}
  25.                 if(control==2){GPIO.F1=1;}
  26.                 if(control==3){GPIO.F2=1;}
  27.         }
  28. }

PD: No se MikroC ya que no lo uso, pero imagino que si hay una instruccion mal, te vas a dar cuenta como pasarlo a MikroC.

Desconectado beto_tech

  • PIC10
  • *
  • Mensajes: 13
Re:Interrupciones 12F no funciona (MikroC)
« Respuesta #2 en: 28 de Septiembre de 2016, 21:27:59 »
Hola amigo KILLERJC he probado el nuevo código que haz mejorado y ha funcionado tal cual como quería..
Muchisimas gracias!  :)
+10

Desconectado beto_tech

  • PIC10
  • *
  • Mensajes: 13
Re:Interrupciones 12F no funciona (MikroC) [Resuelto]
« Respuesta #3 en: 29 de Septiembre de 2016, 11:57:41 »
H0ola KILLERJC, revisando el código meha surgido otra pregunta. Resulta que necesito llamar la interrupción por software cada 0.5 seg. Por lo que he leído esto se logr con un timer (TMR0), pero no sé cómo implementarlo. Me ayudarías.
Muchas gracias!  :)

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Interrupciones 12F no funciona (MikroC)
« Respuesta #4 en: 29 de Septiembre de 2016, 18:53:44 »
Si, no hay problema.

Explicarte exactamente como funciona el timer quedaria para otro momento. La idea es realizar un cargar el timer para que cuando pase de 0xFF a 0x00 genere una interrupcion.
El timer en si es un contador y va a contar los pulsos de reloj (internos o externos que le llegan)

Este es el concepto mas simple de timer.

¿Ahora como creo el codigo?

La primera es leer el datasheet, i ver que registros tenes para modificar:

Los registros que influyen en el Timer0 son:
TMR0 ( contiene el valor de la cuenta)
INTCON ( los bits de habilitacion de la interrupcion del Timer0 y luego las globales)
OPTION_REG ( Aca se determina el prescaler y de donde tomo los pulsos)
TRISIO ( en caso de tomar un pulso externo y no de la señal del oscilador )

Para calcular el valor del preescaler y de valor inicial del TMR0 podes ayudarte con una pagina:
http://eng-serve.com/pic/pic_timer.html

Ejemplo, con el oscilador interno de 4Mhz y usando el TMR0 (podria usar el TMR1 que posee otros registros y es de 16bits)
Tengo que si yo cargo el valor: 60 en TMR0, y tengo un Preescaler de 1:256, el Timer va a desbordar cada 0.05017600 sec

Si quisiera 0.5s deberia desbordarse 10 veces. Siempre comenzando desde 60 el Timer ( ya que cuando desborda comienza de 0 ).

Código: C
  1. char contador=0;
  2.  
  3. void interrupt(void)
  4. {
  5.         if(INTCON.T0IF)
  6.         {
  7.                 // Recargo timer y borro flag, entra aca cada 0.05s
  8.                 TMR0 = 60;
  9.                 INTCON.T0IF = 0;
  10.                 contador++;
  11.                 if(contador==10)
  12.                 {
  13.                         //Entra aca cuando pasaron 0.5s
  14.                         contador=0;
  15.                         GPIO ^= 0x1;    // Alterno el GPIO0
  16.                 }
  17.         }
  18.         // En caso de tener otra interrupcion, es solo un ejemplo
  19.         if(INTCON.GPIF)
  20.         {
  21.         }
  22. }
  23.  
  24. void main(void)
  25. {
  26.  
  27.         GPIO=0x00;
  28.         CMCON=0x07;
  29.         TRISIO = 0xFE;          // GPIO0 como salida para test
  30.  
  31.         OPTION_REG = 0b11010111;// Preescaler 1:256, Preescaler asignado a TMR0, Usa el oscilador interno
  32.         TMR0 = 60;
  33.         INTCON.T0IF = 0;        // Limpio flag por las dudas
  34.         INTCON.T0IE = 1;        // Habilito interrupcion
  35.  
  36.         INTCON.GPIE = 1;        // Habilito la interrupcion del puerto
  37.         INTCON.GIE = 1;         // Habilito interrupciones globales
  38.  
  39.         while(1)
  40.         {
  41.         }
  42. }

Una cosa, el TMR0 no se puede parar, SIEMPRE esta funcionando. Eso puede llegar a traer unos problemas.
El TMR1 en cambio puede pararse. Los pasos son iguales, nomas que tienen otros registros

Desconectado beto_tech

  • PIC10
  • *
  • Mensajes: 13
Re:Interrupciones 12F no funciona (MikroC)
« Respuesta #5 en: 30 de Septiembre de 2016, 19:17:37 »
Ohhhh muchas ya entendí como implementar la interrupción.. Llevaba 2 días enteros probando y buscando.. Muchas gracias Mr KILLERJC.  :)
 ((:-))

+10, eres el Dios de las interrupciones.


 

anything