TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: polac en 20 de Enero de 2014, 14:51:51

Título: necesito un poco de ayuda con programa para pic 16f886
Publicado por: polac en 20 de Enero de 2014, 14:51:51
Diseñar un contador de impulsos externos, (introducido por un pulsador conectado a RA5) de 0 a 99.
La cuenta se debe mostrar en 2 displays de 7 segmentos de ánodo común multiplexados conectados a la puerta B controlados por RA0 y RA1

Mi problema es que al llegar a 9 el contador de las decenas no se activa y no me rula el programa, alguien puede echarme una mano?

#include <16f886.h>
#fuses NOLVP,PUT,NOWDT,EC_IO,NOFCMEN,NOBROWNOUT,NOWRT,BORV40
#use fast_io(A)
#use fast_io(B)
#use delay (clock=4000000)
void main ()
 {
  int cont;
  const int display[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x98};
  int num,dec,uni;
   setup_adc_ports(NO_ANALOGS);
   set_tris_A(0b00100000);
   set_tris_B(0);
   cont=0;
   while(1)
    {
      dec=num/10;
     uni=num%10;
     output_B(display[dec]);
     output_high(PIN_A1);
      output_low(PIN_A0);
     delay_ms(5);
       output_B(display[uni]);
     output_low(PIN_A1);
      output_high(PIN_A0);
     delay_ms(5);
         {
        if(input(PIN_A5)==0)
         {
           if(cont==99)
            {
              cont=0;
            }
                 else
                {
                  cont++;
                }
                 output_B(display[cont]);
                 while(input(PIN_A5)==0);
                 delay_ms(10); 
             }
         }
     }
  }
Título: Re: necesito un poco de ayuda con programa para pic 16f886
Publicado por: AngelGris en 20 de Enero de 2014, 15:21:44
  Como primer punto creo que deberías cambiar el orden en que manejas los display. Yo creo que es conveniente primero deshabilitar los dos display, luego cambiar el dato del puerto B y como tercer paso habilitar el display correspondiente.

  Como segundo punto habría que ver si con los delay que estás utilizando es suficiente. Tal vez por mucho o poco delay te está dando la sensación que no enciende el display adecuado.

  Como tercer punto, como tu quedas a la espera de que se suelte el pulsador (al utilizar "while (input(pin_a5) == 0"), si pasa mucho tiempo con el pulsador presionado, el display dejará de mostrar la información.
Título: Re: necesito un poco de ayuda con programa para pic 16f886
Publicado por: ppyote en 20 de Enero de 2014, 15:28:52
Elimina está línea output_B(display[cont]) y prueba
te recomendaría que la cuenta la hagas con el timer1, por el pin a4 así evitaras que el antirebote del pulsador haga parpadear el display
o con el timer hacer el refresco del display
Título: Re: necesito un poco de ayuda con programa para pic 16f886
Publicado por: carferper en 20 de Enero de 2014, 16:07:02
yo intentaria darle algo de estructura a tu programa y agregar una rutina antirebotes, algo asi por ejemplo:

Código: [Seleccionar]
#include <16f886.h>

#fuses NOLVP, PUT, NOWDT, EC_IO, NOFCMEN, NOBROWNOUT, NOWRT, BORV40

#use fast_io(A)
#use fast_io(B)

#use delay (clock = 4000000)

void actualizar_digito(const int digito)
    {
    const int tbl_disp[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x98};
    output_A = 0xFF;
    output_B = tbl_disp[digito];
    }

void actualizar_display(const int contador)
    {
    actualizar_digito(contador%10);
    output_low(PIN_A1);
    delay_ms(4);

    actualizar_digito(contador/10);
    output_low(PIN_A0);
    delay_ms(4);
    }

void main(void)
    {
    int db_cnt, cont = 0;
    setup_adc_ports(NO_ANALOGS);
    set_tris_A(0b00100000);
    set_tris_B(0b00000000);

    while(1)
        {
        for (db_cnt = 0; db_cnt < 10;)
            {
            db_cnt = (input(PIN_A5) == 0) ? db_cnt + 1 : 0;
            actualizar_display(cont);
            }

        if (input(PIN_A5) == 0)
            cont = (cont < 99) ? cont + 1 :  0;
        
        for (db_cnt = 0; db_cnt < 10;)
            {
            db_cnt = (input(PIN_A5) == 0) ? 0 : db_cnt + 1;
            actualizar_display(cont);
            }
        }
    }
Título: Re: necesito un poco de ayuda con programa para pic 16f886
Publicado por: polac en 20 de Enero de 2014, 16:19:08
gracias, por la ayuda, la cosa es que soy un estudiante de telecomunicaciones y todavía no he avanzado mucho, entonces no puedo usar instrucciones mas avanzadas que estas, he probado a quitar la linea output_B(display[cont]) como me dijo ppyote y nada, y tambien me estoy pegando con los displays que me aconseja AngelGris, pero las decenas me siguen sin contar, del 9 se pasa al 8 . y las decenas se quedan en 0, seguire probando pero gracias.
Título: Re: necesito un poco de ayuda con programa para pic 16f886
Publicado por: AngelGris en 20 de Enero de 2014, 16:36:32
  Trataré de darle algo de forma a mi pensamiento, no en el formato de CCS, pero creo que se entenderá. Algo que sería de mucha ayuda es ver tu esquema de conexionado.

Código: C
  1. unsigned char contador = 0; // variable contador inicializada en 0
  2. unsigned char estado_anterior = 0; // esta variable la voy a utilizar para ver el estado anterior del puerto
  3.  
  4. apagar ambos display
  5. while(1)
  6. {
  7.   poner en el puerto B el valor de la unidad
  8.   enceder display unidad
  9.   retardo necesario
  10.   apagar display unidad
  11.   poner en el puerto B el valor de la decena
  12.   encender display de decena
  13.   retardo necesario
  14.   apagar el display de decena
  15.  
  16.   if ((estado_anterior == 1) && (a5 == 1)) // si estaba presionado y a5 ahora esta suelto
  17.     estado_anterior = 0; // boton suelto
  18.   if ((estado_anterior == 0) && (a5 == 0)) // si estaba suelto y a5 ahora esta presionado
  19.   {
  20.     delay 15 ms // retardo como antirebote
  21.     if (a5 == 0) // si sigue presionado (no fue un rebote)
  22.     {
  23.       contador++; // incremento contador
  24.       estado_anterior = 1; //indico que el estado es presionado
  25.     }
  26.   }
  27. }
Título: Re: necesito un poco de ayuda con programa para pic 16f886
Publicado por: carferper en 20 de Enero de 2014, 17:18:34
puedes empezar probando unicamente el contador con algo asi:
Código: [Seleccionar]
   while(1)
    {
        if (cont < 99)
            cont++;
        else
            cont = 0;      

        output_A = 0xFF;
        output_B = tbl_disp[cont/10];
        output_low(PIN_A1);
        delay_ms(4);
        output_A = 0xFF;
        output_B = tbl_disp[cont%10];
        output_low(PIN_A0);
        delay_ms(4);
    }

y despues incluir el boton pulsador usando cualquier rutina antirebotes. si no quieres usar funciones trata algo como esto:

Código: [Seleccionar]
#include <16f886.h>

#fuses NOLVP, PUT, NOWDT, EC_IO, NOFCMEN, NOBROWNOUT, NOWRT, BORV40

#use fast_io(A)
#use fast_io(B)

#use delay (clock = 4000000)

void main(void)
    {
    int estado_pulsador = 0, cont = 0;
    setup_adc_ports(NO_ANALOGS);
    set_tris_A(0b00100000);
    set_tris_B(0b00000000);
    
    const int tbl_disp[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x98};

    while(1)
        {
        if (input(PIN_A5) == 0)
            {
            delay_ms(10);
            if ((input(PIN_A5) == 0) && (estado_pulsador == 0))
                estado_pulsador = 1;
            }
        
        if ((input(PIN_A5) == 1) && (estado_pulsador == 1))
            {
            delay_ms(10);
            if (input(PIN_A5) == 1)
                {
                estado_pulsador = 0;
                if (cont < 99)
                    cont++;
                else
                    cont = 0;
                }
            }
        output_A = 0xFF;
        output_B = tbl_disp[cont/10];
        output_low(PIN_A1);
        delay_ms(4);
        output_A = 0xFF;
        output_B = tbl_disp[cont%10];
        output_low(PIN_A0);
        delay_ms(4);
        }
    }
Título: Re: necesito un poco de ayuda con programa para pic 16f886
Publicado por: polac en 22 de Enero de 2014, 16:05:25
gracias ya lo resolvi, perdón por la tardanza en responder.

Al final me fallaba que  defini int cont y num, y estaba mal, quite int num, y donde pone num, puse cont y ya va bien, ademas de que sobraba la linea output_B(display[cont]); como dijisteis
 
int cont;
  const int display[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x98};
  int num,dec,uni;
   setup_adc_ports(NO_ANALOGS);
   set_tris_A(0b00100000);
   set_tris_B(0);
   cont=0;
   while(1)
    {
      dec=num/10;
     uni=num%10;

     output_B(display[dec]);