Tabla de Contenidos

Interfaces básicas STM32 DISCO-L476VG

Plataforma de evaluación HW para STM32L4

DISCO-L476VG

Placa de desarrollo STM32 Discovery kit //32L476GDISCOVERY// con MCU STM32L476VG

MCU STM32L476VGT6 (encapsulado LQFP100)

LEDs de usuario

Pulsadores (JoyStick)

image3.jpeg

Pulsador de RESET

Controlador de LCD en el STM32L476

image6.jpeg

image7.jpeg

Display LCD en DISCO-L476VG

image19.jpeg

Desarrollo SW: interfaces E/S básicas

El objetivo del tutorial es el de crear interfaces de usuario con los recursos de E/S básicas de la plataforma HW haciendo uso de los recursos BSP proporcionados por el fabricante, incluyendo LEDs, pulsadores (JoyStick) y LCD.

Creación del proyecto con STM32CubeMX

Desde ventana principal acceder a la selección de placas STBoard e iniciar un nuevo proyecto (Start Project) para la DISCO-L476VG:

Aparecerá la ventana emergente para la inicialización de periféricos a su modo por defecto y en este caso contestaremos que Si para evitar la definición manual de un número elevado de pines individuales asociados al LCD, y eliminaremos los periféricos que no vamos a usar:

Desde la System View, eliminando los periféricos sobrantes debería quedar así:

Quedando definidos los pines para el LCD, JoyStick y LEDs, como se puede comprobar en la Pinout view:

Verificamos que la interfaz de depuración está establecida a Serial Wire en la categoría SYS y el temporizador base del sistema el SysTick; en RCC verificamos que al menos esté incluido el reloj externo de baja velocidad (LSE), pines PC14 y PC15, asociado a un cristal de 32.768 KHz (X1), ya que se utiliza como reloj base de entrada al display LCD del PCB.

En la categoría LCD del apartado Multimedia, ajustamos los parámetros del display del PCB, de acuerdo a las fórmulas señaladas y especificaciones concretas, si bien pretendemos hacer uso de las librerías BSP de nuestro PCB, y vienen ya predefinidos en la función BSP_LCD_GLASS_Init()

En la configuración de reloj asignamos la entrada LSE (32.768 KHz) en el multiplexor para el LCD, y ajustamos la frecuencia del reloj principal si es necesario, p.ej. a la máxima (HCLK) = 80 MHz para que recalcule la ruta de encaminamiento de señales más adecuada.

Comprobamos que todos los pines necesarios aparezcan en GPIO y pasamos a la generación de código en Project Manager exportando al espacio de trabajo donde operará la herramienta de Atollic TrueSTUDIO™:

Edición de código

Importamos el código generado por CubeMX (File→Import→General→Existing Projects into Workspace) y comprobamos las funciones generadas en este proyecto, que en principio sólo serán las correspondientes a GPIO y LCD.

Como el propósito aquí es utilizar funciones del BSP procedemos a la importación de las fuentes proporcionados en el FW; para ello, primero debemos localizar la BSP, que se encuentra en el siguiente directorio relativo a la carpeta de instalación de CubeMX:

[carpeta_STMCubeMX-version]/Repository/STM32Cube_FW_L4_V1.13.0/Drivers/BSP

Como en el caso de los sensores MEMS, arrastramos y copiamos (Copy files and folders) la carpeta BSP a nuestro proyecto en Eclipse, dentro de Drivers, posteriormente iremos eliminando archivos y carpetas innecesarias de otras PCBs y dispositivos hasta que queden únicamente los necesarios, como se muestra a continuación:

Ajustamos los caminos a los archivos de cabecera dentro de las propiedades del proyecto, clic derecho sobre el mismo en el explorador de Eclipse, y click izquierdo sobre la opción Properties e incluimos la ruta relativa al espacio de trabajo:

Pasamos a la edición del código donde incorporamos las nuevas cabeceras del BSP:

/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "string.h"
#include "stm32l4xx_hal.h"
#include "stm32l476g_discovery.h"
#include "stm32l476g_discovery_glass_lcd.h"
/* USER CODE END Includes */

Y en la rutina principal modificamos las secciones de usuario 2 y 3 según el siguiente código a modo de demostración donde se hace uso de llamadas a las funciones BSPs de las interfaces de E/S básicas propuestas.

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
 
/* USER CODE END 0 */
 
/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
 
  /* USER CODE END 1 */
 
  /* MCU Configuration--------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_LCD_Init();
  /* USER CODE BEGIN 2 */
  BSP_LCD_GLASS_Init();
  BSP_LCD_GLASS_DisplayChar((uint8_t *)"8",POINT_ON,DOUBLEPOINT_ON,LCD_DIGIT_POSITION_2);
  HAL_Delay(500);
  BSP_LCD_GLASS_DisplayChar((uint8_t *)"A",POINT_OFF,DOUBLEPOINT_OFF,LCD_DIGIT_POSITION_3);
  HAL_Delay(500);
  BSP_LCD_GLASS_DisplayBar(LCD_BAR_2);
  HAL_Delay(500);
  BSP_LCD_GLASS_ClearBar(LCD_BAR_2);
  HAL_Delay(500);
  BSP_LCD_GLASS_BarLevelConfig(BATTERYLEVEL_OFF);
  HAL_Delay(250);
  BSP_LCD_GLASS_BarLevelConfig(BATTERYLEVEL_1_4);
  HAL_Delay(250);
  BSP_LCD_GLASS_BarLevelConfig(BATTERYLEVEL_1_2);
  HAL_Delay(250);
  BSP_LCD_GLASS_BarLevelConfig(BATTERYLEVEL_3_4);
  HAL_Delay(250);
  BSP_LCD_GLASS_BarLevelConfig(BATTERYLEVEL_FULL);
  HAL_Delay(500);
  BSP_LCD_GLASS_BlinkConfig(LCD_BLINKMODE_ALLSEG_ALLCOM, LCD_BLINKFREQUENCY_DIV512);
  HAL_Delay(500);
  BSP_LCD_GLASS_Clear();
  BSP_LCD_GLASS_BlinkConfig(LCD_BLINKMODE_OFF, LCD_BLINKFREQUENCY_DIV512);
  BSP_LCD_GLASS_DisplayString((uint8_t *)"123456");
  HAL_Delay(500);
  BSP_LCD_GLASS_ScrollSentence((uint8_t *)"      SISTEMAS INTEGRADOS      ",1,SCROLL_SPEED_MEDIUM);
  HAL_Delay(500);
  BSP_LCD_GLASS_Contrast(LCD_CONTRASTLEVEL_0);
  BSP_LCD_GLASS_ScrollSentence((uint8_t *)"      CONTRASTE MIN", 1, SCROLL_SPEED_MEDIUM);
  HAL_Delay(500);
  BSP_LCD_GLASS_Contrast(LCD_CONTRASTLEVEL_7);
  BSP_LCD_GLASS_ScrollSentence((uint8_t *)"      CONTRASTE MAX", 1, SCROLL_SPEED_MEDIUM);
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
	  JOYState_TypeDef JoyState = BSP_JOY_GetState();
      switch(JoyState)
      {
      case JOY_LEFT:
        BSP_LED_Toggle(LED4);
        BSP_LCD_GLASS_DisplayString((uint8_t *)"  LEFT");
        HAL_Delay(1000);
        break;
 
      case JOY_RIGHT:
        BSP_LED_Toggle(LED5);
        BSP_LCD_GLASS_DisplayString((uint8_t *)" RIGHT");
        break;
 
      case JOY_UP:
        BSP_LED_Toggle(LED4);
        BSP_LED_Toggle(LED5);
        BSP_LCD_GLASS_DisplayString((uint8_t *)"    UP");
        break;
 
      case JOY_DOWN:
        BSP_LED_Toggle(LED4);
        BSP_LED_Toggle(LED5);
        BSP_LCD_GLASS_DisplayString((uint8_t *)"  DOWN");
        break;
 
      case JOY_SEL:
        BSP_LED_On(LED4);
        BSP_LED_On(LED5);
        BSP_LCD_GLASS_DisplayString((uint8_t *)"   SEL");
        break;
 
      default:
        break;
      }
  }
  /* USER CODE END 3 */
}

Realizar la depuración y ejecución del código atendiendo al uso de las distintas funciones del BSP.

Ejercicios propuestos

P1: Activación de LEDs con Joystick

P2: Activación de LED por Interrupciones

P2: Activación de LEDs por Interrupciones Priorizadas

P2: Activación de LEDs por Interrupciones Priorizadas (2)