Bienvenidos al último tutorial sobre los recursos básicos de la Ophyra. En este, se continuará aplicando la pantalla TFT-ST7735 y se complementará con la utilización de una memoria uSD.
Proyecto a realizar: Se realizará un ejemplo en el que tras leer la memoria uSD, se extraerá una cadena de caracteres de un archivo “.txt” y luego se mostrará en la pantalla TFT-ST7735. De igual manera, se obtendrá una imagen de la misma memoria para también visualizarla en la pantalla.
IMPORTANTE
Es necesario descargarse la librería para poder controlar la pantalla TFT-ST7735 de Ophyra. Haga click aquí para descargarlo.
Configurando el hardware
Una vez ya creado nuestro proyecto (véase el tutorial preliminar de Crear un Proyecto para Ophyra), el siguiente paso es activar los recursos a utilizar.
Paso 1. Comenzaremos con activar los recursos necesarios para la pantalla TFT-ST7735. Para realizarlo, puede seguir los Pasos 1-4 de la primera parte de este tutorial 10. Manejo de la pantalla TFT-ST7735.
Paso 2. Ahora pasaremos a activar los pines del puerto SD. En la sección de la izquierda, entramos a Connectivity y activaremos el recurso SDIO. Al hacerle click, se abrirá una sección para determinar el modo en que se trabajará, y en nuestro caso se selecciona SD 4 bits Wide bus. En el diagrama del chip del lado derecho se podrán observar todos los nuevos pines que se han activado.
Para corroborar que los pines sean correctos a los que le corresponde a la tarjeta Ophyra, podemos abrir el Manual de Ophyra y en la sección “6. Bus SDIO para la Micro SD” se muestra una tabla con los pine que le deben corresponder.
Nótese que falta la activación del pin PC6 (SD_Detect), pero para efectos de este ejemplo, no se requerirá.
Paso 3. Ahora pasamos a revisar la configuración de nuestro recurso del SDIO. En la lista de parámetros a configurar, podemos observar los siguientes:
Únicamente se hará mención de dos de los parámetros mostraos en la imagen anterior.
- Clock transition on which the bit capture is made – Aquí se determina si las capturas de cada bit se harán en los flancos de subida o bajada del reloj. Nosotros utilizaremos el valor por defecto, que es el flanco de subida (Rising transition).
- SDIOCLK clock divide factor – Este número será el divisor que determina la frecuencia del reloj para el SDIO. Se tiene la fórmula
SDIO_CK = SDIOCLK / [CLKDIV + 2]
. Debido a la arquitectura del ARM, el SDIOCLK siempre va conectado a un reloj de 48 MHZ, y si al tener un valor del CLKDIV en cero, entonces la frecuencia máxima posible sería 24 MHz (pues se divide sobre 2). Al colocar el valor máximo posible en el CLKDIV que es 255, tendríamos entonces una división de 257, dando como resultado una frecuencia mínima de aproximadamente 187 KHz. En nuestro caso, utilizaremos un valor de 40, para que al final tengamos una velocidad poco arriba de 1 MHz.
Paso 4. Ya hemos establecido el protocolo de comunicación para la SD. Sin embargo, aún falta activar el módulo del FATFS que nos permitirá gestionar archivos para así poder leer el archivo de texto y la imágen de la memoria SD. Para ello, en el menú de la izquierda abriremos la categoría de Middleware y hacemos click en el módulo FATFS. Ahí podremos encontrar cuatro opciones, las cuales dos de ellas no están disponibles (SRAM Externo y Disco USB), ya que éstos sólo estarían disponibles si activamos las herramientas con sus pines. De las dos opciones disponibles, tenemos la de SD Card, y esta opción únicamente está activa gracias a que activamos su herramienta en el Paso 2.
Activaremos ese módulo de SD Card y observaremos que la lista de parámetros de configuración es bastante extensa. Detallar los parámetros está fuera del alcance de este tutorial, pero podemos decir de manera general que estos parámetros permiten configurar la forma en que se lee la memoria SD y se puede cambiar el comportamiento de algunas de las funciones del módulo.
Paso 5. Ahora es momento de generar nuestro código.
ADVERTENCIA
Si durante la creación de tu proyecto no llegaste a configurar el reloj de la tarjeta o a configurar los detalles del proyecto respecto a la generación del código, aún estás a tiempo.
Para sabér cómo hacer esas configuraciones, dirígase al tutorial preliminar de Crear un Proyecto para Ophyra y siga los pasos en Anexo 1: Configurar el reloj de la Ophyra y Anexo 2: Configurar los detalles el proyecto.
Para generar el código, basta con hacer clic en el botón de Guardar que se encuentra en la barra de herramientas en la parte superior.
NOTA
Al compilar este proyecto, es muy posible que salga una advertencia, como se muestra en la siguiente imagen. El parámetro que indica que hace falta de configurar no es necesario para lo que necesitamos en nuestro proyecto, replica rolex sea dweller así que podemos continuar sin problemas picándole al botón Yes.
Agregando la librería de la TFT de Ophyra
Antes de empezar a escribir nuestro código, deberemos agregar la librería TFT_Ophyra a nuestro proyecto.
Paso 6. Nos dirigiremos al explorador de proyectos y desplegaremos la carpeta Core para poder visualizar las carpetas Inc y Src.
Ahora, en tu computadora deberás ubicar el archivo de la librería TFT_Ophyra que has descargado y luego hay que descomprimirla. Dentro, en la carpeta SRC encontrarás dos archivos: TFT_Ophyra.c y libST7735_Driver.a. Copia estos archivos directamente sobre la carpeta Src de tu proyecto, haciendo click derecho sobre éste y seleccionando la opción “Pegar”.
Ahora en la carpeta INC de las carpetas descomprimidas, encontrarás tres archivos: TFT_Ophyra.h, ST7735_Driver.h y Intesc_Std_Types.h. Hay que copiar también estos archivos y los pegaremos esta vez en la carpeta Inc de nuestro proyecto.
Paso 7. Ahora debemos configurar las propiedades del proyecto para que se incluyan los archivos de la librería y la compilación se realice correctamente.
Abriremos las propiedades del proyecto y entraremos a la ubicación C/C++ Build → Settings → Tool Settings → MGU GCC Linker → Libraries. Dentro, observaremos dos campos de listas: una llamada “Libraries” y la otra llamada “Library search path”.
Agregaremos un elemento a la lista en “Libraries”, escribiremos “:libST7735_Driver.a” (es el nombre del archivo de nuestra librería) y presionamos el botón OK para guardar. Ahora, en la lista “Library search path” agregaremos un elemento con el texto “${workspace_loc:/${ProjName}/Core/Src}” (es la dirección donde se encuentra nuestro archivo de la librería).
Al haber agregado ambos elementos en sus respectivas listas, cerraremos a ventana de propiedades al presionar el botón Apply and Close.
Realizando el Proyecto
Paso 8. Dentro de nuestro archivo main.c necesitamos incluir los archivos de la librería de la TFT.
/* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "fatfs.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "Intesc_Stdr_Types.h" #include "ST7735_Driver.h" #include "TFT_Ophyra.h" #include "stdio.h" /* USER CODE END Includes */
Paso 9. Para poder utilizar las imágenes BMP, deberemos habilitar sus recursos en la librería de la TFT. Para ello en el archivo TFT_Ophyra.h habremos de quitar el comentario al renglón donde está escrito “define __TFT_BMP”, tal como se muestra en el siguiente código.
/*www.intesc.mx * Autor: Fernando Q. * Created on: 07/12/2017 */ #ifndef TFT_OPHYRA_H_ #define TFT_OPHYRA_H_ // DESCOMENTE LA SIGUIENTE L�NEA SI SE USAR� LA SD Y EL DESPLIEGUE DE IMAGENES. #define __TFT_BMP /* * Este archivo realiza el mapeo de los pines de la pantalla TFT conectada a la tarjeta Ophyra. * * ********************* Instrucciones para incluir la libreria en el proyecto ***************************
Paso 10. Ahora es momento de aprender a utilizar la última función disponible en nuestra librería de la pantalla TFT.
ST7735_tenErrCode TFT_PrintImgBMP(U8 u8XCursor, U8 u8YCursor, TCHAR*uSD_FileName)
Despliega una imagen en formato BMP de 8 ó 24 bits. La imagen debe ser leída desde la memoria uSD.
Argumentos: U8 u8XCursor
y U8 u8YCursor
indican las coordenadas del inicio de la imágen (esquina superior izquierda). TCHAR*uSD_FileName
es el nombre de la imágen a leer, y debe ser escrito entre comillas.
Nota: Se debe especificar la dirección exacta de la imágen dentro de la memoria uSD. Preferentemente, las imágenes deberían estar en la raíz de la memoria. La imagen no debe exceder las dimensiones de la pantalla o se desplegará un error.
Ahora, el código que escribiremos es:
/* Initialize all configured peripherals */ MX_GPIO_Init(); MX_SDIO_SD_Init(); MX_SPI1_Init(); MX_FATFS_Init(); /* USER CODE BEGIN 2 */ // Sección 1 U32 ColorLetra = 0x00000000; U32 ColorFondo = 0xFFFFFFF; // Sección 2 FATFS fatfs; FIL fil; UINT testBytes; CHAR bufer[50]; // Sección 3 TFT_Init(0); TFT_BackLight(1); TFT_ClearDisplay(ColorFondo); // Sección 4 f_mount(&fatfs, "", 0); // Sección 5 f_open(&fil, "prueba.txt", FA_READ); f_read(&fil, bufer, 30, &testBytes); TFT_PrintStr(10, 110, bufer, ColorLetra, ColorFondo); // Sección 6 TFT_PrintImgBMP(30, 0, "logo.bmp"); /* USER CODE END 2 */
A continuación se explicará el código según cada sección.
La sección 1 define las variables a utilizar para los colores del fondo y la letra del texto que imprimiremos. Para este tutorial, pasaremos a un fondo blanco con letras negras.
La sección 2 define las variables que necesitamos para poder leer nuestra memoria. La variable tipo FATFS
es una estructura que guardará la información general para leer el driver (en nuestro caso la uSD). La variable tipo FIL
es una estructura que almacena información respecto al archivo actualmente abierto. La variable testBytes
se utiliza para guardar el número de bytes que se leen tras cada lectura de la memoria. Finalmente, en el bufer
se almacenará la cadena de caracteres leída de la uSD para posteriormente imprimirlo.
En la sección 3 se realiza la inicialización de la TFT, poniendo la pantalla completamente en blanco.
En la sección 4 encontramos una nueva función. Ésta proviene de la librería FATFS y deberá ser siempre la primera en utilizarse.
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt)
Se encarga de montar la memoria (la uSD) e inicializarla.
Argumentos: Como primer argumento se deberá hacer referencia a nuestra estructura donde se guardará la información del driver (en nuestro caso es &fatfs
. El argumento const TCHAR* path
refiere a la dirección en la que se abrirá la memoria. Ya que nosotros comenzamos en la raíz, únicamente ponemos dos veces las dobles comillas, indicando una cadena vacía. Finalmente, BYTE opt
es un byte en que se puede ponerun 1 ó 0 para indicar si se quiere que se fuerce el montado de la memoria en ese instante o que se haga en el momento que se haga la primera lectura (en nuestro caso elegimos la segunda opción).
La sección 5 presenta dos funciones más de la librería FATFS.
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode)
Permite abrir un archivo.
Argumentos: FIL* fp
es un puntero a la estructura donde guardaremos la información de nuestro archivo (en nuestro caso &fil
). Como segundo argumento, tenemos el nombre del archivo que queremos leer (nuestro archivo se llamará “prueba.txt”). El argumento BYTE mode
indica el modo en que se abrirá el archivo. La lista de opciones lo podrás encontrar en la página http://elm-chan.org/fsw/ff/doc/open.html. En nuestro caso, al querer únicamente leer el archivo de texto, utilizaremos el modo FA_READ
.
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br)
Es la función encargada de leer el archivo abierto.
Argumentos: FIL* fp
es un puntero a la estructura donde guardaremos la información de nuestro archivo (en nuestro caso &fil
). Como segundo argumento, tenemos un puntero a nuestro arreglo donde almacenaremos la cadena de caracteres que leeremos. UINT btr
indica el número de bytes a leer. UINT* br
es un puntero a una variable que almacenará la cantidad de bytes realmente leídos.
Al final de esta sección, se imprime en la parte inferior de la pantalla el texto que hayamos escrito en nuestro archivo “prueba.txt”.
Finalmente, en la sección 6 tenemos nuestra función de la librería TFT que imprimirá la imagen llamada “logo.bmp”.
Paso final – Cargar el programa a la Ophyra
Ahora, falta programar nuestro código a la tarjeta Ophyra. Las instrucciones se encuentran en el tutorial del Paso final – Cargar el programa a la Ophyra.
Resultados
Para el ejemplo, es necesario introducir una memoria uSD en la ranura y que contenga los dos archivos en su raíz: “prueba.txt” y “logo.bmp” (haga click aquí para descargar los archivos).
Una vez con la memoria uSD esté introducida en la ranura, al momento de iniciar la tarjeta y que el programa esté corriendo, inmediatamente se puede observar que la pantalla se pone completamente en blanco y se logran visualizar tanto la imagen como el texto.
Conclusiones
En este tutorial hemos aprendido a utilizar una herramienta más de la librería TFT: la impresión de imágenes. Para ello, hemos aprendido a configurar el driver de la uSD incorporada en la tarjeta Ophyra. Ahora puedes continuar con otros proyectos, tal como un visualizador de archivos, utilizando la TFT y los botones de la tarjeta para navegar entre las carpetas de la memoria uSD.
Con esto hemos concluido los tutoriales sobre los recursos básicos de la Ophyra. Esperemos que con esto puedas realizar muchos proyectos más al aprovechar todos los recursos que ofrece nuestra tarjeta Ophyra.