1_entrega
TETRIS HACIENDO USO DEL NUCLEO STM32
Abstract: The following text describes the operation of the first phase of the code for a game of Tetris using the STM32411RE module is detailed as a processing module. For the visualization of the game, an 8X8 LED matrix connected to a MAX7219 was used as a multiplexing system under the language of C ++ programming.
Resumen: A continuacion se detalla el funcionamiento de la primera fase del codigo para un juego de tetris usando el modulo STM32411RE, como modulo de procesamiento, para la visulaizaion del juego se uso una matriz LED 8X8 conectada a un MAX7219 como sistema de multiplexacion bajo el lenguaje de programacion C++.
Keywords: Sistemas Embebidos, STM32, C++, Tetris, Matriz LED, MAX7219

SMT32411 RE https://os.mbed.com/platforms/ST-Nucleo-F411RE/

MAX7219 y matrix LED
https://www.sparkfun.com/datasheets/Components/General/COM-09622-MAX7219-MAX7221.pdf
Descripcion del protocolo SPI
El Protocolo SPI (Serial Peripherical Interface) o en español Interfaz Periferica Serial es un protocolo síncrono que trabaja de modo full dúplex para recibir y transmitir información, permitiendo que los dos dispositivos pueden comunicarse entre sí al mismo tiempo utilizando canales diferentes o líneas diferentes en el mismo cable. Al ser un protocolo síncrono el sistema cuenta con una línea adicional a la de datos encargada de llevar el proceso de sincronismo.
Dentro de este protocolo se define un maestro que será aquel dispositivo encargado de transmitir información a sus esclavos. Los esclavos serán aquellos dispositivos que se encarguen de recibir y enviar información al maestro. Existen cuatro líneas lógicas encargadas de realizar todo el proceso:
• MOSI (Master Out Slave In):. Línea utilizada para llevar los bits que provienen del maestro hacia el esclavo. • MISO (Master In Slave Out):. Línea utilizada para llevar los bits que provienen del esclavo hacia el maestro. • CLK (Clock):. Línea proviniente del maestro encarga de enviar la señal de reloj para sincronizar los dispositivos. • SS (Slave Select):. Línea encargada de seleccionar y a su vez, habilitar un esclavo.
Descripcion de la conexion
Para poder usar el codigo primero que todo es necesario realizar las correctas conexciones entre el Nucleo STM32 y la matriz led, debemos aseguranos de conectar el PIN MOSI, el Habilitador (CS), y el clock de la siguiente manera

Conexion al MAX7219

Conexion al nucleo STM32
Descripcion del programa
El programa "Tetris_PC"cuenta con dos partes un programa principal "tetris_pc.cpp", que contiene y hace uso de todas las funciones que se usaran para el funcionamiento del programa y adiconal a este se encuentra un archivo de encabezado "piezas. h" que en el cual se encuentran todas las figuras que se utilizan en el juego, como se muestra acontinuacion:

Descripcion del Codigo
Como se mensiono anteriormente el programa cuenta con una cabezera en la cual se encuentran configuradas cada una de las piezas que se mostraran sobre la matriz LED al ser llamadas por el programa principal de maera similar a para una figura tipo L, definida por un vector de tamaño 8, con tres posiciones principales que almacenan la forma de la pieza
Encabezado
Encabezado piezas.h
#ifndef PIEZAS_H
#define PIEZAS_H
#include "mbed.h"
//FORMA DE LA PIEZA
uint16_t PZA_LD[8]={0b0010000000,
0b1110000000,
0b0000000000,
0,0,0,0,0};
#endif // PIEZAS_H
Nota: Cabe destacar que para el funcionamiento de la matriz led y por facilidad para el majeno de bits la figura siempre se desplazara de izquierda a derecha.
Programa Principal
Esta seccion encontraremos la descripcion del programa principal, este hace uso de un gran numero de funciones para generar la lectura de sus datos y su posterior procesamiento.
Al principio del programa encontraremos todo lo referente al llamdo de las librerias necesarias para el funcionamiento del programa adicional a ello encontraremos , el establecimiento de las conexiones seriales y la definicion de los pines para cada uno parametros del parametros del protocolo SPI.
Declaracion de Funciones
#include "mbed.h" #include "piezas.h" //#define DEBUG 1 Serial pc(USBTX,USBRX); SPI deviceM(PB_15, PB_14, PB_13); //SE DEFINE EL LED QUE ACTIVARA EL DISPOSITIVO DigitalOut ssel (PB_12);
Como lo indica su nombre la funcion principal es la mas importante del programa desde ella se iniciara la ejecucion de los demas programas, para esto hace un primer llamamiento a la fucnion de inicializar(), que al ejecutarce establecera como se comporatara el MAX7219, como el modo de trabajo y su luminosidad, posterior ha eso dentro de un while infiniro hace el llamado a la funcion de captura de datos queejecutara la captura de datos para su posterior ejecucion.
Funcion Principal
int main() {
inicializar(); // Inicializa el programa para establecer los modos de trabajo liminosidad
while(1){
captura_datos(); // Inicia la lectura de la informacion
}
}
En base a lo anterior el primer llamado de la funcion principal es a esta funcion inicializar(), que establece el modo de trabajo del MAX 7219 como se detalla acontinuacion, posterior ha eso realiza un limpieza de pantalla que evita que se mantengan led encendidos luego de reinicializar el programa.
Funcion inicializar
void inicializar(){ //INICIALIZA LA MATRIZ
sendSPI(0x0c,1);
sendSPI(0x0b,7);
sendSPI(0x09,0); //SELECCIONA EL MODO DE TRABAJO DE LA MATRIZ
sendSPI(0x0A,0x0f); //SELECCIONA LA LUMINOSIDAD DE LA MATRIZ
int i;
for (i=0;i<2;i++){
sendSPI(0x0F,1);
wait (0.5);
sendSPI(0x0f,0);
wait (0.5);
}
for (int j= 1; j<=8;j++){ // limpia la pantalla al encenderce o reiniarcea asi
//no quedan leds encendidos cuando se ejecute el programa nuevamente
sendSPI(j, 0x00); //pone cada columna y vecto en blanco al inicializar
}
}
La funcion de lectura es la más laga de todas desde aqui se capturan los datos para ser procesado, estableciendo una comunicacion serial de 38400 bauds, enviandolos a las variables de posicion (pos), figura y rotacion.
Debe Ingresar 3 datos al abrir el send string del coolterm el primero indica la posicion , luego la figura y finalmente el giro en el siguiente formato 00 00 00 en hexadecimal a 38400 bauds, estos comandos se deben ingresar dentro de el equivalente hexadecimal de '<' y '>', es decir 3C y 3E.
captura de datos
void captura_datos(){
pc.baud(38400); //Inicializa la velocidad de comunicacion
char inicio=0;
char pos= 0;
char figura= 0;
char giro= 0;
char final=0;
do{
debuging("\n Ingrese el inicio del comando. ");
inicio=pc.getc();
debuging("\n Ingrese el posicion. ");
pos=pc.getc();
debuging("\n Seleccione la Figura. ");
figura=pc.getc();
debuging("\n Seleccione la rotacion. ");
giro=pc.getc();
debuging("\n Ingrese el final del comando. ");
final=pc.getc();
if(inicio != '<'){
debuging("\n Error al inicio del comando. ");
}
if(final!= '>'){
debuging("\n Error al final del comando. ");
}
}while(inicio!= '<' || final != '>');
read(pos,figura,giro);
}
Inicializacion del Programa.
Luego de conectar al PC el Dispositivo debemos ir al icono de escritorio y abrir el programa.

Luego se debe esteblecer la velocidad de conexion del puerto. Esta debe estar en 38400 bauds y en el puerto detectado por el PC con el nucleo STM32.
luego debe hacer clic en conectar.

Se debe ir a la siguiente opcion.

Aparecera la siguiente pantalla en la cual se ingresa el comando este debe estar en el siguiente formato
comando = "3C 01 01 01 3E".

los valores 3C y 3E, indican el inicio y finalizacion del comando, cada uno de estos caracteres es equivalente a '<' y a '>', respectivamente, solo si estos son enviados al inicio y el final del programa seran capturados y ejecutados de manera correcta de lo contraio se preguntara por ellos nuevamente hasta que se envie el comando correctamente
El valor # 2 del comando selecciona una posicion entre 00-07, en la cual se desplegara la figura inicialmente.

El siguiente comando ingresa la figura tal que: :
00. L,

01. T,

02. Linea.

03. Cuadrado.

04. Z.

Los giros van el siguiente recuadro lo explica para la letra L:
00 = 0° grados.

01 =90° grados,

02 =180° grados,

03 = 270°grados,

En su segunda parte como se puede ver en el ejemplo el procesamiento de la variables anteriores con dos ciclos swicth anidados, es realizado, el primero escoje la figura y el segundo la rotacion, una vez dentro de esto swicth se realiza el llamado a la funcion desplazamiento tomando como parametros de entrada al vector de la figura extraido del encabezado y a la posicion en el que este se mostrara en la matriz
Funcion de lectura
void read(){
switch(figura){ //Este switch escoje la figura con que trabajaar
case 0: // L
switch(giro){ //Este switch rota la figura a trabajar
case 0:
desplazar(PZA_LD,pos); //LLAMA A LA FUNCION DESPLAZAMIENTO Y PONE LA POSICION
case 1:
desplazar(PZA_LDN,pos);
break;
case 2:
desplazar(PZA_LDO,pos);
break;
case 3:
desplazar(PZA_LDD, pos);
break;
}
break;
}
}
Una vez capturados los datos anteriores la funcion de desplazamiento posee un vector del mismo tamaño de la pieza capturada y es inicializado en ceros cada vez que es llamado, la figura es reubicada en base a la posicion deseada mediante el otro dato capturado por la funcion aqui la variable i inicializa desde que i = posicion ingresada hasta que cubre las tres posiciones principales que sobre la figura para luego de organizada ser llevada a la matriz de captura.
Funcion de desplazamiento
void desplazar(uint16_t* datos, char des){ // tomar la figura y la desplaza segun la posicion ingresada inicialmente
uint16_t desplazamiento[8]={0}; // Inicia un vector auxiliar con solo Ceros
int j= 0;
for(int i=des; i<(des+3);i++){ // Inicia un vector auxiliar con solo Ceros
desplazamiento[i]=datos[j]; // Alamcena los nuevos datos tomados en el vector
j++;
}
captura_matriz(desplazamiento); //Envia el Vector desplazado la funcion de captura de matriz
}
La matriz de captura es la encargada de memorizar y de realizar la impresion de los datos que ejecutara el programa. cuenta con 2 ciclos while que permiten que se ejecute el codigo haste que cierto parametro no se cumpla, el pimer ciclo while, realizar el corrimiento de los bits del vector capturado hasta la parte inferior de la matriz para luego ser capturados en la memoria, el segundo ciclo while imprime a cada "columna" el corrimento del vector, e l programa cuenta con un sistema que le permite identifcar la colicion con otra figura previamente enviada haciendo uso de la operacion and, mientras recorre el vector el resultado de esta siempre sera 0 hasta que finalemente vale 1 al chocar con otro objeto y luego ser nuevamente almacenado en la memoria todos los valores del la posicion del corrimiento en la memoria.
Funcion de captura de matriz
// Toma el vector reorganizado , lo imprime y lo almacena
void captura_matriz(uint16_t* imprimir){
int i=0; // inicia el contador i en 0
int enable=1;
while(i <8 && enable){ //se encarga de desplazar los bits dentro del vector
int j=1; // inicia el contador j en 1
while(j<=8){ //se encarga de seleccionar que posicion del vector imprimira
sendSPI(j, memoria[j-1]|(imprimir[j-1]>>i)); //Imprime el resultado de aplicar OR a la memoria y al desplamamiento de imprimir
//wait(0.1); // Activar este wait para pruebas de desplazamiento y captura de los datos
if(i==7 || (memoria[j-1]&(imprimir[j-1]>>i+1))!=0){ //Detiene el desplazamiento cuando los bits tocan fondo,
enable=0;// desabilitador del ciclo while
for(int k=0; k<8;k++){ // Almacena todos lo datos del vector en la posicion que corrimiento en la memoria
memoria[k]= memoria[k]|(imprimir[k]>>i);
}
}
j++;
}
wait(0.3); // espera para tomar el otro valor de lectura
i++;
}
}
Nota: cada vez que se requiera enviar una figura debe enviarce un nuevo comando desde el coolterm
Please log in to post comments.






