Autor Tema: Manejo de 2 interrupciones MikroC  (Leído 10859 veces)

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

Desconectado Palomino86

  • PIC16
  • ***
  • Mensajes: 180
Manejo de 2 interrupciones MikroC
« 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 :)
Lo que no me destruye, me fortalece

Desconectado bigluis

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 511
    • Tutoriales de Qt C++
Re: Manejo de 2 interrupciones MikroC
« Respuesta #1 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.
Tutoriales de Qt C++

No es necesario que hagamos Grandes cosas, sino que lo que hagamos sea importante.

SI la NECESIDAD es la MADRE del CONOCIMIENTO, SEGURAMENTE la PEREZA su TÍA.

Cuando el ARTE requiere de PRECISION le llamamos CIENCIA

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Manejo de 2 interrupciones MikroC
« Respuesta #2 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
No contesto mensajes privados, las consultas en el foro

Desconectado Palomino86

  • PIC16
  • ***
  • Mensajes: 180
Re: Manejo de 2 interrupciones MikroC
« Respuesta #3 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
Lo que no me destruye, me fortalece


 

anything