Autor Tema: Problema con pulsador seleccionando funciones.  (Leído 2660 veces)

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

Desconectado iNoXSteeL

  • PIC12
  • **
  • Mensajes: 75
    • La web de InoX
Problema con pulsador seleccionando funciones.
« en: 13 de Septiembre de 2009, 05:47:08 »
Hola a todos,

en primer lugar, quería felicitaros por hacer que éste foro sea posible, ya que en el he encontrado bastante ayuda, y bibliografía que consultar. Mi más sincera enhorabuena.

Os expongo mi consulta.

Como principiante en el tema de la programación de PIC's, me he propuesto como ejercicio, realizar el parpadeo de una serie de led's como piloto trasero para una bicicleta, la función que se pretende realizar es, si presiono una vez el pulsador, que ejecute un tipo de parpadeo, si vuelvo a pulsar, el siguiente tipo de parpadeo, así pasando por una serie de funciones hasta volver nuevamente a 0.

Probando con un par de funciones, simulando en proteus, solo consigo que acceda a la segunda función, no soy capaz de que alterne entre las 2 funciones que tiene y que luego se quede en 0, digamos que se quede de nuevo sin funcionar.

Código: [Seleccionar]
#include <16f84A.h>
#fuses XT,NOWDT,NOPROTECT,NOPUT

#byte puertoa=0x05
#byte puertob=0x06

#use delay(clock=4000000)
#use standard_io(A)

int pulsa=0;

void funcion1()               //PARPADEAN TODOS LOS LED
   {
   while(true)
   {
   puertob=(0x1ff);
   delay_ms(100);
   puertob=(0x00);
   delay_ms(100);
   }
   }

void funcion2()               //PARPADEO ALTERNO DE LOS LED
   {
   while(true)
   {
   puertob=(0x55);
   delay_ms(100);
   puertob=(0x00);
   delay_ms(100);
   puertob=(0xaa);
   delay_ms(100);
   puertob=(0x00);
   delay_ms(100);
   }
   }


void main()
   {
   set_tris_a(0x01);
   set_tris_b(0x00);
   puertob=0x00;
   puertoa=0x00; 
 
   while(true)
   {
   if (input(pin_a0)); pulsa++;
   if (pulsa==1) funcion1();
   if (pulsa==2) funcion2();
   if (pulsa==3); pulsa=0;
   }
   }
 

Aparte, en el simulador, me aparecen una serie de advertencias, haciendo referencia a Trisa y a Trisb, TRISA instruction is deprecated for pic 1684.

He tratado de buscar algo relacionado sobre esa advertencia, pero no me he acabado de aclarar muy bien. A ver si me podéis aclarar un poco sobre ambas dudas.

Agradezco vuestra atención.

Un saludo.

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Problema con pulsador seleccionando funciones.
« Respuesta #1 en: 13 de Septiembre de 2009, 09:40:28 »
Hay varias cositas a revisar en el código:
  • No es necesario definir PuertA y PuertoB, para cargar el puerto con algún valor está la función output_x();
  • Defines #use standard_io(A) pero configuras su tris, y standard indica que el compilador cambiará el tris segun sea la instrucción a usar sobre el puerto. Deberías colocar #use fast_io(a) y #use fast_io(b) ya que está claro como será la configuración de cada pin.
  • while(1){} es un bucle infinito y no hay manera de salir de él salvo con un reset, así que no puedes colocarlo en la secuencia si quieres seleccionar otra.
  • Es necesario que tengas en cuenta el efecto rebote de los pulsadores.
  • Habían un par de ; demás.
Revisado todo eso el código quedaria de la siguiente manera:

Código: C
  1. #include <16f84A.h>
  2. #fuses XT,NOWDT,NOPROTECT,NOPUT
  3.  
  4. #use delay(clock=4000000)
  5. #use fast_io(A)
  6. #use fast_io(B)
  7.  
  8.  
  9. int pulsa=0;
  10.  
  11. void funcion1()               //PARPADEAN TODOS LOS LED
  12.    {
  13.    output_b(0xff);
  14.    delay_ms(100);
  15.    output_b(0x00);
  16.    delay_ms(100);
  17.    }
  18.  
  19. void funcion2()               //PARPADEO ALTERNO DE LOS LED
  20.    {
  21.  
  22.    output_b(0x55);
  23.    delay_ms(100);
  24.    output_b(0x00);
  25.    delay_ms(100);
  26.    output_b(0xaa);
  27.    delay_ms(100);
  28.    output_b(0x00);
  29.    delay_ms(100);
  30.    }
  31.  
  32.  
  33. void main()
  34.    {
  35.    set_tris_a(0x01);
  36.    set_tris_b(0x00);
  37.    output_a(0);
  38.    output_b(0);
  39.    while(true)
  40.    {
  41.       if (input(PIN_A0)){
  42.          delay_ms(30);
  43.          if(input(PIN_A0)){
  44.             pulsa++;
  45.          }
  46.       }
  47.       if (pulsa==1) funcion1();
  48.       if (pulsa==2) funcion2();
  49.       if (pulsa==3) pulsa=0;
  50.    }
  51.    }


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

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Problema con pulsador seleccionando funciones.
« Respuesta #2 en: 13 de Septiembre de 2009, 11:30:48 »
Hola.

Creo que la mejor opción es usar la interrupción de RB0 para asignar el pulsador, ya que debido a como están definidas las funciones del pulso, es muy difícil "atinarle" a la función que detecta el pulsador.

Código: C#
  1. #int_RB0
  2. void Pulso_isr(void)
  3. {
  4.  delay_ms(50);//Antirrebotes
  5.  pulsa++;
  6. }

El main quedaría casi igual:

Código: C#
  1. #use fixed_io(b_outputs=pin_b1,pin_b2,pin_b3,pin_b4,pin_b5,pin_b6,pin_b7)
  2. ...
  3. void main()
  4.  {
  5.   set_tris_a(0x01);
  6.   output_a(0);
  7.   ext_int_edge(L_TO_H);
  8.   enable_interrupts(INT_EXT);
  9.   enable_interrupts(GLOBAL);
  10.   while(true)
  11.   {
  12.      if (pulsa==1) funcion1();
  13.      if (pulsa==2) funcion2();
  14.      if (pulsa==3) pulsa=0;
  15.   }
  16.  }

Saludos
El papel lo aguanta todo

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Problema con pulsador seleccionando funciones.
« Respuesta #3 en: 13 de Septiembre de 2009, 11:48:48 »
Tiene mucha razón MLO_, lo único que con esa solución ya no podes usar RB0  :mrgreen:

tengo otra solución creo potable, usar el timer0 como contador, esperando un único pulso:

Código: C
  1. #int_TIMER0
  2. void  TIMER0_isr(void)
  3. {
  4.    delay_ms(30);
  5.    pulsa++;  
  6.    set_timer0(255);
  7. }
  8.  
  9.  
  10. void main()
  11.    {
  12.    set_tris_a(0x10);
  13.    set_tris_b(0x00);
  14.    setup_timer_0(RTCC_EXT_H_TO_L|RTCC_DIV_1);
  15.    output_b(0);
  16.    clear_interrupt(INT_TIMER0);
  17.    set_timer0(255);                    
  18.    enable_interrupts(INT_TIMER0);
  19.    enable_interrupts(GLOBAL);
  20.    while(true)
  21.    {
  22.       if (pulsa==1) funcion1();
  23.       if (pulsa==2) funcion2();
  24.       if (pulsa==3) pulsa=0;
  25.    }
  26.    }


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

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Problema con pulsador seleccionando funciones.
« Respuesta #4 en: 13 de Septiembre de 2009, 12:03:33 »
También es viable, igual en los dos casos se pierde un pin  :mrgreen:

Saludos
El papel lo aguanta todo

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Problema con pulsador seleccionando funciones.
« Respuesta #5 en: 13 de Septiembre de 2009, 12:17:44 »
También es viable, igual en los dos casos se pierde un pin  :mrgreen:

Saludos

A pero en mi caso no del puerto B  :D :D  ;-)
No contesto mensajes privados, las consultas en el foro

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
Re: Problema con pulsador seleccionando funciones.
« Respuesta #6 en: 13 de Septiembre de 2009, 12:40:26 »
yo opino que es bueno usar la interrupción externa por cambio de flanco RB0, por las siguientes razones:

- una vez presionada la tecla, si se mantiene pulsada no ocurriran mas interrupciones (configurando un solo tipo de flanco)

- las llamadas a las siguientes funciones se harán unicamente por cada interrupción sucesiva, con esto te evitas tener que meter un retardo entre detecciones de pulsadas.

ademas que hay que tomar en cuenta el retardo antirrebote, pero para no complicar tanto el programa, le pones un condensador de 470nF en paralelo al botón.

La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado iNoXSteeL

  • PIC12
  • **
  • Mensajes: 75
    • La web de InoX
Re: Problema con pulsador seleccionando funciones.
« Respuesta #7 en: 13 de Septiembre de 2009, 13:42:21 »
Hola.

Suky, MLO__,PalitroqueZ, gracias por vuestra atención y por vuestras respuestas, en principio hay instrucciones que me han sonado a chino y que tengo que asimilar, pero toda ayuda es buena para aprender.

Me he decantado por la segunda solución de Suky, ya que la primera no funcionaba correctamente. En la solución dada por MLO__, el compilador soltaba un error en el preprocesador a causa de la instrucción #int rb0, y como soy aún bastante novato, no he querido ahondar en temas más profundos e ir poco a poco.

En principio ya funciona el código, a excepción de una línea final que añadí, que pone a 0 el puerto B cuando pulsa=0, así no deja led encendido.

Nuevamente gracias por todo.

Nos leemos.

Un saludo.

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Problema con pulsador seleccionando funciones.
« Respuesta #8 en: 14 de Septiembre de 2009, 09:12:53 »
Hola.

El error es por el nombre de la interrupción. Segun el archivo 16F84A.h, se llama int_EXT.

Saludos
El papel lo aguanta todo