Medindo Intervalos de Tempo com a Franzininho C0: Integrando Timer, Interrupções e USART
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.
Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.


