Autor Tema: Problema simulando en Proteus - Interrupcion INT_EXT  (Leído 6049 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado _Maxi

  • PIC10
  • *
  • Mensajes: 34
Problema simulando en Proteus - Interrupcion INT_EXT
« en: 30 de Agosto de 2009, 07:28:18 »
Hola, qué tal? Bueno les comento.

Estoy haciendo un programa simple.. cuando se detecta un flanco H_TO_L en el pin RB0, se enciende un led que está en el pin D0, pongo un delay por un segundo, y luego se apaga.. y así sigue.

Leí por ahí que en la interrupción no hay que usar delays ni nada de eso, sino que hay que tratar de salir lo más rápido posible de la misma, así que el delay de 1 segundo lo puse afuera, en el código se ve cómo lo hice.

Bueno, el problema es que algunas veces, cuando genero el flanco H_TO_L con un pulsador, el led no se prende, no pasa nada, y otras veces sí se prende.. es algo como aleatorio. Quisiera saber si es un comportamiento erroneo normal del proteus o si mi código tiene algo mal.

Éste es el código:

Código: [Seleccionar]
#include <16f887.h>
#use delay (clock=1000000)

#int_ext
void interrupcion()
{
output_high(PIN_D0);
}

void main()
{
set_tris_d(0b00000000);

enable_interrupts(int_ext);
enable_interrupts(global);
ext_int_edge(H_TO_L);

output_low(PIN_D0); //inicio con el led apagado

while(1)
{
    if(input(PIN_D0)) //si el led está prendido, esperar 1 seg y apagarlo
    {
         delay_ms(1000);
         output_low(PIN_D0);
    }
}
}

Éste es el circuito:



Gracias!

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
Re: Problema simulando en Proteus - Interrupcion INT_EXT
« Respuesta #1 en: 30 de Agosto de 2009, 07:59:49 »
Hola _Maxi, voy a ver si te puedo ayudar algo.

Si utilizas un PIN como salida no debes (ni puedes) preguntar por su estado ya que lo cambias a entrada y en el PIC rela tendrías resultados indeterminados y en Proteus vaya usted a saber qué es lo que hace.

Lo suyo es utilizar una variable para recordar qué es lo último que hemos sacado por nuestro PIN y actuar en consecuencia.

Te pongo tu mismo código pero un poco modificado:

Código: CSS
  1. #include <16f887.h>
  2. #use delay (clock=1000000)
  3.  
  4.  
  5. int1 STATE_D0;
  6.  
  7. #int_ext
  8. void interrupcion(){
  9.    output_high(PIN_D0);
  10.    STATE_D0=1;
  11. }
  12.  
  13. void main(){
  14.  
  15.    set_tris_d(0b00000000);
  16.    set_tris_b(0b00000001);
  17.  
  18.    ext_int_edge(H_TO_L);
  19.    enable_interrupts(int_ext);
  20.    enable_interrupts(global);
  21.  
  22.    output_low(PIN_D0); //inicio con el led apagado
  23.    STATUS_D0=0;
  24.  
  25.    while(1){
  26.  
  27.       if(STATUS_D0==1){ //si el led está prendido, esperar 1 seg y apagarlo
  28.          STATUS_D0=0;
  29.          delay_ms(1000);
  30.          output_low(PIN_D0);
  31.       }
  32.    }
  33. }

Pruébalo y nos dices.
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado _Maxi

  • PIC10
  • *
  • Mensajes: 34
Re: Problema simulando en Proteus - Interrupcion INT_EXT
« Respuesta #2 en: 30 de Agosto de 2009, 08:11:30 »
Muchas gracias RedPic, jeje, un error de novatazo XD. Ahora está andando bien :)

Aprovecho para hacer otra preguntita.. sólo en el RB0 puedo tener una interrupción por cambio de estado de algún pin? Ahora voy a leer el datasheet pero si alguien me lo dice por acá me da una mano.

Lo que pasa es que quiero poder activar por ejemplo con 4 pulsadores sobre distintos pines, y poder ver cuál pulsador cambió de flanco.
« Última modificación: 30 de Agosto de 2009, 08:33:22 por _Maxi »

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
Re: Problema simulando en Proteus - Interrupcion INT_EXT
« Respuesta #3 en: 30 de Agosto de 2009, 08:16:25 »
¿El PIC era .... ? Ah si, el 16F887.

Si, creo que todos los de la serie 16F tienen una sola interrupción externa directa. Pero disponen de otra que es muy parecida aunque requiere más código para saber qué está ocurriendo.

Es la Interrupción por Cambio de Estado en los pines del PORTB del 4º al 7º ó  RB4:7 ó #INT_RB.

Dale un vistazo a  Midiendo un pulso. 3ª Parte. Tiempo en Alto con INTRB
« Última modificación: 30 de Agosto de 2009, 08:18:54 por RedPic »
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado _Maxi

  • PIC10
  • *
  • Mensajes: 34
Re: Problema simulando en Proteus - Interrupcion INT_EXT
« Respuesta #4 en: 30 de Agosto de 2009, 08:35:43 »
Lo que pasa es que quiero poder activar por ejemplo con 4 pulsadores sobre distintos pines, y poder ver cuál pulsador cambió de flanco.

Estoy leyendo el link, podría usar esa interrupción de los bits 4-7 del puerto b, y si hago a tiempo antes de que el pulsador se me despulse, preguntar qué puerto acaba de cambiar y guardarlo en una variable.

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Problema simulando en Proteus - Interrupcion INT_EXT
« Respuesta #5 en: 30 de Agosto de 2009, 10:30:29 »
Lo que pasa es que quiero poder activar por ejemplo con 4 pulsadores sobre distintos pines, y poder ver cuál pulsador cambió de flanco.

Estoy leyendo el link, podría usar esa interrupción de los bits 4-7 del puerto b, y si hago a tiempo antes de que el pulsador se me despulse, preguntar qué puerto acaba de cambiar y guardarlo en una variable.

No te preocupes, que vas a tener tiempo suficiente para detectar cual se ha pulsado  ;-)


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado _Maxi

  • PIC10
  • *
  • Mensajes: 34
Re: Problema simulando en Proteus - Interrupcion INT_EXT
« Respuesta #6 en: 31 de Agosto de 2009, 08:12:19 »
Edit: Al final del post escribí de qué manera lo solucioné.

Hola, tengo otra consulta.

Ahora hice un programa que va contando en un display de 7 segmentos las veces que apretamos un pulsador (0-9). Cuando apretamos un pulsador, mediante la interrupcion sumamos un contador y en base a eso mandamos la señal al display.

Mi problema es que en la placa protoboard, mi contador en vez de empezar de 0, empieza desde 1. En cambio en la simulación sí empieza desde 0, como debe ser.

Puede ser que por alguna razón, cuando se inicializa el pic, se me genera un flanco de H_TO_L y por eso ya de entrada en un tiempo imperceptible se me aumenta el contador de 0 a 1? no se, es medio raro.. La resistencia que usé para conectar el pin RB0 a 5v es de 11k, no de 10k, porque no tenía. Así que agarré 2 resistencias de 22k y las puse en paralelo.

Código:

Código: [Seleccionar]
#include <16f887.h>
#use delay (clock=1000000)

int8 i=0;

#int_ext
void sumar()
{
   i=i+1;
}

void main()
{
int8 num[10],i_anterior=15;

enable_interrupts(int_ext);
enable_interrupts(global);
ext_int_edge(H_TO_L);

set_tris_d(0x00);
set_tris_b(0b00000001);

output_d(0x00);

num[0]=0b00111111;
num[1]=0b00000110;
num[2]=0b01011011;
num[3]=0b01001111;
num[4]=0b01100110;
num[5]=0b01101101;
num[6]=0b01111101;
num[7]=0b00000111;
num[8]=0b01111111;
num[9]=0b01100111;

while(1)
{
   if(i<10 && i_anterior!=i)
   {
      output_d(num[i]);
      i_anterior=i;
    }

if(i>=10)
{
   output_d(0b01000000);
   delay_ms(500);
   output_d(0b00000000);
   delay_ms(500);
}
}

}

Circuito:



Gracias.

Solución:

Bueno, lo que hice fue medio un "parche", y fue inicializar la variable del contador, i, en -1, y cuando arranca el programa, esperar con un delay y después poner i=0. En la función de la interrupción le puse un if que pregunta si i es igual a -1, en ese caso no hace nada, entonces así logro escapar a esa interrupcion indeseada de cuando arranco el pic. Lo que no se es por qué sucede esa interrupción indeseada.
« Última modificación: 31 de Agosto de 2009, 09:05:51 por _Maxi »

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Problema simulando en Proteus - Interrupcion INT_EXT
« Respuesta #7 en: 31 de Agosto de 2009, 10:17:37 »
Debes reorganizar tu código al inicio, primero deben ir las configuración de puertos, luego seteo de los puertos y como última tarea la habilitación de las interrupciones:



Código: C
  1. void main()
  2. {
  3. int i_anterior=15;
  4.  
  5.      set_tris_d(0x00);
  6.      set_tris_b(0b00000001);
  7.  
  8.      output_d(0x00);
  9.  
  10.      ext_int_edge(H_TO_L);
  11.      clear_interrupts(int_ext);  // borra flags
  12.      enable_interrupts(int_ext);
  13.      enable_interrupts(global);
  14.      .
  15.      .
  16.      .


Luego la tabla la puedes definirla como variables constantes y cargar sus valores en la definición:

Código: C
  1. const int num[10]={0b00111111,0b00000110,0b01011011,.....};


Saludos!






No contesto mensajes privados, las consultas en el foro

Desconectado _Maxi

  • PIC10
  • *
  • Mensajes: 34
Re: Problema simulando en Proteus - Interrupcion INT_EXT
« Respuesta #8 en: 01 de Septiembre de 2009, 10:08:23 »
Muchas gracias a todos, ya tengo andando bien el codigo :)

Una cosita Suky, al probar con clear_interrupts(int_ext); me daba error, así que en la ayuda ví que en realidad era sin la s final, clear_interrupt(int_ext); y ahí anduvo bien! Lo aclaro por si alguien lo lee después.

Gracias, ahora voy a seguir por los tutoriales de RedPic.
Acá el video de lo que quería hacer:


 

anything