Bienvenidos al noveno tutorial sobre la utilización de los recursos básicos de nuestra tarjeta Ophyra. En este segmento se mostrará como configurar la tarjeta para poder leer la memoria CM24C32-EEPROM. Esta memoria está integrada en la tarjeta y utiliza el mismo puerto serial I2C que en el tutorial pasado, 8. Lectura del snesor MPU6050 (Acelerómetro y Giroscopio).
Proyecto a realizar: Se escribirá una serie de diez datos en diferentes localidades de la memoria y posteriormente se leerán dichas localidades y se enviarán los datos al puerto RS232.
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. Ya que necesitamos utilizar la comunicación RS232 para desplegar los datos obtenidos de la memoria, necesitamos activar nuestro USART. Para activarlo, se hará lo mismo que en el tutorial 7. Comunicación RS232:
- Activar el USART3 en modo asíncrono
- Configurar los parámetros del USART3 (el baudaje, largo de palabra, etc).
- Verificar que los pines activados sean el PB10 (USART3_TX) y PB11 (USART3_RX)
Paso 2. Ya que el primer puerto del I2C está conectado tanto a la memoria EEPROM como al sensor MPU6050, activaremos el puerto I2C de la misma manera que en el tutorial pasado (8. Lectura del snesor MPU6050 (Acelerómetro y Giroscopio).
- Activar el I2C en modo I2C.
- Configurar los parámetros del I2C (Modo estándar a 100KHz, entre otros parámetros).
- Verificar que los pines activados sean el PB6 (I2C1_SCL) y el PB7 (I2C1_SDA).
Paso 3. 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. La interfaz cambiará y comenzará a cargar el código, así como se muestra en la siguiente imagen.
Realizando el programa
Paso 4. Ya que volveremos a utilizar la comunicación RS232 y manejaremos cadenas de caracteres, necesitamos volver a incluir nuestras librerías.
/* Includes ------------------------------------------------------------------*/ #include "main.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include <stdio.h> #include <string.h> /* USER CODE END Includes */
Paso 5. Para no tener que estar escribiendo la dirección que le corresponde a la memoria CM24C32-EEPROM, le haremos una definición, tal como se muestra a continuación:
/* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ #define ADDMEMORY 0x50 << 1 /* USER CODE END PD */
Se le ha escrito la dirección como 0x50 << 1
pues se necesita recorrer un bit a la izquierda (pasando de 0x50 pasa a 0xA0). Esto es necesario debido a que en el protocolo I2C, el bit menos significativo del ID se utiliza como un comando de escritura y lectura. Este bit es manipulado por el dispositivo maestro, poniéndolo en 1 cuando se desea leer información y en 0 cuando se desea escribir en el dispositivo esclavo. Cabe notar que esta gestión se realiza de manera automática por las instrucciones en C que comanda el compotamiento del puerto I2C.
Paso 6. Declaramos nuestras variables a utilizar.
/* Initialize all configured peripherals */ MX_GPIO_Init(); MX_I2C1_Init(); MX_USART3_UART_Init(); /* USER CODE BEGIN 2 */ uint8_t datos[10]; uint8_t datos_in[10]; char bufer[30]; uint8_t numero = 100; /* USER CODE END 2 */
Paso 7. En la sección previa al while, realizaremos la generación de los 10 números mediante un ciclo for. La secuencia de números generada es: 100, 98, 96, 94, 92, 90, 88, 86, 84, 82. Estos números son almacenados temporalmente en el arreglo llamado datos[10]
. Cabe mencionar que estos números son generados arbitrariamente para cuestiones demostrativas y no tienen ningún significado importante.
/* Infinite loop */ /* USER CODE BEGIN WHILE */ for (int i = 0; i <= 9; i++) { datos[i] = numero - (i * 2); } HAL_I2C_Mem_Write(&hi2c1, ADDMEMORY, 0x00, 32, datos, 10, 100); while (1) {
Después de la generación de los números, se observa una nueva función:
HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
Esta función se encarga de enviar los datos hacia la memoria EEPROM y los escribe comenzando desde primer espacio de memoria indicada.
Podemos observar que la instrucción requiere de 7 parámetros:
- Puntero a la variable de control del puerto I2C con el que se está trabajando.
- Es la ID o dirección del dispositivo esclavo (en nuestro caso, la memoria EEPROM).
- Especifica la dirección de espacio de memoria a partir de la cual se comienzan a guardar todos los datos.
- Tamaño de la palabra (en bits) de la memoria EEPROM.
- Bufer o arreglo de datos a escribir sobre la memoria.
- Cantidad de datos a escribir.
- Tiempo de espera máximo.
Paso 8. Ahora escribiremos el código dentro de nuestro bucle infinito. Esta sección leerá los datos provenientes de la memoria y los enviará al puerto USB-Serial para que posteriormente sea visualizado en una terminal serial. Para este proyecto, volveremos a utilizar la terminal serial incluida en el STM32Cube IDE.
while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ HAL_I2C_Mem_Read(&hi2c1, ADDMEMORY, 0x00, 32, datos_in, 10, 50); for (int i = 0; i <= 9; i++) { sprintf(bufer, "Datos = %d\n\r", datos_in[i]); HAL_UART_Transmit(&huart3, (uint8_t*)bufer, (uint16_t)strlen(bufer), (uint32_t)100); } } /* USER CODE END 3 */
Esta parte del código se explicará en los dos segmentos que está dividido (separado por el reglón vacío):
La primera parte se encarga de leer los 10 bytes de información ubicados en la memoria EEPROM. Para ello, se utilizó la siguiente función:
HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
Esta función requiere también de 7 parámetros:
- Puntero a la variable de control del puerto I2C con el que se está trabajando.
- Es la ID o dirección del dispositivo esclavo (en nuestro caso, la memoria EEPROM).
- Especifica la dirección de espacio de memoria a partir de la cual se comienzan a leer todos los datos.
- Tamaño de la palabra (en bits) de la memoria EEPROM.
- Bufer o arreglo de datos donde se guardarán los datos leídos de la memoria.
- Cantidad de datos a leer.
- Tiempo de espera máximo.
La segunda parte envía cada dato previamente leído de la memoria hacia el puerto serial para su visualización en la terminal.
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
Necesitamos abrir la terminal del puerto serial en el STM32Cube IDE. Para ello, seguimos los mismos pasos que en el tutorial 7. Comunicación RS232 en la sección “Abriendo la terminal del puerto serial”.
Una vez abierta la terminal, podremos observar que se está escribiendo constantemente la secuencia de datos (100, 98, 96, 94, 92, 90, 88, 86, 84, 82) en secuencia. Una vez que terminó de escribir el 82, vuelve a comenzar la secuencia con el 100, y este proceso lo hará indefinidamente.
Conclusiones
Hemos configurado y programado en Ophyra la memoria M24C32-EEPROM mediante el puerto serial I2C. Así mismo, utilizamos de nuevo el puerto serial RS232 para poder visualizar la información proveniente de la memoria en la terminal del STM32Cube IDE. Ahora puedes continuar con otros ejercicios más complicados, como la escritura de datos flotantes y su posterior recuperación.
Para seguir aprendiendo más sobre los recursos básicos de la Ophyra, te recomendamos seguir con el siguiente tutorial: 10. Manejo de la pantalla TFT-ST7735.