Introdução
Nos últimos artigos da série sobre Franzininho C0 com STM32CubeIDE foi apresentado projetos envolvendo temporizadores, interrupções e comunicação USART. Neste tutorial, uniremos esses três conceitos em um único projeto. Vamos medir o tempo decorrido entre dois pressionamentos de um botão e exibir o valor resultante na porta serial.
Material necessário:
Nesse exemplo vamos usar a placa Franzininho C0 e o botão presente nela, conforme o pinout abaixo.
Configuração CubeMX:
- Abra STM32Cube , crie um novo projeto e selecione o microcontrolador de destino “STM32C011F6P6”.
- Vá para a página de configurações de relógio e em HCLK digite 48 MHz para a frequência de saída desejada do sistema. Pressione a tecla “Enter” e deixe o aplicativo resolver os divisores/multiplicadores PLL necessários para atingir a taxa de clock desejada. Depois volte para a página de configuração dos pinos, selecione “Trace and Debug” e habilite “Serial Wire.
- Para configurar a interrupção no pino PA8, clique sobre ele e selecione a opção “GPIO_EXT8”. Em seguida, nas configurações do GPIO, ative o resistor interno de pull-up e defina o modo como “External Interrupt Mode with Falling Edge Trigger Detection” que detecta borda de descida.
- Habilite a entrada correspondente no NVIC.
- Para configuração da USART, primeiro em SYS, habilite o uso dos pinos PA9 e PA10. Em seguida, selecione PA10 como “USART1_RX” e PA9 como “USART1_TX” e em “Connectivity” selecione a opção “USART1”, depois escolha o Mode “Asynchronous”.
- Por fim, vamos habilitar o TIM3 e configurá-lo para gerar uma interrupção a cada 1 milissegundo. Para isso, calcule os valores dos parâmetros e após serem configurados, habilite a interrupção.
- Gere o código em “Project” > “Generate Code”.
Código:
- Em Core > Src > main.c ,adicione as bibliotecas de entrada e saída padrão e a biblioteca para manipulação de strings no início do arquivo:
#include "stdio.h"
#include "string.h"- Adicione as variáveis globais necessárias para o funcionamento do código. Estas variáveis são usadas para controlar o estado do botão, armazenar o tempo e preparar mensagens para transmissão via USART:
/* USER CODE BEGIN PV */
/* Variáveis globais */
volatile uint32_t time = 0;
volatile uint8_t button_state = 0;
char uart_tx_buffer[50];
uint8_t msg_start[] = "Contagem de tempo iniciada!\r\n";
/* USER CODE END PV */
- Crie a função callback para interrupção externa. Adicione a função que será chamada quando o botão conectado ao pino especificado (neste caso, GPIO_PIN_8) for pressionado. Esta função inicia ou para o temporizador e transmite mensagens via USART dependendo do estado do botão:
/* Função de configuração da interrupção externa */
void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin) {
if (GPIO_Pin == GPIO_PIN_8) { // Botão pressionado
if (!button_state) { // Primeiro pressionamento
HAL_TIM_Base_Start_IT(&htim3); // Inicia temporizador
HAL_UART_Transmit(&huart1, msg_start, (sizeof(msg_start)-1), 1000); // Transmite mensagem serial pela USART
button_state = 1;
} else { // Segundo pressionamento
HAL_TIM_Base_Stop_IT(&htim3); // Para temporizador
sprintf(uart_tx_buffer, "Tempo decorrido: %lu ms\r\n", time); // Formata mensagem
HAL_UART_Transmit(&huart1, (uint8_t *)uart_tx_buffer, strlen(uart_tx_buffer), 1000); // Transmite mensagem serial pela USART
//zera variaveis de controle
time = 0;
button_state = 0;
}
}
}
- Por fim, vamos criar a função para interrupção do temporizador. Adicione a função de callback que será chamada cada vez que o temporizador alcançar o período configurado. Esta função incrementa a variável time a cada interrupção:
/* Função de callback de interrupção do temporizador */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
if (htim == &htim3) {
time++;
}
}
Na imagem abaixo, pode ser visto o código.
Gravação:
Utilizando um gravador ST-LINK realize as conexões como indicado na figura e faça o upload do código.
Funcionamento:
Usando o console Serial, que pode ser o próprio do STM32CubeIDE ou de outra ferramenta, você verá o seguinte funcionamento:
Ao pressionar o botão, a contagem de tempo é iniciada, e uma mensagem é exibida no console Serial. Ao pressionar o botão novamente, a contagem é parada e o tempo decorrido é exibido no console Serial.

Detalhe, se pressionar o botão muito rapidamente, o sistema pode registrar múltiplas pressões devido ao debounce, o que pode fazer com que a contagem pare e reinicie rapidamente. O debounce é o efeito de contatos mecânicos oscilando brevemente quando o botão é pressionado e isso pode ser resolvido implementando um pequeno atraso (ex. 50 ms) na interrupção, deixo como desafio para você resolver caso queira.
Conclusão:
Neste tutorial, integramos temporizadores, interrupções e comunicação USART para medir intervalos de tempo com a Franzininho C0, utilizando STM32CubeIDE. Configuramos e iniciamos um projeto, ajustamos os pinos e as interrupções, e finalmente, implementamos a lógica para iniciar e parar a contagem de tempo via um botão, exibindo os resultados no console Serial.
Este exercício prático oferece uma compreensão de como combinar diversos periféricos, abrindo caminho para projetos mais complexos.





