Saltar a contenido

6. Versión 3: RGB light

Ya tenemos una librería que nos permite tener botones que funcionan autónomamente mediante FSM. De ella hemos creado un botón que nos permitirá encender y apagar el juego Simone. Además, hemos creado una librería que nos permite crear teclados matriciales, también gestionados mediante FSM. De esta última, hemos creado un teclado que permitirá al jugador introducir la secuencia de colores en cada turno.

Bibliografía

  1. "Fundamentos teóricos de sistemas basados en microcontrolador STM32” 1

  2. Datasheet "STM32F446xC/E” 2

  3. Reference manual "RM0390. STM32F446xx advanced Arm-based 32-bit MCUs’ 3

En este capítulo vamos a crear una librería que nos permita mostrar un LED RGB donde cada color estará controlado por una señal PWM. Este elemento que llamaremos RGB light nos permitirá mostrar (i) los colores de la secuencia que tiene que replicar el usuario, y (ii) dar feedback visual al jugador cada vez que pulse una tecla.

Como ya hicimos en las versiones anteriores, (i) vamos a implementar la parte portable PORT dependiente del HW para comunicarnos con el LED RGB, y lo probaremos con un test unitario. (ii) Después, vamos a crear la lógica de la FSM para gestionar las secuencias del juego con los distintos colores (la parte COMMON), y lo probaremos con un test unitario. (iii) Por último, montaremos el HW y probaremos el funcionamiento del LED RGB con un programa de ejemplo.

Cuando lea esta introducción conviene que lea y entienda el capítulo "Circuito de reloj” del libro 1, prestando especial atención al ejemplo proporcionado sobre PWM.

Cada uno de los LED (R, G, y B) del LED estará conectado a una GPIO del STM32F446RE. Los tres LED están controlados por el mismo temporizador en modo PWM, pero cada uno con un canal de dicho temporizador. La señal PWM es una señal cuadrada que tiene un periodo fijo y un ciclo de trabajo variable. Si el ciclo de trabajo es del 100\%, el LED estará a máxima intensidad, y si es del 0\%, el LED estará apagado. Las características a destacar del sistema de la Versión 3 se muestran en la siguiente tabla.

Parámetro Valor
Pin LED rojo PB6
Pin LED verde PB8
Pin LED azul PB9
Modo Alternativo
Pull up/ down Sin pull
Temporizador (para todos los colores) TIM4
Canal LED rojo (ver la tabla de Función Alternativa en el datasheet2)
Canal LED verde (ver la tabla de Función Alternativa en el datasheet2)
Canal LED azul (ver la tabla de Función Alternativa en el datasheet2)
Modo PWM Modo PWM 1
Prescaler (Calcular para frecuencia de 50 Hz)
Periodo (Calcular para frecuencia de 50 Hz)
Ciclo de trabajo LED rojo (variable, depende del color a mostrar)
Ciclo de trabajo LED verde (variable, depende del color a mostrar)
Ciclo de trabajo LED azul (variable, depende del color a mostrar)

Un color se representa en el LED RGB mediante la combinación de los tres colores básicos: rojo, verde y azul. La combinación de los tres colores básicos en diferentes proporciones nos permite obtener una amplia gama de colores. La intensidad la controla el ciclo de trabajo (canal del temporizador), pero la frecuencia para los tres colores será la misma. La frecuencia de la señal PWM será de \(50 Hz\), valor lo suficientemente alto para que no se perciba el parpadeo de los LED. Nuestro ojo integrará esos trenes de pulsos y lo veremos como un color determinado. Si se cambia el ciclo de trabajo, estaremos controlando la intensidad de cada LED, y por tanto el color mostrado.

¿Cuándo cambiaremos los valores del ciclo de trabajo? Pues depende de la intensidad calculada de forma aleatoria según el nivel de dificultad del juego. Cuanto más difícil sea el nivel, más parecidos serán los colores (menor intensidad), y por tanto más difícil será para el usuario distinguirlos.

La tabla de colores muestra los colores que se usarán en el juego y los valores de ciclo de trabajo asociados a cada color para máxima intensidad en tanto por ciento. Los colores están definidos en la librería que se proporciona rgb_colors.c de la parte COMMON, y que mencionaremos más adelante.

Color LED rojo LED verde LED azul
Rojo \(100~\%\) \(0~\%\) \(0~\%\)
Verde \(0~\%\) \(100~\%\) \(0~\%\)
Azul \(0~\%\) \(0~\%\) \(100~\%\)
Amarillo \(37~\%\) \(37~\%\) \(0~\%\)
Turquesa \(10~\%\) \(35~\%\) \(32~\%\)
Blanco \(100~\%\) \(100~\%\) \(100~\%\)
Apagado \(0~\%\) \(0~\%\) \(0~\%\)

En la Versión 5 puedes implementar otros colores. Tienes una lista de colores en la www.downtownuplighting.com—aunque no todos se pueden mostrar en un LED RGB.

La figura muestra un ejemplo de señal PWM para un color amarillento (que no el amarillo de la tabla. Se muestran en el osciloscopio dos de los LED del RGB. En la parte superior se muestra el canal de osciloscopio para el LED rojo, y en la parte inferior el canal de osciloscopio para el LED verde. Fíjate que el periodo de la señal PWM es el mismo para los dos LED (\(20 ms\)), pero el ciclo de trabajo es distinto: \(20.8\%\) para el LED rojo y \(36.6\%\) para el LED verde.

Ejemplo de señales PWM para un color amarillento.

Igual que hemos hecho hasta ahora, estamos desarrollando una librería. Así, cada vez que se quiera añadir un LED RGB le asociaremos una FSM. Las particularidades de dónde está conectado cada nuevo LED RGB, sus características físicas, etc., son cosas específicas del HW, por lo que estarán en PORT.

Estructura de un color RGB Estructura HW LED RGB Estructura FSM del LED RGB
(a) Estructura de un color RGB, (b) Estructura del HW del LED RGB en PORT, (c) Estructura de la FSM del *RGB light* en COMMON.

Las figuras de estructuras de un color RGB, del HW y del SW muestran las estructuras que vamos a necesitar para el LED RGB.

Un color RGB se define por la estructura de la figura (a) con tres valores uint8_t que indican la intensidad de cada componente en un rango de [0, COLOR_RGB_MAX_VALUE]. Donde la etiqueta COLOR_RGB_MAX_VALUE se ha definido con un valor de 255, por lo que este será el número de niveles de intensidad que podremos representar para cada componente.

La estructura del HW del LED RGB (en PORT) se muestra en la figura (b). La estructura de la FSM (en COMMON) se muestra en la figura (c).

Preparemos el proyecto para poder añadir el LED RGB:

  1. Descarga del repositorio de la asignatura los ficheros correspondientes a la parte PORT de la librería del RGB light correspondientes a la versión V3: https://github.com/sdg2DieUpm/simone/tree/simone_v3. Solo descarga por ahora: port_rgb_light.h, stm32f4_rgb_light.h, y stm32f4_rgb_light.c y colócalos en las carpetas correspondientes. De la parte COMMON descarga solo rgb_color.h y rgb_color.c, que incluyen la definición de los colores que usaremos en el juego.

  2. Coloca cada uno donde corresponde: PORT o COMMON, en include, o src, como se explicó en el los capítulos anteriores.

  3. Verás que no compila, y es que solo se proporciona un esqueleto del código.

6.1 Colores RGB predefinidos

Antes de ponernos a programar, conviene explicar qué son los ficheros rgb_colors.h y rg_colors.c. Estos ficheros se han de colocar en la carpeta common/include y common/src respectivamente. Estos ficheros contienen los colores que se usarán en el juego. Cada color está representado por una estructura de tipo rgb_color_t que contiene tres campos: r, g, y b, que representan la intensidad de cada componente del color en un rango de [0, COLOR_RGB_MAX_VALUE]. Estos colores predefinidos son los que se muestran en la tabla.

Estos ficheros permiten definir múltiples colores de manera sencilla y reutilizable. Si deseas añadir más colores, puedes hacerlo en la Versión 5 definiendo nuevas variables de tipo rgb_color_t en el fichero rgb_colors.c y declarándolas en el fichero rgb_colors.h. También podrías cambiar el rango de intensidad modificando el valor de COLOR_RGB_MAX_VALUE para tener mayor o menor resolución en la representación de los colores.

6.2 PORT: cabeceras de la librería del RGB light

Vamos a implementar el contrato con el usuario de la parte dependiente del HW de librería del RGB light. Esta es la interfaz que vamos a proporcionar al usuario para que pueda usar la librería y añadir LEDs RGB como necesite. Vamos a portar las funciones necesarias para usar la librería, cómo no, para la placa Nucleo-STM32F446RE. Comenzaremos de nuevo por la cabecera y luego los códigos fuente. El montaje de nuestro LED RGB con la Nucleo-STM32F446RE se muestra en la figura.

Montaje del LED <span style="color: red; font-weight: bold;">R</span><span style="color: green; font-weight: bold;">G</span><span style="color: blue; font-weight: bold;">B</span> de cátodo común con la <span style="color: RoyalBlue; font-weight: bold;">Nucleo-STM32F446RE</span>.

En el mercado existen numerosos LEDs RGB. En este proyecto utilizaremos un LED de cátodo común. En este tipo de LEDs, el ánodo de cada LED está conectado a un pin del microcontrolador a través de una resistencia, y los cátodos de los tres LED están internamente conectados a un pin común que irá a tierra. Para adquirir uno, ve a la BOM).

6.2.1 Cabecera port_rgb_light.h

Esta cabecera depende del HW pero no de las particularidades del microcontrolador STM32F446RE. Vamos a seguir los siguientes pasos:

  1. Incluye todas las cabeceras necesarias según indica la API.

  2. Define (#define) el PORT_RGB_LIGHT_ID, que es un valor numérico natural que será el identificador del RGB light trasero. Si es el único RGB light del sistema, le asignaremos el 0.

  3. Escribe los prototipos de las funciones públicas que aparecen en la API del fichero port_rgb_light.h.

  4. Puede ser buen momento ahora para documentar con Doxygen.

Ya hemos acabado con el encabezado que interactúa con el HW del RGB light y que no depende del microcontrolador. Todavía dará errores al compilar. Vamos ahora a programar la cabecera que sí depende del microcontrolador stm32f4_rgb_light.h.

6.2.2 Cabecera stm32f4_rgb_light.h

Esta cabecera define los pines a los que está conectado el LED RGB de cada RGB light asociado.

  1. Incluye todas las cabeceras necesarias según indica la API.

  2. Define (#define) los valores de las GPIO de los pines de los LED rojo, verde y azul.

  3. Declara la estructura stm32f4_rgb_light_hw_t, que contiene en sus campos los puertos y pines de cada GPIO. Presta atención a la API.

  4. Declara el array de estructuras de tipo stm32f4_rgb_light_hw_t como se hizo en versiones anteriores. Este array contendrá las características de todos los LED RGB que tengamos en el sistema.

  5. Documenta todo con Doxygen.

Ya hemos acabado con el encabezado (header) que interactúa con el HW del RGB light. Todavía dará errores al compilar. Vamos ahora a implementar todas las funciones prototipadas en port_rgb_light.h.

6.3 PORT: fuente de la librería del RGB light

Vamos a portar las funciones necesarias para usar la librería del RGB light y comprobar que la parte HW está bien programada. Vamos a programar los ficheros fuente de la parte PORT, que todos estarán en el fichero stm32f4_rgb_light.c.

6.3.1 Fuentes stm32f4_rgb_light.c

Este fichero es mucho menos extenso que el de la versión anterior. La mayor complejidad está en la configuración de los canales del temporizador, pero si has leído el capítulo del libro relativo a PWM y lo has entendido, no deberías tener problema 1. Vamos a ello.

  1. Incluye las librerías necesarias, si falta alguna, según indique la API.

  2. Igual que hicimos anteriormente, define la variable global privada stm32f4_rgb_light_hw_t rgb_lights_arr[] con la configuración física de nuesto LED RGB. Se trata del array de estructuras de tipo stm32f4_rgb_light_hw_t, que representa al HW de cada RGB light que tengamos en nuestro juego.

    Asigna los valores HW del LED RGB del LED PORT_RGB_LIGHT_ID utilizando los #define de stm32f4_rgb_light.h.

  3. Codifica la función _stm32f4_rgb_light_get() de manera análoga a como se ha hecho en las versiones anteriores.

Ahora vamos a codificar las funciones más importantes de la parte PORT del RGB light, y son las que configuran el temporizador asociado al LED RGB.

  1. Codifica la función _timer_pwm_config() como indica la API. Esta función configura el temporizador que controla los ciclos de trabajo de los LED rojo, verde y azul. Para ello, apóyate en el ejemplo "timer para PWM” del libro de Fundamentos 1.

    Esta función configura un temporizador para que genere una señal PWM con una frecuencia fija y un ciclo de trabajo variable. El temporizador elegido y la frecuencia se muestra en la tabla de HW para la versión 3.

    Esta función recibe el identificador del LED RGB. Cada RGB light tendrá su propio temporizador, pero esta función será llamada para configurar todos ellos. Asegúrate de que el código se ejecuta dentro de un bloque condicional que compruebe el identificador del RGB light.

    Para saber qué fuente de reloj habilitar para el temporizador, consulta la tabla "Figure 3. STM32F446xC/E block diagram” del datasheet 2. Allí podrás ver si nuestro temporizador está conectado al APB1 o al APB2, y tenemos que habilitar el reloj en el registro RCC->APB1ENR o RCC->APB2ENR respectivamente.

    Puedes poner los valores de los registros TIMx->PSC y TIMx->ARR a mano, o usando las ecuaciones. Puedes crear un #define para la frecuencia de la señal PWM, si te es más cómodo. Si lo haces a mano, asegúrate de que los valores son correctos.

    Asegúrate de que los registro Capture Compare Enable Register (CCER) y Capture Compare Mode Register (CCMRx) están configurados correctamente. En el CCER se habilitan los canales de salida y en el CCMRx se configura el modo PWM. La x es el registro 1 o 2, dependiendo del canal que estés configurando.

    Es muy importante que la función _timer_pwm_config() se llame desde la función port_rgb_light_init(). Si no, no se podrán generar las señales PWM.

Vamos a continuar con las funciones públicas de la parte PORT del RGB light.

  1. Completa la función port_rgb_light_init() como se indica en la API.

    Configura las GPIO y el modo alternativo de los tres LED RGB. Para ello, consulta la tabla de Función Alternativa del datasheet 2.

    Asegúrate de que la función _timer_pwm_config() se llama desde esta función y que el LED RGB comienza apagado.

  2. Codifica la función port_rgb_light_set_rgb siguiendo la API.

    Esta función se encarga de configurar el ciclo de trabajo de los LED rojo, verde y azul. Lo hace con la proporción de los valores recibidos en la estructura rgb_color_t sobre el máximo valor definido en COLOR_RGB_MAX_VALUE. Si el valor recibido es 0, el LED estará apagado, deshabilitando el canal correspondiente.

    Fíjate que la función recibe el identificador del LED RGB. Asegúrate de que el código se ejecuta dentro de un bloque condicional que compruebe el identificador del RGB light.

    Sigue el siguiente flujograma para implementar la función port_rgb_light_set_rgb():

  3. Si queda algo por documentar puede ser buen momento ahora.

Ahora, compila, el código no debería tener ningún error. ¡Ya hemos acabado con la implementación de portado del LED RGB! Vamos a probarlo con el test unitario de la parte PORT.

6.4 PORT: Test unitario del RGB light

Vamos a comprobar que la parte PORT funciona correctamente pasando los test HW del código que hemos desarrollado de la librería del LED RGB antes de continuar con la FSM.

¡Importante! Los test que se proporcionan comprueban solo algunos aspectos esenciales, pero no son exhaustivos. Es responsabilidad del alumno comprobar que el sistema final funciona correctamente. image Ten a mano y revisa el capítulo "Test unitarios y ejemplos de integración” del libro de fundamentos teóricos 1.

Descarga el fichero de test HW del RGB light test_port_rgb_light.c de https://github.com/sdg2DieUpm/simone/tree/simone_v3_test. Ponlo en la carpeta test/stm32f4 de tu proyecto.

  1. Conecta la placa Nucleo-STM32 al ordenador.

  2. Pulsa sobre el icono de depuración image y selecciona image Clean and Debug sobre la plataforma que queramos depurar (stm32f446re).

  3. En el desplegable que se abre, selecciona el test test_port_rgb_light. Se compilará y se cargará en la placa.

  4. Comprueba que todos los test pasan correctamente en el texto mostrado en la terminal de depuración. Si no es así, lee los mensajes de error y corrige tu código hasta que pase todas las pruebas. Si no pasa las pruebas, no continúes con el siguiente test.

  5. Termina la depuración pulsando (image) y repite el proceso hasta que pase todos los test.

¡Ya hemos acabado con la parte PORT del RGB light! Vamos ahora a implementar la parte COMMON.

6.5 COMMON: cabecera de la FSM del RGB light

6.5.1 Consideraciones de la FSM del RGB light

Antes de empezar vamos a partir de una serie de consideraciones.

  • La FSM almacena el último color que se le ha indicado que tiene que representar y su intensidad. La intensidad se almacena en porcentaje como un un uint8_t pero ha de estar limitada a MAX_LEVEL_INTENSITY igual a \(100\) cuando se opere con ella. El color se almacena en una estructura de tipo rgb_color_t.

  • La FSM contiene un campo de estado (status) que indica si el RGB light está activo. Si el RGB light está desactivado, no se mostrará ningún color. Esto puede ser útil si, por ejemplo, tenemos más de un RGB light en el sistema y queremos desactivar alguno de ellos.

    La máquina de estados superior, la del sistema Simone, será la que indique si el RGB light está activo o no. La FSM del RGB light solo se encargará de representar los colores si está activo.

  • La FSM contiene otro flag que indica si el RGB light está en modo ocioso (idle). En este estado, el RGB light ya ha puesto un color, no se ha cambiado éste ni la intensidad, y podemos entrar en un modo de bajo consumo Sleep Mode Versión 4. En Sleep Mode, el núcleo del procesador se detiene, pero los periféricos y el sistema de reloj continúan funcionando, por eso el LED permanecerá encendido en el color que se haya quedado.

  • El flag new_color lo activa la máquina de estados de Simone cuando se ha cambiado el color a representar. La FSM del RGB light comprobará este flag para saber si tiene que cambiar el color del LED.

  • El valor de inicio de intensidad al arrancar debe ser el máximo permitido. El intensidad se da en porcentaje.

  • La FSM contiene información del identificador (ID) del RGB light. Este ID es único y gestionado por el usuario en el PORT. Ahí es donde el usuario proporciona identificadores e información HW (GPIO a la que está conectado) para todos los LED RGB del sistema.

Nuestra librería implementa la lógica de la FSM mostrada en la figura y que llamaremos fsm_rgb_light (en los ficheros .c y .h). Tiene 2 estados en los que:

  • IDLE_RGB: estado inicial de la FSM en el que espara a ser activada. Si se le activa se cambia al estado SET_COLOR. También se vuelve a este estado cuando el sistema no está activo (status es false).

  • SET_COLOR: en este estado la FSM espera a que se le haya pasado un nuevo color base y/o una intensidad nueva. Tras poner el color, se activa el flag idle y se queda en este estado. El nuevo color se corrige modificando la intensidad del color base recibido según el porcentaje de intensidad indicado; esto se hace con la función privada _correct_rgb_light_levels() que deberá implementar. Si se le desactiva el sistema, vuelve al estado IDLE_RGB.

La parte COMMON de nuestra librería trabaja con la estructura (struct) pública que se muestra en la figura (c) fsm_rgb_light_t. El tipo de esta estructura está declarada en el fichero fsm_rgb_light.h.

  1. Lo primero, descarga del repositorio de la asignatura los ficheros correspondientes a la parte COMMON de la librería del RGB light correspondientes a la versión V3: https://github.com/sdg2DieUpm/simone/tree/simone_v3. Solo descarga lo que faltaba por implementar, es decir, los ficheros fsm_rgb_light.h y fsm_rgb_light.c. Ponlos en las carpetas correspondientes de tu proyecto.

    Ahora, vamos a completar la cabecera de la FSM del RGB light, fsm_rgb_light.h.

  2. Incluye las librerías necesarias, si falta alguna, según indique la API.

  3. Ahora vamos a definir el enumerado con los nombres de los estados de la FSM. Escribe el enum FSM_RGB_LIGHT_SYSTEM con los nombres de los estados del diagrama de la .

  4. Defina los #define que se indican en la API para el máximo nivel de intensidad porcentual que se pueden manejar en el RGB light.

  5. Es buena práctica ir documentado el código a la vez que se programa.

  6. Seguidamente declararemos la estructura fsm_rgb_light_t y definimos sus campos. Es muy importante que la máquina de estados del RGB light fsm_t sea el primer campo.

    Continuamos con las declaraciones de funciones públicas de la librería. Procedamos:

  7. Escribe los prototipos de las funciones públicas que aparecen en la API del fichero fsm_rgb_light.h. Añada la función fsm_rgb_light_check_activity() que, aunque la usaremos en la siguiente versión, también será necesaria para el test de la FSM.

  8. Puede ser buen momento ahora para documentar las funciones con Doxygen.

Vamos ahora a programar el fichero fuente fsm_rgb_light.c.

6.6 COMMON: fuente de la FSM del RGB light

Vamos a proceder con la implementación de las funciones del RGB light. Deberás implementar todas las funciones públicas de las que ya has declarado el prototipo en el encabezado, y la función privada _correct_rgb_light_levels() que aparece en la API del fichero fsm_rgb_light.c. ¡Recuerda que las funciones privadas no se declaran en el .h!

  1. Lo primero que debe aparecer es la inclusión de cabeceras como indica la API.

    Ahora empezamos a codificar las funciones privadas de la FSM. Bajo la línea de /\* Private functions \*/ vamos a codificar la función _correct_rgb_light_levels().

  2. Codifica la función _correct_rgb_light_levels() que se encarga de calcular los niveles de ciclo de trabajo de cada LED rejo, verde y azul. Esta función simplemente multiplica por un valor entre [0, 1] cada uno de los componentes RGB. Esta función Ten en cuenta que el valor que almacenan no es el ciclo de trabajo entre 0 y 100, sino que quedará entre 0 y 255. ¡El ciclo de trabajo se calcula en port_rgb_light_set_rgb()!

  3. Documenta la función con Doxygen.

    Continuamos con las funciones de entrada o comprobación check_ de la FSM bajo la línea de /\* State machine input or transition functions \*/.

  4. Codifica las funciones check_active(), check_set_new_color() y, check_off() como se indica en la API.

  5. Documenta las funciones con Doxygen, encima del nombre de cada función.

    Seguiremos con las funciones de salida o actualización de la FSM do_.

  6. Codifica las funciones do_set_on(), do_set_color() y, do_set_off() como se indica en la API.

  7. Documenta las funciones con Doxygen. En este caso, igual que antes, la documentación irá en el .c, encima del nombre de cada función.

    Todavía no hemos acabado con el desarrollo, pero puedes compilar para ir depurando errores.

  8. Declara la tabla de transiciones de la FSM fsm_trans_rgb_light. Esto eliminará muchos errores de compilación.

  9. Completa la función de inicialización de la FSM fsm_rgb_light_init() como se indica en la API. En esta función se inicializan los campos de la estructura de la FSM, y se llama a la función fsm_init() para inicializar la máquina de estados. También se llama a la función port_rgb_light_init() para inicializar el HW del LED RGB.

  10. Codifica las funciones fsm_rgb_light_fire() y fsm_rgb_light_destroy() igual que hiciste en las versiones anteriores. Estas funciones lanzan la FSM y liberan la memoria respectivamente.

  11. Codifica el resto de las funciones fsm_rgb_light_xxx() públicas que quedan declaradas en el .h como se indica en la API.

  12. Documenta el código que esté sin comentar todavía.

Ya hemos acabado con la programación de la librería del RGB light. Ahora, si compilas, no deberán aparecer errores.

6.7 COMMON Test unitario de la FSM del RGB light

Vamos a hacer el test del código que hemos desarrollado de la librería de la máquina de estados del RGB light y probar que funciona antes de continuar con la siguiente versión.

¡Importante! Recuerda que los test que se proporcionan comprueban solo algunos aspectos esenciales, pero no son exhaustivos. Es responsabilidad del alumno comprobar que el sistema final funciona correctamente.

Descarga el fichero de test de la FSM del RGB light test_fsm_rgb_light.c de https://github.com/sdg2DieUpm/simone/tree/simone_v3_test. Ponlo en la carpeta test/ de tu proyecto. ¡No lo metas en stm32f4/, pues no es un test específico del microcontrolador!

  1. Con la placa Nucleo-STM32 conectada al ordenador.

  2. Pulsa sobre el icono Clean and Debug sobre la plataforma que queramos depurar (stm32f446re).

  3. En el desplegable que se abre, selecciona el test test_fsm_rgb_light. Se compilará y se cargará en la placa.

  4. Ejecuta el test por completo, o pon puntos de parada si deseas ir paso a paso.

  5. Comprueba los mensajes del gdb-server para ver el resultado de las pruebas de los tests. Debería haber pasado todos los tests. Si no, lee el mensaje de error y corrige tu código hasta que pasen todas las pruebas. Si no pasan las pruebas, no continúes.

  6. Termina la depuración pulsando (image) y repite el proceso hasta que pasen todos los test.

6.8 Ejemplo de uso de la Versión 3

En este test de integración del RGB light es responsabilidad del alumno comprobar que la funcionalidad es la esperada. El ejemplo que se da no contempla todas las situaciones.

Descarga el fichero de ejemplo example_v3.c de https://github.com/sdg2DieUpm/simone/tree/simone_v3_test. Ponlo en la carpeta example/ de tu proyecto.

Procedamos:

Para poder hacer el ejemplo del RGB light, necesitamos montar el LED RGB. En el esquema de la figura se muestra un ejemplo de montaje.

  1. Monte el HW como se muestra en la .

  2. Con la placa Nucleo-STM32 conectada al ordenador.

  3. Pulsa sobre el icono de depuración image y selecciona image Clean and Debug sobre la plataforma que queramos depurar (stm32f446re).

  4. En el desplegable que se abre, selecciona el test example_v3. Se compilará y se cargará en la placa.

  5. Se parará en la primera línea del main(). Ejecuta el test por completo, o pon puntos de parada si deseas ir paso a paso. Este código no termina, pues es un bucle while infinito.

  6. Abre la terminal del gdb-server para ver los mensajes que se van imprimiendo.

  7. Comprueba que los colores del LED RGB cambian en función de la intensidad que se le indica en los mensajes de la terminal.

  8. Haz distintas pruebas y asegúrate de que el comportamiento es el adecuado.

¡Hemos creado nuestra tercera librería! Fíjate que es portable a cualquier plataforma solo con adaptar las funciones del PORT.

No dejes de documentar el código. Comprueba que la documentación del código se ha generado correctamente como se explica en la "Guía de instalación de herramientas para compilación multiplataforma en C” 4., o en el vídeo "[MatrixMCU] Documentación de código con Doxygen”.

Guarda una copia de su proyecto como simone_v3 para tener un punto de partida para la siguiente versión, y una copia de seguridad por si algo falla.


  1. Josué Pagán Ortiz, Pedro José Malagón Marzo, Román Cárdenas Rodríguez, and Juan José Gómez Valverde. Fundamentos teóricos de sistemas basados en microcontrolador STM32. Sistemas Digitales II, Sistemas Electrónicos. Josué Pagán Ortiz, Madrid, March 2025. URL: https://oa.upm.es/88460/

  2. STMicroelectronics. Stm32f446xc/e. Technical Report, STMicroelectronics, 2021. URL: https://www.st.com/resource/en/datasheet/stm32f446re.pdf

  3. STMicroelectronics. Rm0390 reference manual. stm32f446xx advanced arm-based 32-bit mcus. Technical Report, STMicroelectronics, 2021. URL: https://www.st.com/resource/en/reference_manual/rm0390-stm32f446xx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf

  4. Josué Pagán Ortiz, Pedro José Malagón Marzo, Román Cárdenas Rodríguez, Amadeo de Gracia Herranz, Sergio Esteban Romero, and Daniel Capellán Martín. Guía de instalación de herramientas para compilación multiplataforma en C. Sistemas Digitales II, Sistemas Electrónicos. Josué Pagán Ortiz, Madrid, March 2025. URL: https://oa.upm.es/92376/