Nesse post vamos dar os primeiros passos com stm32. Embora desconhecido para muitas pessoas, este microcontrolador é mais ágil e preciso que os já consagrados Arduino e ESP8266. Por este motivo, especialistas e entusiastas de sistemas embarcados vêm, cada vez mais, recomendando seu uso. Entre as placas de desenvolvimento que utilizam microcontrolador STM32, a mais consagrada é a BluePill. Vejamos algumas de suas características principais:
- Chip: STM32F103C8T6
- Processador de 32 bits
- Memória Flash: 64 kB
- Memória SRAM: 20 kB
- Frequência de clock: 72 MHz
- Número de GPIO’s: 32
- Tensão de operação: 3,3 V
- Permite comunicação PWM, I2C, SPI, USART, ADC e CAN.

Para aprender como programar-lá, vamos propor um projeto bem simples: um pisca-pisca com leds. Ficou curioso? Continue lendo!
Montagem do circuito
Hora de colocar a mão na massa! Utilizaremos os seguintes materiais para a montagem do circuito:
- Placa de desenvolvimento BluePill;
- Gravador ST-LINK;
- Protoboard;
- Led Vermelho;
- Resistor de 150 Ω;
- Jumpers Macho-Fêmea.
A montagem do circuito é bem simples! Primeiro, conecte o gravador ST-LINK à placa de desenvolvimento. Em seguida, fixe a placa na protoboard. Por fim, conecte o resistor e o led ao pino PB0. Assim:

Instalação da STM32CubeIDE e ST-LINK Utility
Para fazermos este projeto, precisaremos dos aplicativos STM32CubeIDE e ST-LINK Utility. Na STM32CubeIDE, faremos toda a parte de configuração e programação do projeto, enquanto no ST-LINK Utility será feito o carregamento do código principal na placa. Os dois aplicativos podem ser baixados diretamente do site da ST. Antes do download, é preciso logar ou criar uma conta. Uma vez baixados, é só seguir as instruções do instalador! Os links para download se encontram a seguir:
- STM32CubeIDE: https://www.st.com/en/development-tools/stm32cubeide.html
- ST-LINK Utility: https://www.st.com/en/development-tools/stsw-link004.html
Criação de um projeto na STM32CubeIDE
Com a STM32CubeIDE devidamente instalada, já podemos dar início ao nosso projeto. Para isto, na barra de opções no canto superior esquerdo da sua tela, clique em File 🡪 New 🡪 STM32 Project.

Na tela seguinte, devemos procurar pelo modelo do microcontrolador que se encontra na nossa placa de desenvolvimento. Basta olhar o part number escrito na sua placa. No nosso caso, o modelo é STM32F103C8T6. Em seguida, digite o modelo na caixa de pesquisa “Commercial Part Number”.

Feito isto, selecione o modelo correspondente na tabela localizada no canto inferior da tela. Certifique-se que o modelo selecionado é, de fato, o microcontrolador presente na sua placa. Se não for, o projeto não irá funcionar!

Com o modelo selecionado, clique em “Next”. Você irá se deparar com a tela a seguir. Nela, dê um nome para o seu projeto e escolha o local onde deseja salva-lo. Em seguida, no campo de opções, selecione “C” como “Targeted Language”, “Executable” como “Targeted Binary Type” e “STM32Cube” como “Targeted Project Type”.

Tudo certo até aqui? Ótimo! Você deve estar visualizando o arquivo .ioc do seu projeto, que nada mais é que um mapa de entradas e saídas. Aqui, faremos a configuração dos pinos que utilizaremos em nosso projeto. No nosso caso, o pino PB0 foi escolhido para ser a saída do led. Para configura-lo como saída, clique nele e selecione a opção “GPIO_Output”.

Por padrão, as saídas da BluePill assumem nível lógico baixo quando estão ativas. Precisamos mudar isto! Para isto, clique em “System Core” e, em seguida, em “GPIO”. No campo de configuração do pino PB0, altere o campo “GPIO output level” para “High”. Para facilitar as próximas etapas, optamos por alterar também a “User Label” deste pino para “led”.

Hora de verificarmos se fizemos tudo certo! Para isto, na barra de opções na parte superior da tela, clique em “Build All”. Se tudo estiver certo, o projeto não deve conter nenhum erro.

Desenvolvimento do código principal
Passamos agora para o desenvolvimento do código principal. Uma das enormes vantagens do uso da STM32CubeIDE é que ela nos gera de forma automática um código com todas as entradas e saídas devidamente declaradas de acordo com a configuração feita no arquivo .ioc (daí a importância de se fazer tudo corretamente!). Para acessa-lo, nos diretórios presentes no canto direito da tela, clique em Core 🡪 Src 🡪 main.c.

Você deve estar visualizando o código principal. Viu só como é rápido e prático! Mas, calma! Ainda não acabamos. Dentro da estrutura “While” em “Infinite loop”, insira as linhas de código a seguir:
HAL_GPIO_TogglePin(led_GPIO_Port, led_Pin); HAL_Delay(500);
Após as modificações, o código principal deve ficar da seguinte forma:
/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * Copyright (c) 2022 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* 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 */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_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(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { HAL_GPIO_TogglePin(led_GPIO_Port, led_Pin); HAL_Delay(500); /* USER CODE END WHILE */ /* 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 RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { Error_Handler(); } } /** * @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_GPIOB_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(led_GPIO_Port, led_Pin, GPIO_PIN_SET); /*Configure GPIO pin : led_Pin */ GPIO_InitStruct.Pin = led_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(led_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 */ __disable_irq(); while (1) { } /* 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(uint8_t *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */
Vamos descobrir se deu tudo certo? Na barra de opções no canto superior da tela, clique em “Build Debug for project”. Se tudo estiver ok, não deverão ser encontrados nenhum erro.

Upload do código na BluePill
Para fazermos o upload do código principal na placa de desenvolvimento, utilizaremos o aplicativo ST-LINK Utility. Com o aplicativo aberto, conecte o seu ST-LINK no computador e clique em “Connect to the target”.

Se não houver problemas de comunicação, no canto inferior da tela, você verá que a BluePill está conectada.
Ótimo! Agora, na barra de opções na parte superior da tela, clique em Target 🡪 Program & Verify 🡪 Start.

E aí? O que aconteceu? Isso mesmo! A cada 500 ms, o estado do led é invertido, fazendo com que ele pisque. Viu só? Você acabou de fazer um pisca-pisca utilizando STM32. Legal, não é?
Considerações finais
Com este projeto simples, você pôde ver como é rápido e prático programar um microcontrolador STM32, porém, suas aplicações não se restringem apenas a piscar leds. No Cheetah E-Racing, ele é o responsável pela comunicação com nada mais nada menos que nove sensores na placa de telemetria frontal! Gostou? Aproveite os conhecimentos adquiridos e crie projetos cada vez mais complexos! Siga o Cheetah E-Racing nas redes sociais e fique ligado para nossos novos posts! Até a próxima!
Esse conteúdo é resultado da parceria da MakerHero com a Cheetah E-Racing. Curtiu o conteúdo? Então deixe seu comentário abaixo! E não esqueça de acompanhar a Cheetah E-Racing nas redes sociais.