Introdução ao STM32 Nucleo64 usando STM32CubeMX e TrueSTUDIO – Simple LED Control

Tempo de leitura: 10 minutes

Muitos de nós devem estar familiarizados com os microcontroladores populares e placas de desenvolvimento como Arduino, Raspberry Pi, ESP8266, NoduMCU, 8051, etc. Na verdade, para a maioria das pessoas, Arduino teria sido sua primeira placa de desenvolvimento, mas à medida que nos aprofundamos e começamos designs profissionais, logo perceberemos as limitações do Arduino (como custo, versatilidade, estabilidade, velocidade, etc.) e entenderemos a necessidade de mudar para uma plataforma de microcontrolador mais nativa como PIC, STM, Renesas, etc.

Já cobrimos uma sequência de tutoriais de microcontroladores PIC, que orientam os iniciantes no aprendizado de microcontroladores PIC. Da mesma forma, começando com este artigo, também planejaremos uma sequência de Tutoriais da placa de desenvolvimento STM32 Nucleo64 que podem ajudar os iniciantes a aprender e desenvolver usando a plataforma STM32. As placas de desenvolvimento Nucleo64 são uma plataforma de baixo custo e fácil de usar para desenvolvedores profissionais e também para amadores. Se você é completamente novo nas placas de desenvolvimento STM32 .

Nota: Existem muitas versões de placas de desenvolvimento STM32 Nucleo64, a placa particular usada neste tutorial é NUCLEO-F030R8. Escolhemos esta placa principalmente pelo seu baixo custo. Mesmo que você tenha uma versão diferente, a maioria das coisas discutidas no tutorial serão suficientes para você começar.

 

Selecionando e baixando as plataformas de desenvolvimento necessárias para as placas Nucleo64

Começar com qualquer microcontrolador vai precisar de um IDE de programação, como temos Arduino IDE para placas Arduino, Atmel Studio para microcontrolador AVR, MP Lab para PIC, etc. Portanto, aqui também precisamos de um IDE para nossas placas STM32 Nucleo64 para realizar programação e depuração. A família STM32 consiste em microcontroladores de 32 bits que suportam os seguintes IDEs e conjuntos de ferramentas:

  • IAR Embedded Workbench® para ARM® (EWARM).
  • MDK-ARM Keil
  • TrueSTUDIO
  • Bancada de trabalho do sistema para STM32

Aqui para nossos tutoriais, TrueSTUDIO será usado para escrever, compilar e depurar código porque é gratuito para baixar e usar até mesmo para projetos comerciais sem qualquer requisito de licença. Então STM32CubeMX será usado para gerar drivers periféricos para placas STM32 para tornar a programação fácil. Para carregar nosso programa (arquivo hex) em nossa placa de desenvolvimento, as pessoas normalmente usam a ferramenta STM32 ST-LINK Utility, mas em vez disso, usaremos o próprio TrueSTUDIO para fazer isso. TrueSTUDIO tem um modo de depuração que permite aos programadores carregar o arquivo hex diretamente para a placa STM32. TrueSTUIO e STM32CubeMX são fáceis de baixar, basta seguir o link abaixo, inscrever-se e baixar o setup. Em seguida, instale-os no seu laptop.

Diagrama de circuito e configuração de hardware

Antes de prosseguirmos com a seção de software e codificação, vamos preparar nossa placa para este projeto. Conforme mencionado anteriormente neste artigo, controlaremos um LED usando um botão. Agora, se você viu o vídeo com link acima, você já deve saber que sua placa de desenvolvimento STM32 tem dois conjuntos de pinos de conector em cada lado chamados pinos ST Morpho. Conectamos um botão de pressão e um LED a esses pinos, conforme mostrado no diagrama de circuito abaixo.

As conexões de circuito são fáceis para este projeto, precisamos conectar um LED no PA5 do PORTA e um switch no PC13 do PORTC em relação ao GND. Depois que as conexões foram feitas, minha configuração de teste ficou assim.

Como alternativa, também podemos usar o LED embutido e o botão de pressão na placa. Esses LEDs embutidos e o botão de pressão também são conectados no mesmo pino, conforme mostrado no diagrama de circuito. Adicionamos componentes externos apenas para a prática. O diagrama de pinos abaixo da placa de desenvolvimento STM32 será útil para saber onde cada pino Morpho está conectado a bordo.

 

Primeiros passos com STM32CubeMX para placas de desenvolvimento STM32 Nucleo64

Etapa 1: após a instalação, inicie o STM32CubeMX e selecione o seletor de placa de acesso para selecionar a placa STM32.

Etapa 2: Agora pesquise o painel pelo nome do seu painel STM32, como NUCLEO-F030R8, e clique no painel mostrado na imagem. Se você tiver um fórum diferente, pesquise o respectivo nome. O software oferecerá suporte a todas as placas de desenvolvimento STM32 da ST Microelectronics.

Etapa 3: Agora clique em sim como mostrado na imagem abaixo, para inicializar todos os periféricos em seu modo padrão. Posteriormente, podemos alterar os requeridos conforme a necessidade de nosso projeto.

Depois de clicar em ‘Sim’, a tela será semelhante à imagem abaixo e o pino de cor verde indicando que eles são iniciados por padrão.

Etapa 4: agora os usuários podem selecionar a configuração desejada nas categorias. Aqui neste tutorial, vamos alternar um LED usando um botão. Portanto, precisamos fazer o pino do LED como saída e o pino do interruptor como INPUT.

Você pode selecionar qualquer pino, mas estou selecionando PA5 e alterando seu estado para GPIO_Output para fazê-lo funcionar como um pino de saída, conforme mostrado na imagem abaixo.

Da mesma forma, estou selecionando PC13 como GPIO_Input para poder ler o status do meu botão.

Como alternativa, também podemos configurar os pinos na guia pinagem e configuração, assim como mostrado abaixo.

Etapa 5: Na próxima etapa, o usuário pode definir a frequência desejada para o microcontrolador e os pinos de acordo com o oscilador externo e interno. Por padrão, um oscilador de cristal interno de 8 MHz é selecionado e, usando o PLL, este 8 é convertido para 48 MHz. O que significa que, por padrão, a placa STM32 ou o microcontrolador e os pinos funcionarão em 48 MHz.

Etapa 6: Agora vá para o gerenciador de projeto e dê um nome ao seu projeto, localização do projeto e selecione o conjunto de ferramentas ou IDE. Aqui estamos usando TrueSTUDIO, então selecionei o mesmo mostrado abaixo.

Etapa 7: Agora clique na marca Gerar Código pelo círculo vermelho na imagem abaixo.

Etapa 8: Agora você verá um pop-up conforme fornecido e clique em abrir projeto. Mas, certifique-se de ter instalado o TrueSTUDIO antes desta etapa.

 

Programação da placa de desenvolvimento STM32 Nucleo64 usando TrueSTUDIO

Agora seu código ou projeto será aberto no TrueSTUDIO automaticamente se TrueSTUDIO solicitar a localização do espaço de trabalho e fornecer um local do espaço de trabalho ou ir com o local padrão.

O usuário verá a tela fornecida abaixo e, em seguida, precisará clicar na marca do canto em vermelho.

E agora podemos ver o código em nosso IDE TreuSTUDIO. No lado esquerdo sob a pasta ‘src’ podemos ver outros arquivos de programa (com extensão .c) que já foram gerados para nós a partir do STM32Cube. Basta programar o arquivo main.c. Mesmo no arquivo main.c já teremos algumas coisas configuradas para nós pelo CubeMX, apenas temos que editá-lo para se adequar ao nosso programa. O código completo dentro do arquivo main.c é fornecido na parte inferior desta página.

Programa STM32 Nucleo64 para controlar o LED usando o botão de pressão

Como todo o driver e código necessários são gerados pelo STM32CubeMX, só temos que configurar um pino de LED como saída e um botão como entrada. O programa para controlar o led usando o botão de pressão deve ser escrito no arquivo main.c. O programa completo pode ser encontrado no final desta página. A explicação disso é a seguinte

Nós apenas escrevemos o código para alternar o LED usando o botão de pressão. Para conseguir isso, primeiro definimos pinos para LED e botões. Aqui nós definimos um LED no pino 5 número de PORTA

#define LED_PORT GPIOA
#define LED_PIN GPIO_PIN_5

E defina a chave no pino número 13 do PORTC.

#define SW_PORT GPIOC
#define SW_PIN GPIO_PIN_13

Então, na função principal, inicializamos todos os periféricos usados.

/ * Inicializar todos os periféricos configurados * /
MX_GPIO_Init();
MX_USART2_Init();

Em seguida, leia o botão de pressão usando a instrução if e, se o botão for encontrado, pressione (LOW) e o LED alternará seu estado.

While (1)
{
  /* CÓDIGO DO USUÁRIO END WHILE */
  If (!HAL_GPIO_ReadPin(SW_PORT, SW_PIN))  
  {
    HAL_GPIO_TogglePin(SW_PORT, LED_PIN);
    HAL_Delay(200);
  }
  /* CÓDIGO DE USUÁRIO BEGIN 3 */
}

Aqui a função HAL_GPIO_ReadPin (SW_PORT, SW_PIN) tem dois argumentos, um é PORT e o outro é um pino no qual a chave é conectada e este pino é configurado como INPUT durante a configuração do periférico no STM32CubeMX.

 

Depuração e upload de código para STM32 Necleo64 Development Board usando TrueSTUDIO

Agora conecte sua placa ao computador usando o cabo do programador. Depois de conectá-lo, o driver necessário para a placa deve ser baixado automaticamente, você pode verificar isso usando o gerenciador de dispositivos.

Em seguida, pressione o ícone de depuração marcado pelo círculo vermelho na imagem fornecida abaixo para compilar o programa e entrar no modo de depuração.

No modo de depuração, o código será carregado automaticamente. Agora precisamos executar o código pressionando ‘Resume’ ou F8 (marcado no circuito vermelho na imagem abaixo).

Agora podemos testar o controle do LED pressionando o botão. De acordo com o código, o LED deve mudar de estado toda vez que você pressiona o botão.

Após o teste, também podemos encerrar o programa pressionando o ícone encerrar, marcado pelo círculo vermelho na imagem abaixo.

Código

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define LED_PORT GPIOA
#define LED_PIN GPIO_PIN_5
#define SW_PORT GPIOC
#define SW_PIN GPIO_PIN_13
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart2;
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* 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_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
  /* USER CODE END 2 */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
  if (!HAL_GPIO_ReadPin(SW_PORT, SW_PIN))
  {
  HAL_GPIO_TogglePin(LED_PORT, LED_PIN);
  HAL_Delay(200);
  }
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL12;
  RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
  {
    Error_Handler();
  }
}
/**
  * @brief USART2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART2_UART_Init(void)
{
  /* USER CODE BEGIN USART2_Init 0 */
  /* USER CODE END USART2_Init 0 */
  /* USER CODE BEGIN USART2_Init 1 */
  /* USER CODE END USART2_Init 1 */
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 38400;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART2_Init 2 */
  /* USER CODE END USART2_Init 2 */
}
/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOF_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
  /*Configure GPIO pin : PC13 */
  GPIO_InitStruct.Pin = GPIO_PIN_13;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
  /*Configure GPIO pin : LD2_Pin */
  GPIO_InitStruct.Pin = LD2_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LD2_GPIO_Port, &GPIO_InitStruct);
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  /* USER CODE END Error_Handler_Debug */
}
#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(char *file, uint32_t line)
{ 
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/