Guia Prático para Interrupções no STM32: Teoria & Aplicação

Interrupções são mecanismos essenciais em microcontroladores STM32Famílias de microcontroladores STM32: Uma visão geralFamílias de microcontroladores STM32: Uma visão geralProfundo mergulho nas famílias STM32, explorando arquitetura, aplicações e desempenho. Descubra dicas e casos práticos para projetos embarcados. para lidar com eventos assíncronos de forma eficiente. Imagine um sistema que precisa responder imediatamente a um botão pressionado pelo usuário, enquanto continua executando outras tarefas. Sem interrupções, o código ficaria preso em loops de verificação (polling), desperdiçando recursos. Neste artigo, exploraremos como configurar e usar interrupções no STM32O que é STM32 e por que usá-lo?O que é STM32 e por que usá-lo?Descubra os principais benefícios, arquitetura ARM Cortex-M e aplicações práticas dos microcontroladores STM32. Comece a inovar agora., desde a estrutura do NVIC até exemplos práticos com GPIOsImplementando um sistema de alarme com sensores de movimento e STM32Implementando um sistema de alarme com sensores de movimento e STM32Aprenda a criar um sistema de alarme robusto com STM32, sensores de movimento, técnicas de debounce e otimização de energia. Confira o tutorial completo!, combinando teoria e prática para um entendimento completo.

Índice🔗

O que são interrupções e por que são importantes?🔗

Interrupções permitem que o processador pause a execução atual para lidar com um evento de alta prioridade, retomando depois o fluxo original. No STM32O que é STM32 e por que usá-lo?O que é STM32 e por que usá-lo?Descubra os principais benefícios, arquitetura ARM Cortex-M e aplicações práticas dos microcontroladores STM32. Comece a inovar agora., isso é crítico para:

Exemplo Prático:

Um sistema de alarme usando um sensor de movimento. Sem interrupções, o microcontrolador precisaria verificar constantemente o estado do sensor. Com interrupções, ele só age quando o sensor é acionado.

Arquitetura do NVIC🔗

O Nested Vectored Interrupt Controller (NVIC) é o núcleo do gerenciamento de interrupções no STM32O que é STM32 e por que usá-lo?O que é STM32 e por que usá-lo?Descubra os principais benefícios, arquitetura ARM Cortex-M e aplicações práticas dos microcontroladores STM32. Comece a inovar agora.. Ele gerencia prioridades, aninhamento e latência, permitindo respostas rápidas e hierarquizadas. Principais características:

RecursoDescrição
PrioridadesAté 16 níveis de prioridade (configuráveis via registradores).
AninhamentoInterrupções de alta prioridade podem interromper as de baixa prioridade.
Latência reduzidaResposta a interrupções em até 12 ciclos de clock.

Funcionamento Interno do NVIC

flowchart TD A[Evento Externo/Interno] --> B[Detecção de Interrupção pelo NVIC] B --> C[Verificação da Prioridade] C --> D[Busca do Vetor de Interrupção] D --> E[Execução da ISR] E --> F[Retorno para a Tarefa Original]

Configuração Básica do NVIC:

// Habilita a interrupção EXTI0 (pino PA0)
HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0); // Prioridade 0, subprioridade 0
HAL_NVIC_EnableIRQ(EXTI0_IRQn);

Prioridades Preemptivas vs. Subprioridades:

A prioridade preemptiva determina se uma interrupção pode interromper outra. A subprioridade ordena interrupções com a mesma prioridade preemptiva. Use a fórmula:

$$ \text{Prioridade NVIC} = \text{Valor numérico} \times \frac{16}{\text{Níveis suportados}} $$

EXTI: Configurando interrupções externas🔗

O External Interrupt/Event Controller (EXTI) é responsável por gerar interrupções a partir de sinais externos (pinos GPIOConfigurando e usando GPIOs no STM32Configurando e usando GPIOs no STM32Explore neste tutorial os fundamentos e configurações práticas dos GPIOs no STM32, com exemplos de LED, botões e modos alternativos., sensores). Passos para configurar:

1. Habilitar o clock do SYSCFG (para mapeamento de pinos).

2. Configurar o pino GPIOConfigurando e usando GPIOs no STM32Configurando e usando GPIOs no STM32Explore neste tutorial os fundamentos e configurações práticas dos GPIOs no STM32, com exemplos de LED, botões e modos alternativos. como entrada.

3. Vincular o pino ao EXTI via SYSCFG_EXTILineConfig.

4. Definir o tipo de trigger (borda de subida, descida, ou ambas).

Exemplo de Configuração:

GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; // Interrupção na borda de subida
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

Passo a passo: Implementando uma interrupção GPIO🔗

Vamos criar dois exemplos práticos: um botão que alterna um LED e outro que usa callback para resposta assíncrona.

Exemplo 1: Botão em PA0 alterna LED em PB7

// main.c
void EXTI0_IRQHandler(void) {
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0); // Limpa a flag de interrupção
    HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_7); // Alterna o LED
}
int main(void) {
    // Configuração inicial do sistema
    HAL_Init();
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    // Configura PA0 como entrada com interrupção
    GPIO_InitStruct.Pin = GPIO_PIN_0;
    GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    // Configura PB7 como saída
    GPIO_InitStruct.Pin = GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    // Habilita a interrupção
    HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(EXTI0_IRQn);
    while (1) {
        // Código principal pode executar outras tarefas
    }
}

Exemplo 2: Uso de Callback para LED em PG13

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
    if(GPIO_Pin == GPIO_PIN_0) {
        HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_13);
    }
}
int main(void) {
    // Configuração do LED em PG13
    __HAL_RCC_GPIOG_CLK_ENABLE();
    GPIO_InitTypeDef LED_Init = {0};
    LED_Init.Pin = GPIO_PIN_13;
    LED_Init.Mode = GPIO_MODE_OUTPUT_PP;
    HAL_GPIO_Init(GPIOG, &LED_Init);
    // Restante igual ao exemplo anterior
}

Depuração de interrupções: Erros comuns e soluções🔗

ProblemaCausa ProvávelSolução
Interrupção não é acionadaPino não configurado como entradaVerificar GPIO_InitStruct.Mode
ISR é chamada repetidamenteFlag de interrupção não limpaChamar HAL_GPIO_EXTI_IRQHandler()
Latência altaPrioridade do NVIC mal configuradaAjustar prioridades com HAL_NVIC_SetPriority

Dica de Depuração:

Use o debuggerFerramentas de desenvolvimento para STM32: IDEs, compiladores e debuggersFerramentas de desenvolvimento para STM32: IDEs, compiladores e debuggersAprenda a selecionar e integrar IDEs, compiladores e debuggers para STM32 com dicas e exemplos claros, otimizando seu desenvolvimento. para verificar registradores como EXTI_PR (flag de interrupção) e NVIC_ISPR (status de interrupções pendentes).

Casos avançados: DMA e prioridade de interrupções🔗

DMA com Interrupções

Interrupções podem ser combinadas com DMA para transferir dados sem CPU. Exemplo: leitura de ADCConfigurando e usando o ADC no STM32Configurando e usando o ADC no STM32Este tutorial para STM32 ensina a configurar o ADC via registradores e HAL, explicando calibração, DMA, filtragem e resolução de problemas práticos. via DMA com interrupção de conclusão.

// Interrupção de transferência completa do DMA
void DMA1_Channel1_IRQHandler(void) {
    if (DMA->ISR & DMA_ISR_TCIF1) {
        // Processa dados do ADC
        HAL_DMA_IRQHandler(&hdma_adc);
    }
}

Gerenciamento de Prioridades

Interrupções de alta prioridade (valor numérico baixo) interrompem ISRs de baixa prioridade. Configure prioridades conforme a criticidade:

HAL_NVIC_SetPriority(TIM2_IRQn, 1, 0); // Timer: prioridade alta
HAL_NVIC_SetPriority(EXTI0_IRQn, 2, 0); // Botão: prioridade média

Boas práticas e considerações finais🔗

1. Minimize o tempo de execução da ISR:

Mantenha ISRs curtas. Use flags ou filasImplementando um sistema multitarefa com STM32 e RTOSImplementando um sistema multitarefa com STM32 e RTOSAprenda a migrar de código bare-metal para multitarefa robusta usando FreeRTOS no STM32. Descubra técnicas avançadas e exemplos práticos. para processamento posterior na rotina principal.

2. Sincronização de recursos compartilhados:

Proteja variáveis globais com volatile ou utilize mutexSincronização e comunicação entre tarefas no STM32Sincronização e comunicação entre tarefas no STM32Aprenda a implementar mecanismos de sincronização com semáforos, mutexes, filas e event groups em sistemas embarcados com STM32 e FreeRTOS. em sistemas com RTOS.

3. Evite bloqueios:

Não use funções bloqueantes (como HAL_Delay()) dentro de ISRs.

4. Teste de estresse:

Simule eventos rápidos e múltiplos para garantir que a ISR lida com todas as situações.

5. Documentação clara:

Comente prioridades e dependências entre interrupções para facilitar manutenção.

Autor: Marcelo V. Souza - Engenheiro de Sistemas e Entusiasta em IoT e Desenvolvimento de Software, com foco em inovação tecnológica.

Referências🔗

Compartilhar artigo

Artigos Relacionados