TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: iNoXSteeL en 13 de Septiembre de 2009, 05:47:08

Título: Problema con pulsador seleccionando funciones.
Publicado por: iNoXSteeL 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.
Título: Re: Problema con pulsador seleccionando funciones.
Publicado por: Suky en 13 de Septiembre de 2009, 09:40:28
Hay varias cositas a revisar en el código:
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!
Título: Re: Problema con pulsador seleccionando funciones.
Publicado por: MLO__ 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
Título: Re: Problema con pulsador seleccionando funciones.
Publicado por: Suky 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!
Título: Re: Problema con pulsador seleccionando funciones.
Publicado por: MLO__ en 13 de Septiembre de 2009, 12:03:33
También es viable, igual en los dos casos se pierde un pin  :mrgreen:

Saludos
Título: Re: Problema con pulsador seleccionando funciones.
Publicado por: Suky 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  ;-)
Título: Re: Problema con pulsador seleccionando funciones.
Publicado por: PalitroqueZ 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.

Título: Re: Problema con pulsador seleccionando funciones.
Publicado por: iNoXSteeL 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.
Título: Re: Problema con pulsador seleccionando funciones.
Publicado por: MLO__ 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