Autor Tema: Ayuda con un proyecto!!!  (Leído 1763 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Fenhasan

  • PIC10
  • *
  • Mensajes: 9
Ayuda con un proyecto!!!
« en: 22 de Diciembre de 2004, 21:23:00 »
Hola amigos:

·Tengo algunas dudas respecto a un proyecto que estoy desarrollando. Tengo que monitorear tres pulsadores, lo cual estoy haciendo mediante la interrupción por cambio del puerto B, y discrimino en software qué pin cambió.

·Si cualquiera de los pines cambia de estado, se inicia una temporización de 2 segundos; la temporización se interrumpe si otro de los pines cambia de estado, y se produce un pulso de salida de 10 [ms] de duración. Si la cuenta termina normalmente, no hay pulso de salida.

·Mi problema se produce con la temporización; el período es de una duración real mucho mayor a la que yo esperaba, y no entiendo bien el porqué; supongo que se debe a las líneas de assembler que genera el compilador, pero aun así creo que es demasiado largo.

·A continuación adjunto el codigo que escribí, para que por favor me echen una manito:

Codigo:


//Funciona mediante la interrupción de cambio de PortB.
//En este caso, detecta los cantos de subida en los
//pines RB4 a RB7.

#include <16F628A.h>
#reserve 0x20
#byte FLAGS = 0x20
#bit  FLAG5 = 0x20.5
#bit  FLAG6 = 0x20.6
#bit  FLAG7 = 0x20.7
#fuses INTRC_IO,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOMCLR,NOPUT,NOCPD
#use delay(clock=4000000)
#use rs232(baud=9600, parity=N, bits=8, xmit=PIN_B2, rcv=PIN_B1)
#use standard_io(B)

#int_rb
void rb_isr()
{
int change,last_b;
change = last_b ^ input_b();
if(bit_test(change,7)&&!bit_test(last_b,7))
   FLAG7 = 1;   // cambio RB7
if(bit_test(change,6)&&!bit_test(last_b,6))
   FLAG6 = 1;   // cambio RB6
if(bit_test(change,5)&&!bit_test(last_b,5))
   FLAG5 = 1;   // cambio RB5
//if(bit_test(change,4)&&!bit_test(last_b,4))
//   FLAG4 = 1;   // cambio RB4
last_b  = input_b();
delay_ms(50); //Antirebotes
}

#int_rda
void rda_isr()
{
int dato;
dato = getc();

if(dato==49)
{
 write_eeprom(0,49); //1 segundo
 reset_cpu();
}

if(dato==50)
{
 write_eeprom(0,50); //2 segundos
 reset_cpu();
}

if(dato==51)
{
 write_eeprom(0,51); //3 segundos
 reset_cpu();
}

}

void pulse()
{
output_high(PIN_A1);
delay_ms(10);
output_low(PIN_A1);
}

main()
{
int16 i;
int stored,t;

ENABLE_INTERRUPTS(global);
ENABLE_INTERRUPTS(int_rb);
ENABLE_INTERRUPTS(int_rda);

stored = read_eeprom(0);   //Leer seteo para la demora;
                           //se hace en cada reset.
if(stored==49)
 t=20;   //1 segundo  = 50000 * 20 [us]

if(stored==50)
 t=40;   //2 segundos = 50000 * 40 [us]

if(stored==51)
 t=60;   //3 segundos = 50000 * 60 [us]

i=0;

while(1)
   {
   if(FLAG7)                             //CASO 1
   {
   
    output_high(PIN_A2);
    while(!(FLAG6||FLAG5)&&(i<50000))   //Rutina de retardo
    {
     delay_us(t);
     i++;
    }
    output_low(PIN_A2);
   
    if(FLAG6||FLAG5)
     pulse();

    FLAGS=0;   //bajar el flag

    i=0;      //Resetear contador
   }

   if(FLAG6)                             //CASO 2
   {
   
    output_high(PIN_A2);
    while(!(FLAG7||FLAG5)&&(i<50000))   //Rutina de retardo
    {
     delay_us(t);
     i++;
    }
    output_low(PIN_A2);
   
    if(FLAG7||FLAG5)
     pulse();

    FLAGS=0;   //bajar el flag

    i=0;      //Resetear contador
   }

   if(FLAG5)                               //CASO 3
   {
    output_high(PIN_A2);
    while(!(FLAG7||FLAG6)&&(i<50000))     //Rutina de retardo
    {
     delay_us(t);
     i++;
    }
    output_low(PIN_A2);
    if(FLAG7||FLAG6)
     pulse();

    FLAGS=0;   //bajar el flag

    i=0;      //Resetear contador
   }

   }

}



·Bueno, ese es mi problema; espero que alguien me pueda ayudar en esto. También pensé en temporizar contando interrupciones de TMR0, pero no logré realizarlo Llorica

·Agradeciendo de antemano su ayuda, se despide atte.

Fernando

Desconectado Modulay

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2651
RE: Ayuda con un proyecto!!!
« Respuesta #1 en: 23 de Diciembre de 2004, 05:53:00 »
Holas Fernando.
No sé si la rutina de interrupcion por cambio de estado en el puerto B te estará funcionando como debe por un pequeño detalle:
La variable last_b no la inicializas antes de usarla para modificar el valor de "change",por lo que estoy viendo le asignas el valor del puerto B después de haberla ya utilizado.Esto creo q deberías hacerlo al revés,ya que si la declaras y la usas sin darle un valor determinado antes,obtendrás resultados "no deseados".
Creo que la rutina está un poco enrevesada.Si lo que quieres es saber únicamente que pin es el que se activó,se puede hacer de forma más sencilla haciendo uso de la funcion input() ó bit_test()
Saludos

Desconectado cHiPmAn

  • PIC16
  • ***
  • Mensajes: 110
RE: Ayuda con un proyecto!!!
« Respuesta #2 en: 23 de Diciembre de 2004, 06:19:00 »
Holas,

tan solo me he mirado la rutina de interrupción y he visto alguna cosilla rara.

En primer lugar, hacer retardos en la rutina de interrupción es de las peores cosas que puedes hacer. Yo lo sacaria (hace tiempo tube problemas metiendo un delay en la rutina de interrupción).

En segundo lugar, no veo donde borras el flag que avisa que ha habido un cambio en el puertoB. Ahora no recuerdo como se llama el bit.

A ver si suena la flauta RollEyes y puedes arreglar el codigo.

Suerte!

Desconectado cHiPmAn

  • PIC16
  • ***
  • Mensajes: 110
RE: Ayuda con un proyecto!!!
« Respuesta #3 en: 23 de Diciembre de 2004, 06:20:00 »
Otra cosilla importante es q la variable last_b la has definido de manera local. Yo desconozco que hace el compilador, pero lo mas normal es que no guarde su valor.

Desconectado Fenhasan

  • PIC10
  • *
  • Mensajes: 9
RE: Ayuda con un proyecto!!!
« Respuesta #4 en: 28 de Diciembre de 2004, 11:51:00 »
Holas:

·Uhm, en realidad la rutina de detección de interrupciones parece funcionar bien, en el sentido de que el tiempo de espera se interrumpe una vez que se detecta la pulsación de otro botón.

·Sin embargo, lo que no puedo lograr es que el tiempo de retardo dure lo que yo necesito: necesito 2 [seg] y llega hasta 20 [seg] !!! Todavía no puedo entender el porqué... La rutina es la misma que apparece en el main().

·Si alguien sabe algún método más apropiado para hacer una temporización precisa, estaría muy agradecido. Atte.

Fernando