TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: Palomino86 en 12 de Febrero de 2011, 11:49:43

Título: Manejo de 2 interrupciones MikroC
Publicado por: Palomino86 en 12 de Febrero de 2011, 11:49:43
Que tal foro; aqui ando molestando nuevamente con una duda.

Lo que pasa es que estoy realizando un programa el cual maneja 2 interrupciones, una por cambio de estado en el Pin RB0 y otra por overflow del TMR2 en MikroC

El codigo es el siguiente:
Código: [Seleccionar]
//Librerias
#include "lcd_serial.h"

//Variables Globales
volatile long Contador,Overflow;
char Numeros[10];
unsigned char n;

void Write_Char(char *s);

//Interrupción
void interrupt(void)
{
  if(INTCON.INTF==1)                                                               //Verifica si se activo la bandera de interrupción del Puerto B0
  {
    Contador++;
    INTCON.INTF=0;
  }
 
  if(PIR1.TMR2IF==1)                                                             //Verifica si se activo la bandera de interrupcion de TMR2
  {
    Overflow++;
    PIR1.TMR2IF=0;
  }
}

//Programa Principal
void main()
{

//Configuración de Pines
  ADCON1=7;                                                                     //Todos los pines como digitales
  PORTB=0;                                                                      //Limpia el puerto B
  PORTC=0;                                                                      //Limpia el puerto C
  PORTD=0;                                                                      //Limpia el puerto D
  TRISB=0b00100001;                                                             //Configuración del Puerto B
  TRISC=0b00000000;                                                             //Configuración del Puerto C
  TRISD=0b10000000;                                                             //Configuración del Puerto D

  //PIR1=0;                                                                       //Limpia las banderas de interrupción del registro PIR1
  INTCON=0b00000000;                                                            //Interrupciones Deshabilitadas al inicializar

//Configuración del Timer 2
  T2CON=0b00100000;                                                             //Configuracion del Registro T2CON Prescaler = 1, Postcaler = 5, TMR2 = Off
  TMR2=0;                                                                       //Inicializamos el valor del TIMER 2 en cero.
  PR2=124;                                                                      //Valor de PR2 para que cada 128 us se realice una interrupción.

  Soft_UART_Init(&PORTB,5,4,9600,0);                                            //Configuración de comunicación serial por UART (Modo Invertido)
  Delay_ms(200);

  Contador=0;
  while(1)
  {
   Contador=0; Overflow=0; strcpy(Numeros,' ');

   INTCON=0b11010000;                                                           //Interrupciones Deshabilitadas al inicializar
   T2CON=0b00100100;                                                            //Configuracion del Registro T2CON Prescaler = 1, Postcaler = 5, TMR2 = On

   while(Overflow<8000);
   
   INTCON=0b00000000;                                                           //Interrupciones Deshabilitadas al inicializar
   T2CON=0b00100000;                                                            //Configuracion del Registro T2CON Prescaler = 1, Postcaler = 5, TMR2 = Off
   
   LongToStr(Contador,Numeros);
   HomeLCD();
   WriteLCD("Contador:",9);
   Write_Char(Numeros);
   
   Delay_ms(500);
  }
}

void Write_Char(char *s)
{
  while(*s)
  {
      if(*s!=' ')
      {
        Soft_UART_Write(*s) ;
      }
      s++ ;
  }
}


Al realizar el debug en Proteus, al momento de haber una interrupcion por el puerto RB0 me incrementa simultaneamente las variables Contador y Overflow.... lo cual desde mi punto de ver no es correcto...

pero si yo realizo el siguiente cambio en la interrupcion...
Código: [Seleccionar]
//Interrupción
void interrupt(void)
{
  if(INTCON.INTF==1)                                                               //Verifica si se activo la bandera de interrupción del Puerto B0
  {
    Contador++;
    INTCON.INTF=0;
  }
 
  else if(PIR1.TMR2IF==1)                                                             //Verifica si se activo la bandera de interrupcion de TMR2
  {
    Overflow++;
    PIR1.TMR2IF=0;
  }
}

Solamente entra a la interrupcion por cambio de estado en el pin RB0..... Estoy realizando esto con el pic16f877 y ya le he estado dando muchas vueltas y aun no encuentro que es lo que puedo tener mal.....

Agradeceria mucho si alguien me pudiera dar algun tipo acerca de este tema que me ayude a resolver lo siguiente...

Saludos :)
Título: Re: Manejo de 2 interrupciones MikroC
Publicado por: bigluis en 12 de Febrero de 2011, 13:49:15
 :? Por lo general cuando hay una interrupción por cambio en las entradas tienes que mandar a leer esa entrada, de lo contrario el flag de interrupciones jamás se pondrá a cero.

Pero creo que ese error solo ocurre cuando es por cambio en el puerto, es decir por el IOC (Interrup On Change).

Prueba a leer el puerto antes de borrar el falg de interrupciones.
Título: Re: Manejo de 2 interrupciones MikroC
Publicado por: Suky en 12 de Febrero de 2011, 14:11:33
Claro, si o si hay que leer el puerto para que el cambio se haga efectivo y detectar el próximo cambio o no.  ;-)


Saludos
Título: Re: Manejo de 2 interrupciones MikroC
Publicado por: Palomino86 en 12 de Febrero de 2011, 16:26:01
Listo ya encontre el problema.

Me configurar el registro PIE1.

Código: [Seleccionar]
//Librerias
#include "lcd_serial.h"

//Variables Globales
volatile long Contador,Overflow;
char Numeros[10];
unsigned char n;

void Write_Char(char *s);

//Interrupción
void interrupt(void)
{
  if(INTCON.INTF==1)                                                               //Verifica si se activo la bandera de interrupción del Puerto B0
  {
    Contador++;
    INTCON.INTF=0;
  }
 
  if(PIR1.TMR2IF==1)                                                             //Verifica si se activo la bandera de interrupcion de TMR2
  {
    Overflow++;
    PIR1.TMR2IF=0;
  }
}

//Programa Principal
void main()
{

//Configuración de Pines
  ADCON1=7;                                                                     //Todos los pines como digitales
  PORTB=0;                                                                      //Limpia el puerto B
  PORTC=0;                                                                      //Limpia el puerto C
  PORTD=0;                                                                      //Limpia el puerto D
  TRISB=0b00100001;                                                             //Configuración del Puerto B
  TRISC=0b00000000;                                                             //Configuración del Puerto C
  TRISD=0b10000000;                                                             //Configuración del Puerto D

  PIR1=0;                                                                       //Limpia las banderas de interrupción del registro PIR1
  INTCON=0b00000000;                                                            //Interrupciones Deshabilitadas al inicializar

//Configuración del Timer 2
  T2CON=0b00100000;                                                             //Configuracion del Registro T2CON Prescaler = 1, Postcaler = 5, TMR2 = Off
  TMR2=0;                                                                       //Inicializamos el valor del TIMER 2 en cero.
  PR2=124;                                                                      //Valor de PR2 para que cada 128 us se realice una interrupción.

  Soft_UART_Init(&PORTB,5,4,9600,0);                                            //Configuración de comunicación serial por UART (Modo Invertido)
  Delay_ms(200);

  Contador=0;
  while(1)
  {
   Contador=0; Overflow=0; strcpy(Numeros,' ');

   INTCON=0b11010000;                                                           //Interrupciones Deshabilitadas al inicializar
   T2CON=0b00100100;                                                            //Configuracion del Registro T2CON Prescaler = 1, Postcaler = 5, TMR2 = On
   PIE1=0b00000010;

   while(Overflow<8000);
   
   INTCON=0b00000000;                                                           //Interrupciones Deshabilitadas al inicializar
   T2CON=0b00100000;                                                            //Configuracion del Registro T2CON Prescaler = 1, Postcaler = 5, TMR2 = Off
   
   LongToStr(Contador,Numeros);
   HomeLCD();
   WriteLCD("Frec:",5);
   Write_Char(Numeros);
   WriteLCD(" Hz",3);
   
   Delay_ms(500);
  }
}

void Write_Char(char *s)
{
  while(*s)
  {
      if(*s!=' ')
      {
        Soft_UART_Write(*s) ;
      }
      s++ ;
  }
}

Aqui queda el codigo de un detector de frecuencias

Saludos