Medir ancho de pulso con interrupciones. Inconvenientes.

Buenas,
Estoy trabajando con el PIC16F873A, intentando medir el ancho de un pulso ingresado por el puerto B, utilizando el TIMER0. (Con CCS)

A Continuacion subo el programa correspondiente:

Código:
#include <16f873A.h>
#use delay(clock=100000)
#fuses NOWDT,XT,NOLVP,NOPROTECT

#BYTE TRISB= 0x86
#byte PORTB=0x06
#byte TRISC=0x87
#byte PORTC=0x07
#INT_EXT
int valor;
int bandera=0;

ext_isr()
{
if(bandera ==0)
      {  
      set_timer0(0);
      ext_int_edge(L_to_H);
      bandera=1;
      }
else
      {
      valor=get_timer0();
      ext_int_edge(H_to_L);
      bandera=0;
      }
}

void main()
{
SET_TRIS_B(0X01);
TRISC = 0x00;
PORTC=0;
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
enable_interrupts(int_ext);
ext_int_edge(H_to_L);
enable_interrupts(GLOBAL);
while(1)
{
 PORTC=valor;
}
}


Al querer simular en proteus, me salta el error siguiente:
"stack overflow pushing return address of interrupt"
y
"attempt to write unimplemented memory location 0x009C with 0x07 ignored".

Cualquier ayuda o sugerencia sera bienvenida.Slds.
 
Última edición por un moderador:
Posiblemente sea por la estructura que tiene tu programa, la versión de compilador con respecto a las instrucciones TRIS, o la frecuencia de 100 KHz que tienes defina.
(Tal vez quisiste poner 1 MHz. = 1000000)

Prueba de ésta forma:
PHP:
#include <16f873a.h>
#use     delay(crystal = 1MHz)

int8 valor;
int8 bandera=0;
   
#INT_EXT
void ext_isr()
{  
   if(bandera == 0)
   {  
      set_timer0(0);
      ext_int_edge(L_to_H);
      bandera = 1;
   }
   else
   {
      valor = get_timer0();
      ext_int_edge(H_to_L);
      bandera = 0;
   }
}


void main()
{
   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256);
   enable_interrupts(INT_EXT);
   ext_int_edge(H_to_L);
   enable_interrupts(GLOBAL);
   
   while(true)
   {
      output_c(valor);
   }
}
 
Gracias! El inconveniente estaba justo en una de las partes que me corregiste.

#include <16f873A.h>
#use delay(clock=1000000)
#fuses NOWDT,XT,NOLVP,NOPUT
#use standard_io(c)
#byte PORTC=0X07
int valor=0;
int bandera=0;


#INT_EXT

ext_isr()
{
...
}


Funciona Correctamente.

Si coloco al reves, es decir,de la siguiente manera, se produce stack overflow

#include <16f873A.h>
#use delay(clock=1000000)
#fuses NOWDT,XT,NOLVP,NOPUT
#use standard_io(c)
#byte PORTC=0X07

#INT_EXT
int valor=0;
int bandera=0;

ext_isr()
{...}



Si supieras explicarme, te agradeceria. Calculo que es error de principiante.
Saludos y muchas gracias.!
 
Es sencillo. Estabas colocando tus variables entre el indicador del controlador y el servicio de interrupción, pero no dentro.

Lo puedes hacer de dos formas.

Si requieres de variables globales, las declaras en la cabecera del programa.

Por ejemplo:
Código:
[B][COLOR=Red]#include [/COLOR]<PIC.H>[/B]

[B][COLOR=Blue]int[/COLOR] Mi_Var1, Mi_Var2;[/B]

[COLOR=Red][B]#INT_EXT[/B][/COLOR]
[B][COLOR=Blue]void[/COLOR] int_ext_isr ([COLOR=Blue]void[/COLOR])[/B]
{
    [COLOR=Olive][B]// Código[/B][/COLOR]
}
Y si son variables exclusivas de la rutina, las debes incluir internamente.
Código:
[COLOR=Red][B]#INT_EXT[/B][/COLOR]
[B][COLOR=Blue]void[/COLOR] int_ext_isr ([COLOR=Blue]void[/COLOR])[/B]
{
   [B][COLOR=Blue] int[/COLOR] Mi_Var1, Mi_Var2; [/B]
   [COLOR=Olive][B] // Código[/B][/COLOR]
}
También debes tener en cuenta cuando se debe mantener el valor de una variable y cuando debe ser inicializada.
 
Última edición:
Atrás
Arriba