Version mas reciente 2.0. Contiene manejo de joystick, interrupciones y mejoras de algunos bugs

Dependencies:   mbed

tetris

Tarjeta: En este caso se usa la tarjeta STM FM411 RE [1], usa un procesador ARM CORTEX M4 ,el cual trabaja a una velocidad máxima de 100 MHZ, y adicional mente, contiene las siguientes especificaciones:

Voltaje de alimentación: 1.7v-3.6 V. Voltaje de salida: 3.3v-5v Interfaces de comunicación: 3modulos I2C 3 modulas USART 5 módulos SPI (SPI-I2SS) 1 módulo SDIO 1 MODULO A CONEXIÓN USB, puerto 2.0 de alta velocidad

Conversor análogo a digital: Posee un conversor hasta de 16 canales con resolución de 12 bits.

Periféricos Para este caso, se usa la matriz led de 8*8, adicionalmente, se usa el integrado max 7219,este integrado permite el control de hasta 8 dígitos o 7 segmentos , o el control de 64 diodos led independientes. Esto se debe a que este chip realiza un multiplexado para concatenar la información, y gracias a la memoria ram que tiene incorporada puede almacenar en bits de 8*8, este integrado es bastante versátil, ya que funciona con el uso de únicamente 3 conexiones. Este es muy usado para realzar el control de una gran cantidades de diodos led, o display de 7 segmentos por medio del uso de tarjetas programables, minimizando la cantidad de conexiones por cada display a programar. Para realizar el encendido de la 3, el chip usa los pines 2,3,5-8, los cuales funcionan como cátodos, y permiten la conexión positiva de cada uno de los led, por otro lado, se cierra el circuito por medio de la tierra asignada en los pines 4,9.

CONEXIÓN DE MATRIZ DE LED

Pines. Pin 13: Contiene la conexión al reloj, debido a que la señal de reloj esta generada de tal forma, que siempre es constante, normalmente es una onda cuadrada con una frecuencia fija y constante. Al realizar la sincronización de circuitos (que todos operen bajo la misma señal), esto permite que para los mismos se puede configurar la frecuencia, así como retardos, de acuerdo a los tiempos de respuesta configurados, y la configuración que se tenga para tomar la configuración (Flancos de subida, o flancos de bajada, la cual permite la sincronización entre la matriz de led y la tarjeta de forma síncrona. Para tomar la señal proveniente del procesador principal, el integrado Max 7219 , usa el pin 13, el cual esta designado para tomar la señal proveniente y sincronizar con la misma para que tanto la tarjeta como la matriz operen con la misma señal. Pin 15: pin referente a la salida de información de la memoria maestra de la tarjeta, este pin va conectado directamente al pin de la matriz, conocido como MOSI, el cual significa (Master Output Slave Input), traducido, nos indica que genera la trasmisión de datos desde un integrado principal a otro esclavo. Para este caso, la transmisión se genera desde la tarjeta, la cual por medio de la conexión del pin 15, en el cual, además de tener disponible la conexión para controlar UN PWM, también permite el envió de información desde el procesador principal , hacia la matriz. El pin usado por el integrado Max 7219 para recibir la información es el 1, el cual esta predeterminado como MOSI, y por el cual ingresan los datos enviados desde la tarjeta, con una capacidad de procesamiento de 16 bit, trabajando al a velocidad determinada desde el control principal, configurada como señal CLK, haciendo el papel de disco esclavo, se encargándose de ejecutar las rutinas diseñadas Pin 12: Dadas las distintas funcionalidades que se le pueden dar a este pin, para este caso se optó para generar desde el mismo (UART, MISO Y USB), se usa la configuración UART (envío y recepción de información), de tal forma, que este nos permite el envío y recepción de información.

Este proceso se genera desde la rutina configurada, permitiendo el uso únicamente de este pin para generar las dos funcionalidades.

En el caso del integrado MAX 7219, la recepción de información se realiza por medio del pin 1, haciendo que el integrado actué como disco esclavo, pero trasmite datos a el disco principal por medio del pin 12, el cual se encarga de registrar la información a partir de los flancos de bajada, con un procesamiento de 16 bits y trasmitirla de acuerdo a la velocidad configurada en la señal CLK.

CONEXIÓN DE JOYSTICK

Los joystick se definen como dos resistencias variables que a medida que se modulan generan cambios de voltaje de acuerdo a la rotación de eje, el cual es compatible con distintas interfaces, el cual tiene la siguiente conexión. Conexión de pines GND: Tierra VCC: Conexión a 5v VRx : Genera la variación de voltaje, reflejando desplazamientos en el eje x de la matriz de led VRy: Genera la variación de voltaje, reflejando desplazamientos en el eje Y de la matriz de led SW: Pulsador.

Configuracion de puertos:

SPI deviceM(PB_15, PB_14, PB_13); Esta línea se encarga de enviar información a la matriz, utilizándola como un disco esclavo en el cual únicamente se muestra la configuración enviada desde la tarjeta

DigitalOut ssel (PB_12); Se encarga de generar la recepción de información proveniente desde la matriz.

Serial command(USBTX,USBRX); Se encarga de enviar y recubrir información por el puerto USB serial

AnalogIn joy(A0); Conversor Analogo digital, que se encarga de leer las variación del voltaje del joystyk en el eje X

AnalogIn joy1(A1); Conversor Analogo digital, que se encarga de leer las variación del voltaje del joystyk en el eje X

Velocidad de transmisión Para establecer la velocidad de comunicación, se define la velocidad con la cual se planea que trabaje el procesador, en este caso 200milisegundos (ms), este se define como un retardo, presente en la función init_display

CODIGO

  1. include "figs.h": Esta librería se encarga de generar el parámetro en una matriz 3*3 , en el cual de acuerdo a la figura que se desea dibujar se indican los segmentos que se desean utilizar. Codigo:
  2. ifndef FIGS_H
  3. define FIGS_H
  4. include "mbed.h"
  5. define PLANT_TYPE 1

uint8_t PLANT[7]={0b10000000,0b11000000,0b11100000,0b01000000,0b01100000,0,0b00100000};FIG_C[0]=1; FIG_C[1]=11; FIG_C[2]=111; FIG_C[3]=01; FIG_C[4]=011

  1. endif

Función SendSPI: Dentro de esta función se establecen dos variables con en nombre de d1 y d2, las cuales se encargan de recibir 2 datos, el registro, y la información que desea ser visualizada, por lo cual en primera medida, se genera la habilitación, e indaga sobre la comunicación en el puerto serial, y dependiendo del registro que está solicitando la información, se habilita, y realiza en él envió de la misma. Al finalizar la trasmisión, deshabilita, y espera que nuevamente ingrese información para ser mostrada en la matriz. Codigo: void sendSPI(uint8_t d1, uint8_t d2) { deviceM.unlock(); ssel=0; deviceM.write(d1); deviceM.write(d2); ssel=1; deviceM.lock();

Init_display: Prepara la matriz para la comunicación con la tarjeta, usando todas las filas y columnas, y configurando la intensidad de la iluminación, para este caso, indicando que no se realizara la decodificación de datos. Finalmente realiza el testeo de la matriz, solicitando que todos los led enciendan y es apaguen 4 veces, con el fin de que el usuario verifique que todos los led funcionen correctamente.

Codigo: void init_display() { sendSPI(0x0c,1); sendSPI(0x0b,7); sendSPI(0x09,0); sendSPI(0x0A,0x0E); int j; for (j=0;j<4;j++){ sendSPI(0x0F,1); wait (0.2); sendSPI(0x0f,0); wait (0.2); }

Función copy_matrix : dentro de esta función , se imprimen las figuras declaradas en la función anterior, según corresponda el registro. Para que visualmente las figuras no se salgan de la matriz de led, se genera la comparación de cada una, con el fin de que está a pesar de la columna que se escoja para ser visualizada y siempre este dentro del campo visual del usuario, lo cual está registrado dentro de la matriz con el nombre matrix_act. Después de tener la figura que se va a imprimir, la matriz matrix_temp, Se encarga de generar el desplazamiento visual de la forma elegida, para esto, se genera la comparación de la matriz en cada una de las filas, de tal forma, que este se genere de una forma continua, evaluando una fila a la vez, y al detectar el registro en la misma, pase a la siguiente fila.

Codigo: void copy_matrix(uint8_t a,uint8_t b,uint8_t c,uint8_t* fig,uint8_t columna) { if(((matrix_act[cont-2]& *(fig+c)>>columna-1)==0)&&((matrix_act[cont-1]& *(fig+b)>>columna-1)==0)&&((matrix_act[cont]& *(fig+a)>>columna-1)==0)){ matrix_temp[0]= *(fig+5)>>columna-1; matrix_temp[1]= *(fig+a)>>columna-1; matrix_temp[2]= *(fig+b)>>columna-1; matrix_temp[3]= *(fig+c)>>columna-1;

Función Borrar Con el fin de limpiar las constantes declaradas y que no se visualice basura, esta función se encarga de recorrer la y limpiar los distintos valores registrados en las columnas de la matriz que contiene los límites de las figuras matriz_act , esto se hace, cada vez que se envía un dato por el puerto serial (función sendSPI).

Codigo: void borrar() { int i; for(i=0;i<=8;i++) { sendSPI(i,0); matrix_act[i]=0; }

Funcion buscar_fila En primera media, esta función se inicializa con un for el cual genera un barrido a la matriz para permitir a la figura desplazarse en los espacios que tenga disponibles , para que esta es uboque sobre la o las figuras , o sobre algún según correspoda.

Para que esto funcione se genera la comparación entre la información de las columnas (matrix_act) y las filas (matrix_temp)¸cuando ya se ha llegado al límite establecido de filas, se genera la comparación para que la figura actual se quede estática. Finalmente, se limpia la matriz de columnas (matriz act) y se envía el dato que permite habilitar nuevamente el envió de otra figura desde la primera fila.

Codigo: void buscar_fila(){ for (uint8_t i=0;i<9;i++){ if((matrix_act[i]& matrix_temp[3])==0){ fila=i; } if(((matrix_act[i]& matrix_temp[3])!=0)&& (i!=9)){ fila=i-1; command.printf("Fila pos 1: %d \n", fila); i=9; } if(((matrix_act[i]& matrix_temp[2])!=0)&& (i!=9)){ fila=i; i=9; command.printf("Fila pos 2: %d \n", fila); } if(((matrix_act[i]& matrix_temp[1])!=0)&& (i!=9)){ fila=i+1; i=9; command.printf("Fila pos 3: %d \n", fila); } } if(fila>8) fila=8; if(fila<=1){ wait_ms(VEL); borrar(); fila=8; Función guardar: se genera la comparación entre cada una filas y columnas contenidas en las matrices matrix_act (columnas) y matrix_temp, permitiendo guardar la figura cuando esta llega a la última fila, o al límite establecido por alguna figura que se encuentre en la parte inferior y la cual debe quedar estática.

Codigo: void guardar(){ matrix_act[fila-3]=matrix_temp1[0]; matrix_act[fila-2]=matrix_temp1[1]; matrix_act[fila-1]=matrix_temp1[2]; matrix_act[fila ]=matrix_temp1[3];

Función reada: Para hacer uso del Joystick, se debe tener en cuenta los cambios de voltaje, los cuales indicaran los movimientos en los ejers X y Y , para generar dicha lectura, se leen la información contenida en los puertos de los conversores análogos a digital AO y A1, de acuerdo a la variación de voltaje en los mismos, se interpretara el movimiento que se debe generar en el eje X (izquierda y derecha), y en el eje Y (de arriba hacia abajo únicamente).

Codigo: void reada() { vx=0; vy=0; vx=joy.read(); vy=joy1.read(); cc=cambio.read() Función movimiento_fig: Dentro de esta función se describe el desplazamiento de las figuras en el eje X y Y , extrayendo los valores de los conversores análogos, para determinar el movimiento de la figura dentro de la matriz, es importante resaltar, que en el eje y, solo se genera el movimiento de forma descendente.

Dentro del switch que se encuentra en la función, se le asignan un movimiento a cada lectura de voltaje.

Caso 4: esta configuración esta hecha para que se baje la figura, sin embargo, como se tiene un desplazamiento predeterminado para que la figura baja de acuerdo con la velocidad indicada, no se utiliza

Caso 1 : cuando se detecta un 1 en el eje Y del puerto A1, se genera la rotación de la figura en intervalos de 90°

Caso 2: Esta configurado para que genere el movimiento hacia la izquierda de la matriz, esto ocurre cuando se detecta un 0 en la lectura del puerto A0

Caso 3: Esta configurado para que genere el movimiento hacia la derecha de la matriz, esto ocurre cuando se detecta un 1 en la lectura del puerto A0 Codigo: void bajaf() { movimiento=4;} void movimiento_fig(){ reada(); command.printf("vy = %f \n", vy); command.printf("vx = %f \n", vx); command.printf("cc = %f \n", cambio.read()); if(vy<0.2) movimiento=1;

if(vy>0.8) movimiento=4;

if(vx<0.2) movimiento=3;

if(vx>0.80) movimiento=2; command.printf("movimiento = %d \n", movimiento);

switch (movimiento){

case 4: cont++; printf("%f", joy.read()); if(cont>8)cont=8; break;

case 1: if( (matrix_temp[1]==2) || (matrix_temp[1]==1)|| (matrix_temp[1]==3)) columna; rotacion++; if(rotacion>4) rotacion=1; printf("%f", joy1.read()); break;

case 2: if((matrix_temp[2]==7 || matrix_temp[3]==7)||(matrix_temp[2]==3 && matrix_temp[3]==6)) { command.printf("a"); columna=6; } else if((matrix_temp[1]==2 && matrix_temp[2]==2 && matrix_temp[3]==2)){ command.printf("b"); columna=8; } else if (columna<7){ command.printf("c"); columna++; } printf("%f", joy1.read()); break;

case 3: columna; if(columna<1) columna=1; printf("%f", joy.read()); break;

}

Función print_matrix : Esta función permite la actualización de la información contenida en las filas y columnas de la matriz general, por lo cual, al tomar al tener definida la información que debe mostrarse, se envía para que esta sea inmutable, y por medio del puerto serial, se envía la información para que se habilite el ingreso de una nueva figura.

Codigo: void print_matrix(uint8_t *temp){ matrix_temp1[0]=(matrix_temp[0]+ matrix_act[cont-3]); matrix_temp1[1]=(matrix_temp[1]+ matrix_act[cont-2]); matrix_temp1[2]=(matrix_temp[2]+ matrix_act[cont-1]); matrix_temp1[3]=(matrix_temp[3]+ matrix_act[cont]); sendSPI(cont-3,matrix_temp1[0]); sendSPI(cont-2,matrix_temp1[1]); sendSPI(cont-1,matrix_temp1[2]); sendSPI(cont ,matrix_temp1[3]); pasa de i+2 a i+1 wait_ms(VEL);

Función crear_fig: Por medio de un switch se genera la validación del tipo de figura y de acuerdo al mismo, se indican los registros necesarios para generar la visualización de la figura, haciendo uso de la matriz principal definida en la librería figuras.h

Esta visualización se puede generar por medio del arreglo definido, ya que indicando el numero de la posición del arreglo, se forman las figuras.

Para este caso, las figuras definidas para el Tetris son las siguientes

De igual forma, para genera rotación de las figuras, también se indica la posición dentro del arreglo en el caso de las figuras que lo requieren, por lo cual, no es necesario generar la rotación.

Codigo: switch (type_fig){ case 1: if(columna>7) columna=7; copy_matrix(5,1,1,PLANT,columna); break;

case 2: if(rotacion==1 || rotacion==3) copy_matrix(0,0,0,PLANT,columna); if(rotacion==2 || rotacion==4) copy_matrix(5,5,2,PLANT,columna); break;

case 3: if(rotacion==1) copy_matrix(0,0,1,PLANT,columna); if(rotacion==2) copy_matrix(5,2,0,PLANT,columna); if(rotacion==3) copy_matrix(1,3,3,PLANT,columna); if(rotacion==4) copy_matrix(5,6,2,PLANT,columna); break;

case 4: if(rotacion==1) copy_matrix(5,3,2,PLANT,columna); if(rotacion==2) copy_matrix(0,1,0,PLANT,columna); if(rotacion==3) copy_matrix(5,2,3,PLANT,columna); if(rotacion==4) copy_matrix(3,1,3,PLANT,columna); break;

case 5: if(rotacion==1 || rotacion==3) copy_matrix(5,4,1,PLANT,columna); if(rotacion==2 || rotacion==4) copy_matrix(0,1,3,PLANT,columna); break;

Función figuras: Para generar el envió de una figura en forma automática, se utiliza la función rand, la cual al indica un numero aleatorio entre 1 y 4 , el resultado, es el numero de la figura que se va a enviar

Codigo: figura= rand() % 5+1; rotacion= rand() % 4+1; columna= 4;

Función elimina_linea : esta función se encarga de generar un barrio por toda la función, de tal forma, que cuando detecta que todos los registros en alguna fila están ocupados (todos los led están encendidos), elimina esa fila.

Codigo: for(uint8_t i=0;i<9;i++){ if(matrix_act[i]==255){ for(uint8_t a=i;a>=1;a){ sendSPI(a,matrix_act[a-1]); matrix_act[a]=matrix_act[a-1];

Integracion de funciones: el programa se inicializa con la lectura de la trama, con el fin de que la primera figura aparezca en do se indique según la columna desingnada, después de esto, se limpian los otros posibles registros que estén contenidos dentro de la matriz y se procede a entrar en un bucle.

Dentro de este bucle, se genera el desplazamiento vertical de la figura, por medio de la función buscar_fila, hace un barrido para identificar los espacios disponibles en la matriz, a medida que la figura baja, esta se puede mover o rotar, según indique el usuario.

Para que las filas figuras sigan bajando , se utiliza la variable cont =0 la cual se encarga de monitorear las filas que se están utilizando, de tal manera, que cuando el registro es igual a 8, no permite que bajen mas figuras, y por lo contario, reincializa el programa.

En caso de que se complete una fila, esta se elimina y el programa ingresa dentro de otro bucle , en el cual, se seguirá ejecutando el programa eliminado las filas que han sido completadas, hasta que el usuario acumule las figuras de tal forma que estas ocupen de alguna forma todas las filas de la matriz.

Codigo: int main() { bajar.attach(&bajaf, 0.1); init_display(); borrar(); while(1){ figuras(); buscar_fila(); cont=0; elimina_linea(); while (cont<fila){ movimiento_fig(); crear_fig(figura,rotacion,columna); buscar_fila(); print_matrix(matrix_temp); } guardar(); }

Forma de Juego.

Las figuras aparecen en la parte superior de la matriz, las cuales se pueden desplazar a la derecha o a la izquierda, de acuerdo al movimiento que genere el usuario en el joystick.

Para rotar la figura, el usuario debe colocar la palanca hacia arriba, la figura rota en intervalos de 90ª , hasta completar 360ª, para parar , simplemente, el usuario debe bajar la palanca.

Las figuras deben apilarse de tal forma, que se complete una fila, al completarse, esta será eliminada, y seguirán cayendo más figuras, cada vez mas rápido.

El juego termina cuando la figura alcanza la fila superior de la matriz led, después de lo cual, se reinicia la matriz, para que el juego vuelva a comenzar


All wikipages