TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado 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:
//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...
//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 :)
-
:? 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.
-
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
-
Listo ya encontre el problema.
Me configurar el registro PIE1.
//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