Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

21/10/2015 #1


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.
21/10/2015 #2
Moderador

Avatar de D@rkbytes

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:
Código 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);
   }

21/10/2015 #3


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.!
21/10/2015 #4
Moderador

Avatar de D@rkbytes

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:
#include <PIC.H>

int Mi_Var1, Mi_Var2;

#INT_EXT
void int_ext_isr (void)
{
    // Código
}
Y si son variables exclusivas de la rutina, las debes incluir internamente.
Código:
#INT_EXT
void int_ext_isr (void)
{
    int Mi_Var1, Mi_Var2; 
    // Código
}
También debes tener en cuenta cuando se debe mantener el valor de una variable y cuando debe ser inicializada.
Respuesta
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.