Banner publicitario de PCBWay

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