TODOPIC

Microcontroladores PIC => * PROYECTOS * => Mensaje iniciado por: juanchin en 13 de Enero de 2013, 11:00:53

Título: Diseño marcador de ping-pong con pic16f886
Publicado por: juanchin en 13 de Enero de 2013, 11:00:53
Hola a todos,
Estoy diseñando un marcador de ping-pong para mi mesa  :lol: . Pienso usar un PIC16F886, un 7447 y 4 displays de 7 segmentos. Lo estoy haciendo en C con mplab. La entrada, con los pulsadores (uno para subir el marcador y el otro para bajar, por cada jugador), va a ser por el puerto A, voy a usar el puerto B para la habilitación de cada display y el puesto C para mostrar los números.

Acá va el código:
Código: [Seleccionar]
#include <pic.h>
#include <htc.h>

#define _XTAL_FREQ 4000000

int j1 = 0;
int j1_unidades = 0; //jugador 1
int j1_decenas = 0;
int j2 = 0;
int j2_unidades = 0; //jugador 2
int j2_decenas = 0;

void mostrar();

void main()
{
TRISA = 0xFF; //configuro el puerto A como entrada
TRISB = 0x00; //configuro los puertos B y C como salidas.
TRISC = 0x00;

PORTA = 0x00;
PORTB = 0x00;
PORTC = 0x00;

ANSEL = 0; //configuro todos los puestos como entrada/salida digital

while(1)
{
if(PORTAbits.RA4 == 1) //botón de reset
{
if(PORTAbits.RA0 == 0)
{
j1_unidades++;
j1++;
if(j1_unidades == 10)
{
j1_unidades = 0;
j1_decenas++;
}
}

if(PORTAbits.RA1 == 0)
{
j1_unidades--;
j1--;
if(j1_unidades == -1)
{
j1_unidades = 9;
j1_decenas--;
}
}

if(PORTAbits.RA2 == 0)
{
j2_unidades++;
j2++;
if(j2_unidades == 10)
{
j2_unidades = 0;
j2_decenas++;
}
}

if(PORTAbits.RA3 == 0)
{
j2_unidades--;
j2--;
if(j2_unidades == -1)
{
j2_unidades = 9;
j2_decenas--;
}
}

mostrar(20);

if(((j1==7)&&(j2==0))||((j1==11)&&(j2==1))||((j1>=21)&&((j1-j2)>=2))) //si gana el jugador 1, de cualquiera de las 3 formas posibles
{
//TRISA = 0x00; ¿como desjabilito el puerto A?
j2_decenas = 0;
j2_unidades =0;
mostrar();
}

if(((j2==7)&&(j1==0))||((j2==11)&&(j1==1))||((j2>=21)&&((j2-j1)>=2))) //si gana el jugador 2, de cualquiera de las 3 formas posibles
{
//TRISA = 0x00;
j1_decenas = 0;
j1_unidades =0;
mostrar();
}

} //fin "if" del reset

else
{
j1_decenas = 0;
j1_unidades = 0;
j2_decenas = 0;
j2_unidades =0;
j1 = 0;
j2 = 0;
mostrar();
TRISA = 0xFF;
}

} //fin while
} //fin main

void mostrar()
{
PORTC = j1_decenas;
PORTB = 0x10;
__delay_ms(20);

PORTC = j1_unidades;
PORTB = 0x20;
__delay_ms(20);

PORTC = j2_decenas;
PORTB = 0x40;
__delay_ms(20);

PORTC = j2_unidades;
PORTB = 0x80;
__delay_ms(20);
}

¿Qué les parece? ¿se podría mejorar? Lo que querría agregarle es que cuando un jugador gane, se deshabilite el puerto A para que no se puedan seguir subiendo o bajando los puntos y también me gustaría que el marcador que ganó titile. ¿Cómo podría hacer esas cosas?

También adjunto una simulación en proteus. Si alguno lo simula, ¿esta bien como se ven los displays? Lo que hago es habilitar los displays de a uno, en la simulación se re nota el cambio de displya a display ¿se va a ver así en la realidad o se va a ver mas fluido?

Desde ya, muchas gracias!!!
Título: Re: Diseño marcador de ping-pong con pic16f886
Publicado por: fantaxmax en 13 de Enero de 2013, 13:40:31
no te seria mejor ocupar un pic mas pequeñito como el 16f84a? tiene pines suficientes para controlar el 7447, los displays, y los botones, el compilador que yo uso es CCS, y de hecho tengo una libreria para controlar 4 displays con un solo puerto, debo modificarla un poquito porque enviaba los datos el 7447 y luego a un flipflop d, para no tener que refrescar tan seguido si el numero no cambiaba.
cabe destacar que saque varias cosas de esta libreria ya que como mencione anteriormente, usaba flipflop's para mantener el valor del display.

Código: C
  1. // definimos los pines de activacion de los display de siete segmentos
  2. #ifndef DSP_1
  3. #define DSP_1 PIN_B4
  4. #endif
  5. #ifndef DSP_2
  6. #define DSP_2 PIN_B5
  7. #endif
  8. #ifndef DSP_3
  9. #define DSP_3 PIN_B6
  10. #endif
  11. #ifndef DSP_4
  12. #define DSP_4 PIN_B7
  13. #endif
  14. // definimos funciones recortadas
  15. #define ACT output_high
  16. #define DES output_low
  17.  
  18. // envia los 7 bits del display
  19. void dsp_putc(BYTE a, BYTE d){
  20. output_b(d);
  21. if(a==0){ACT(DSP_1);}
  22. if(a==1){ACT(DSP_2);}
  23. if(a==2){ACT(DSP_3);}
  24. if(a==3){ACT(DSP_4);}
  25. delay_us(10);
  26. DES(DSP_1);
  27. DES(DSP_2);
  28. DES(DSP_3);
  29. DES(DSP_4);
  30. }

eso saca el numero binario, y la activacion de los displays, por el puerto b. B0-3=numero binario, B4-7=displays, esto lo puedes portar al c de mplab, no creo que sea muy dificil, espero te sirva esta ayuda,

para los consejos que pides, para los botones, puedes usar un flag, que se compruebe cada vez que presionas un boton
para que el display titile, puedes usar un 555, o puedes hacer el pic envie no todas las veces en numero al display, me explico?, imagine en tu mente un lapso de tiempo aleatorio, ahi va un tren de pulsos, el cual le dice al display, que el dato que hay en los pines compartidos, es de el, entonces, en ves de enviar todos esos pulsos, suprimes la mitad, de 50 pulsos, envias 25, y 25 los suprimes, de 5 en 5, para que se cree el efecto que deseas, ahi ya puedes ir probando cual te genera un mejor efecto,
respecto a los displays en el proteus, es normal que se note el cambio, en la vida real no se nota ese efecto, pero tienes que reducir ese delay, a unos 500 us, ya que 20ms es mucho, bueno eso basicamente puedo aportar,

Saludos! y suerte!
Título: Re: Diseño marcador de ping-pong con pic16f886
Publicado por: juanchin en 17 de Enero de 2013, 10:59:15
Muchas gracias por la respuesta!! Lo voy a tener en cuenta para el diseño final.

Saludos.