pub:silab2

Interfaces básicas STM32 DISCO-L476VG

Plataforma de evaluación HW para STM32L4

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

  • Depurador/programador en PCB ST-LINK/V2-1 con conector SWD
  • Alimentación (4x opciones):
    • ST-LINK/V2-1
    • Conector USB FS
    • Externa 5 V
    • Batería CR2032
  • 2x LEDs de usuario: LD4 (rojo), LD5 (verde)
  • 2x botón pulsador: USER y RESET
  • 1x puerto USB OTG FS con conector micro-AB, capacidad de re-enumeración USB y 3x interfaces USB:
    • VCP (Virtual Com port)
    • Almacenamiento masivo (USB Disk drive) para programación por arrastre
    • Depuración (Debug port)
  • 1x Joystick de 4x direcciones y selección central
  • SAI Audio DAC, estéreo, con conector Jack de salida
  • Micrófono digital MEMS
  • Acelerómetro y magnetómetro MEMS
  • Giróscopo MEMS
  • 128-Mbit memoria Quad-SPI Flash
  • Amperímetro de corriente del MCU con 4 rangos y auto calibración

  • ARM®32-bit Cortex®-M4 CPU con FPU y acelerador ART
  • 80 MHz frecuencia máxima de CPU
  • VDD de 1.71V a 3.6 V
  • 1 MB Flash
  • 128 KB SRAM
  • 114x GPIOs con capacidad de interrupción externa
  • 3x 12-bit ADCs con 16 canales
  • 2x 12-bit DAC
  • 3x USART
  • 2x UART
  • 1x LPUART
  • 2x SAI
  • 3x I2C
  • 3x SPI
  • 1x Quad SPI
  • 7x temporizadores (Timers) de propósito general, 2x básicos y 2x avanzados
  • 2x temporizadores de bajo consumo (low-power)
  • 2x temporizadores tipo Watchdog
  • 1x CAN
  • USB OTG FS
  • SDMMC
  • SWPMI
  • LCD COM x SEG
  • RTC
  • TRNG (generador de aleatorios por HW)
  • 21x sensores capacitivos
  • 2x comparadores analógicos
  • 2x amplificadores operacionales

image3.jpeg

image6.jpeg

image7.jpeg

  • 24 segmentos
  • 4 comunes ® excitación multiplexada (1/4 duty)
  • polarización 1/3 (bias) ® 3+1 = 4 voltajes de polarización

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.

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™:

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.

P1: Activación de LEDs con Joystick

  • Crear un proyecto nuevo llamado “p1_cubemx_leds_joystick” usando STM32 CubeMX
  • Funcionamiento:
    • Encender LED rojo al pulsar JOY_UP
    • Encender LED verde al pulsar JOY_DOWN
    • Encender ambos LEDs al pulsar JOY_CENTER
    • Parpadear LED rojo con retardo de 100 ms al pulsar JOY_RIGHT
    • Parpadear LED verde con retardo de 100 ms al pulsar JOY_LEFT
    • LEDs apagados si no se pulsa en el joystick
    • No olvidar poner comentarios en el código
  • Elementos de ayuda:
    • UM1884 User Manual – Description of STM32L4/L4+ HAL and low-layer drivers (PDF)
    • archivo ..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_gpio.c

P2: Activación de LED por Interrupciones

  • Crear un proyecto nuevo llamado “p2_int_led” usando STM32 CubeMX
  • Configurar temporizador TIM6 para producir interrupciones cada 100 ms
  • Funcionamiento:
    • LED rojo: parpadear cada 100 ms usando interrupciones del TIM6
  • No olvidar poner comentarios en el código
  • Elementos de ayuda:
    • UM1884 User Manual – Description of STM32L4/L4+ HAL and low-layer drivers (PDF)
      • descripción detallada de las funciones de la HAL
    • RM0351 Reference Manual – STM32L4x5-L4x6 advanced ARM-based 32-bit MCUs (PDF)
      • descripción detallada de los temporizadores

P2: Activación de LEDs por Interrupciones Priorizadas

  • Crear un proyecto nuevo llamado “p2_int_leds_prioridades” usando CubeMX
  • Configurar los temporizadores TIM6 y TIM7 para producir interrupciones
    • prioridad TIM6 < prioridad TIM7
  • Funcionamiento:
    • LED rojo: parpadear cada 1000 ms usando interrupciones del TIM6
    • LED verde: parpadear cada 1000 ms usando interrupciones del TIM7. Dentro de la ISR, realizar un retardo de 250 ms después de conmutar y antes de salir de la ISR
    • Arrancará primero el TIM7 y después de 10 ms el TIM6. Comprobar como el LED rojo (menor prioridad) se retrasa con respecto al LED verde (» 250 + 10 ms)

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

  • Crear un proyecto nuevo llamado “p2_int_leds_prioridades2” usando CubeMX
  • Funcionamiento:
    • todo igual que en el proyecto “p2_int_leds_prioridades” pero invirtiendo el orden de las prioridades, es decir, prioridad TIM6 > prioridad TIM7
    • Comprobar que, a pesar del retardo de 250 ms de la ISR del TIM7 (LED verde), la ISR del TIM6 (LED rojo) es atendida inmediatamente debido a que es más prioritaria. Es decir, que el LED rojo apenas tiene retardo respecto al LED verde (» 10 ms)
  • pub/silab2.txt
  • Última modificación: 2020/09/28 11:44
  • (editor externo)