Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
- Committer:
- villani
- Date:
- 2022-06-05
- Revision:
- 0:b24a8232cb00
File content as of revision 0:b24a8232cb00:
#include "mbed.h"
Ticker tick; //Definición del ticker
// Entradas y salidas
// Leds indicadores de turno
DigitalOut LED_JUG_1(PTE30);
DigitalOut LED_JUG_2(PTE29);
//Control de catodos para la multiplexación
DigitalOut K_1(PTA13);
DigitalOut K_2(PTD5);
//Segmentos del los displays
DigitalOut SEGMENTO_A(PTC12);
DigitalOut SEGMENTO_B(PTC13);
DigitalOut SEGMENTO_C(PTC16);
DigitalOut SEGMENTO_D(PTC17);
DigitalOut SEGMENTO_E(PTA16);
DigitalOut SEGMENTO_F(PTA17);
DigitalOut SEGMENTO_G(PTE31);
//Fila de leds de juego
BusOut myleds(PTC7,PTC0,PTC3,PTC4,PTC5,PTC6,PTC10,PTC11); //Funcion para vectorizar la salida
//Pulsadores
BusIn mypuls(PTC8,PTC9); //Funcion para vectorizar la entrada (jugador 1 y 2 respectivamente)
// Definicion de estados
enum{
STANDBY = 0, //0
TURNO_J1, // 1
TURNO_J2, // 2
TRANSICION, //3
GANADOR //4
};
#define BASE_TIEMPO 0.01 // Base de tiempo 10ms
//Declaración de variables universales
unsigned int t = 0; //Timer de la maquinada de estados
unsigned int clk = 0; //Timer de multiplexación
unsigned char tipo_de_transicion = 0; //Define que transición se ejecutará y a que estado pasara despues de pasar por el estado TRANSICION
static int posicion_leds; //Define que led de juego estara encendido una vez el juego comenzado
unsigned char direccion; //Define el recorrido de "la luz"
unsigned char prox_turno; //Define a posicion inicial y dirección de "la luz"
static int parpadeo = 0; //Define la cantidad de veces que el/los leds parpadean
unsigned char puntuacion[2] = {0};
unsigned char numero_display[10] = {0b1111110,0b0110000,0b1101101,0b1111001,0b0110011,0b1011011,0b1011111,0b1110000,0b1111111,0b1111011}; //Vector con todos los valores binarios necesarios para el control de los displays usando operaciones de bits
//Maquina de estados
void Input_Pulso(int indice);
//Funcion para el manejo de displays
void Display(int numero_1, int numero_2);
// Funcion del ticker
void Interrupcion(void)
{
t++;
clk++;
}
//Inicialización de comunicación serial
Serial pc(USBTX, USBRX, 115200);
int main() {
// Inicializaciones
mypuls[0].mode(PullNone);
mypuls[1].mode(PullNone);
tick.attach(&Interrupcion, BASE_TIEMPO);
//Bucle infinito
while(1){
Input_Pulso(0);
Display(puntuacion[0], puntuacion[1]);
}
}
void Input_Pulso(int indice){
static int estado = STANDBY; //Estado inicial
switch(estado){
case STANDBY:
//Antes de iniciar el juego
LED_JUG_1 = 1; //Se encienden ambos leds indicadores de turnos
LED_JUG_2 = 1;
if(t<100){ //Durante 1s...
for(int p=0;p<8;p++){ //Los leds de juego pares permaneceran prendidos mientras que los impares apagados
if(p % 2 == 0)
myleds[p] = 1;
else
myleds[p] = 0;
}
}
if(t>=100 && t<200){ //Durante 1s pasado el anterior...
for(int p=0;p<8;p++){ //Los leds de juego impares permaneceran prendidos mientras que los pares apagados
if(p % 2 != 0)
myleds[p] = 1;
else
myleds[p] = 0;
}
}
if(t>=200) //Cada 2s el timer t se resetea
t=0;
if(mypuls[0]==1 && mypuls[1]==1){ //Si ambos pulsadores se presionan simutaneamente...
estado = TRANSICION; //Se cambia el estado dando inicio al juego
t = 0; //Se resetea el timer t
tipo_de_transicion = 0; //Se indica que trancición se ejecutara
for(int p=0;p<8;p++){ //Se apagan todos los leds de juego
myleds[p] = 0;
}
}
break;
case TRANSICION:
//Abarca todas las tranciciones del juego
if(puntuacion[0]>=5 || puntuacion[1]>=5){ //Primero se revisa si alguno de los dos jugadores ganó
estado = GANADOR; //Cabio de estado a GANADOR
if(puntuacion[0] > puntuacion[1]) //Luego se revisa cual de los dos jugadores gano y se comunica serialmente
pc.printf("EL JUGARDOR 1 GANA!!!!\n");
else
pc.printf("EL JUGARDOR 2 GANA!!!!\n");
for(int p=0;p<8;p++){ //Se apagan todos los leds de juego
myleds[p] = 0;
}
}
switch(tipo_de_transicion){
case 0: //Transición del estado STANDBY a TURNO_J1
//Todos los leds de juego parpaderan lentamente tres veces antes de dar inicio al juego
if(t<50){ //Los primeros 500ms...
for(int p=0;p<8;p++){ //Se encienden todos los leds de juego
myleds[p] = 1;
}
}
else if(t>=50 && t<100){ //Los siguientes 500ms...
for(int p=0;p<8;p++){ //Se apagan todos los leds de juego
myleds[p] = 0;
}
}
else if(t>=100 && t<150){ //Los siguientes 500ms...
for(int p=0;p<8;p++){ //Se encienden todos los leds de juego
myleds[p] = 1;
}
}
else if(t>=150 && t<200){ //Los siguientes 500ms...
for(int p=0;p<8;p++){ //Se apagan todos los leds de juego
myleds[p] = 0;
}
}
else if(t>=200 && t<400){ //El siguiente segundo...
for(int p=0;p<8;p++){ //Se encienden todos los leds de juego
myleds[p] = 1;
}
}
else if(t>=400){ //Luego de 4s del ultimo reinicio del timer...
for(int p=0;p<8;p++){ //Se apagan todos los leds de juego
myleds[p] = 0;
}
t = 0; //Se reinicia el timer t
estado = TURNO_J1; //Se cambia el estado al turno del jugador 1
direccion = 0; //Se ajustan las condiciones iniciales de "la luz"
posicion_leds = 0;
LED_JUG_2 = 0; //Se apaga el led de turno 2 mientras que el otro se deja encendido
}
break;
case 1: //Trancición entre los turnos de los jugadores
//El led de juego que se encontraba encendido al momento de la pulsación del jugador en su turno se pondra a parpadear rapidamente (100ms) por un breve periodo de tiempo antes del siguiente turno
if(t>10 && parpadeo<15){
parpadeo++;
myleds[posicion_leds]=!myleds[posicion_leds];
t = 0; //Se reinicia el timer t
}
if(parpadeo>=15){
//En función de la variable "proximo_turno" se cambia el estado a "TURNO_J1" o "TURNO_J2" y se ajustan las condiciones iniciales y al estado que se cambiara
if(prox_turno==0){
direccion = 0;
posicion_leds = 0;
LED_JUG_1 = 1;
LED_JUG_2 = 0;
estado = TURNO_J1;
}
else if(prox_turno==1){
direccion = 1;
posicion_leds = 7;
LED_JUG_1 = 0;
LED_JUG_2 = 1;
estado = TURNO_J2;
}
parpadeo = 0; //Se resetea la variable
}
break;
default: //No deberia pasar nunca pero esta puesto por las dudas
tipo_de_transicion = 0;
break;
}
break;
case TURNO_J1:
switch(direccion){ //Controla que la variable "posicion_leds" vaya de 0 a 7 y viceversa
case 0: //Dirección estandar
if(t >= 5){ //Tiempo en el que tarda un "pasar la luz de un led al siguiente"
posicion_leds++;
t = 0; //Se resetea el tiempo
}
if(posicion_leds >=7) //Una vez llegando al ultimo led de juego...
direccion = 1; //Cambio de dirección
break;
case 1: //Dirección inversa
if(t >= 5){ //Tiempo en el que tarda un "pasar la luz de un led al anterior"
posicion_leds--;
t = 0; //Se resetea el tiempo
}
if(posicion_leds <=0) ///Una vez llegando al primer led de juego...
direccion = 0; //Cambio de dirrección
break;
default: //No deberia pasar nunca pero esta puesto por las dudas
direccion = 0;
break;
}
for(int p=0;p<8;p++){ //Primero se apagan todos los leds de juego
myleds[p] = 0;
}
myleds[posicion_leds] = 1; //Luego se prende unicamente el led de juego que la variable "posicion_leds" defina
if(mypuls[0] == 1){ //Pulsación del jugador 1
if(posicion_leds==7) //Si el led se juego encendido es el ultimo...
puntuacion[0]++; //Se logra puntuar
t = 0; //Se resetea el tiempo
tipo_de_transicion = 1; //Se indica que trancición de ejecutara
estado = TRANSICION; //Se cambia el estado
prox_turno = 1; //Se indica que el proximo turno es del jugador 2
pc.printf("JUGARDOR 1:%d JUGADOR 2:%d\n",puntuacion[0],puntuacion[1]); //Se comunica la puntuación por comunicación serial
}
break;
case TURNO_J2:
switch(direccion){ //Controla que la variable "posicion_leds" vaya de 0 a 7 y viceversa
case 0: //Dirección estandar
if(t >= 5){ //Tiempo en el que tarda un "pasar la luz de un led al siguiente"
posicion_leds++;
t = 0; //Se resetea el tiempo
}
if(posicion_leds >=7) //Una vez llegando al ultimo led de juego...
direccion = 1; //Cambio de dirección
break;
case 1: //Dirección inversa
if(t >= 5){ //Tiempo en el que tarda un "pasar la luz de un led al anterior"
posicion_leds--;
t = 0; //Se resetea el tiempo
}
if(posicion_leds <=0) //Una vez llegando al primer led de juego...
direccion = 0; //Cambio de dirrección
break;
default: //No deberia pasar nunca pero esta puesto por las dudas
direccion = 0;
break;
}
for(int p=0;p<8;p++){ //Primero se apagan todos los leds de juego
myleds[p] = 0;
}
myleds[posicion_leds] = 1; //Luego se prende unicamente el led de juego que la variable "posicion_leds" defina
if(mypuls[1] == 1){ //Pulsación del jugador 2
if(posicion_leds==0) //Si el led se juego encendido es el primero...
puntuacion[1]++; //Se logra puntuar
t = 0; //Se resetea el tiempo
tipo_de_transicion = 1; //Se indica que trancición de ejecutara
estado = TRANSICION; //Se cambia el estado
prox_turno = 0; //Se indica que el proximo turno es del jugador 1
pc.printf("JUGARDOR 1:%d JUGADOR 2:%d\n",puntuacion[0],puntuacion[1]); //Se comunica la puntuación por comunicación serial
}
break;
case GANADOR:
//Todos los leds de juego parpaderan
if(t>10 && parpadeo<50){ //Ajuste de tiempo y cantidad de veces que los leds parpadearan
parpadeo++;
for(int p=0;p<8;p++){
myleds[p]=!myleds[p];
}
t = 0;
}
if(parpadeo>=50){ //Una vez finalizado el parpadeo...
parpadeo = 0;
estado = STANDBY; //Se cambia al estado inicial
puntuacion[0] = 0; //Se reinician ambas puntuaciones
puntuacion[1] = 0;
}
break;
}
}
void Display(int numero_1, int numero_2){
//A la funcion se le ingresan dos variales: puntuacion[0] y puntuacion[1]
static int posicion=0; //Variable que difine los estados de los transistores colocados en los catodos de los displays
if(clk==1){ //Tiempo de multiplexación: 10ms
if(posicion==1){
posicion = 0; //Cambio de la variable para el siguiento uso
K_2 = 0; //Transistor 2 al corte
K_1 = 1; //Transistor 1 en saturación
//Impresión de la puntuación del jugador 1 en el primer display
SEGMENTO_A = numero_display[numero_1]&0b1000000;
SEGMENTO_B = numero_display[numero_1]&0b0100000;
SEGMENTO_C = numero_display[numero_1]&0b0010000;
SEGMENTO_D = numero_display[numero_1]&0b0001000;
SEGMENTO_E = numero_display[numero_1]&0b0000100;
SEGMENTO_F = numero_display[numero_1]&0b0000010;
SEGMENTO_G = numero_display[numero_1]&0b0000001;
}
else{
posicion = 1; //Cambio de la variable para el siguiento uso
K_1 = 0; //Transistor 1 al corte
K_2 = 1; //Transistor 2 en saturación
//Impresión de la puntuación del jugador 2 en el segundo display
SEGMENTO_A = numero_display[numero_2]&0b1000000;
SEGMENTO_B = numero_display[numero_2]&0b0100000;
SEGMENTO_C = numero_display[numero_2]&0b0010000;
SEGMENTO_D = numero_display[numero_2]&0b0001000;
SEGMENTO_E = numero_display[numero_2]&0b0000100;
SEGMENTO_F = numero_display[numero_2]&0b0000010;
SEGMENTO_G = numero_display[numero_2]&0b0000001;
}
clk = 0; //Reseteo del clock
}
}