Tutorial Completo: Configuração e Uso do ADC em STM32

O ADC (Conversor Analógico-DigitalImplementando um osciloscópio simples com STM32Implementando um osciloscópio simples com STM32Descubra como implementar um osciloscópio digital com STM32, desde a aquisição de sinais via ADC com DMA até a visualização e processamento em tempo real.) é um componente crítico em sistemas embarcados para aquisição de dados analógicos, como leitura de sensores, monitoramento de tensão e controle de processos. Nos microcontroladores STM32, o ADC oferece alta flexibilidade com múltiplos canais, resoluções ajustáveis e modos avançados de operação. Este artigo combina teoria detalhada, configuração prática (via HAL e registradores), técnicas de otimização e exemplos reais, incluindo uso de DMA, calibração e solução de problemas.

Sumário

Visão Geral do ADC🔗

O ADC converte sinais analógicos (0-3.3V) em valores digitais, com resolução de 12 bits (4096 níveis) em muitos modelos 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.. Sua operação depende de parâmetros como tensão de referência (VREF+), tempo de amostragem e modo de conversão.

Aplicações Comuns:

Equação Fundamental:

$$ V_{in} = D \times \frac{V_{ref}}{2^n - 1} $$

Onde:

  • \( D \): Valor digital lido.
  • \( V_{ref} \): Tensão de referência (ex: 3.3V).
  • \( n \): Resolução em bits (ex: 12).

Configuração do ADC: Registradores vs. HAL🔗

Via Registradores (Low-Level)

O controle direto dos registradores oferece máximo desempenho. Exemplo para configurar o ADC1:

// Habilita clock do ADC
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
// Configura tempo de amostragem (239.5 ciclos para canal 5)
ADC1->SMPR2 |= ADC_SMPR2_SMP5_2 | ADC_SMPR2_SMP5_1 | ADC_SMPR2_SMP5_0;
// Habilita o ADC
ADC1->CR2 |= ADC_CR2_ADON;

Via HAL (STM32CubeIDE)

A HALUsando o DAC no STM32 para gerar sinais analógicosUsando o DAC no STM32 para gerar sinais analógicosAprenda a configurar e calibrar o DAC do STM32 para gerar sinais analógicos precisos. Descubra técnicas avançadas, exemplos práticos e dicas de otimização. simplifica a configuração com abstração de hardware:

ADC_HandleTypeDef hadc;
void MX_ADC1_Init(void) {
  hadc.Instance = ADC1;
  hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
  hadc.Init.Resolution = ADC_RESOLUTION_12B;
  hadc.Init.ScanConvMode = DISABLE;
  hadc.Init.ContinuousConvMode = DISABLE;
  HAL_ADC_Init(&hadc);
  // Configuração do canal
  ADC_ChannelConfTypeDef sConfig = {0};
  sConfig.Channel = ADC_CHANNEL_0;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES;
  HAL_ADC_ConfigChannel(&hadc, &sConfig);
}

Dica: Use HAL_ADC_Start() e HAL_ADC_PollForConversion() para leituras sob demanda.

Modos de Operação e Aplicações🔗

ModoDescriçãoCaso de Uso
SingleConversão única de um canal.Leitura pontual de sensor.
ScanSequência de conversões em múltiplos canais.Multiplexação de sensores.
ContinuousConversões contínuas sem reinicialização.Monitoramento em tempo real.
InjectedConversão de alta prioridade (interrompe a sequência regular).Resposta a eventos críticos.

Exemplo de Scan Mode:

hadc.Init.ScanConvMode = ENABLE;
hadc.Init.NbrOfConversion = 3; // 3 canais sequenciais

Calibração, Precisão e Técnicas de Filtragem🔗

Calibração

A calibração internaCalibração de ADC no STM32: Melhore a precisão de leituras analógicasCalibração de ADC no STM32: Melhore a precisão de leituras analógicasDescubra métodos avançados para calibração de ADC em microcontroladores STM32, combinando teoria e prática para garantir precisão em aplicações críticas. corrige offset e linearidade. Execute após inicializar o ADC:

HAL_ADCEx_Calibration_Start(&hadc, ADC_SINGLE_ENDED);

Técnicas para Melhorar Precisão

1. OversamplingOversampling no STM32: Aumentando a resolução do ADC via softwareOversampling no STM32: Aumentando a resolução do ADC via softwareAprenda a aplicar oversampling em STM32 para aumentar a resolução do ADC de 12 para 16 bits, otimizando medições com precisão e confiabilidade.:

Capture múltiplas amostras e calcule a média:

#define SAMPLES 10
uint32_t avg = 0;
for (int i = 0; i < SAMPLES; i++) {
  avg += HAL_ADC_GetValue(&hadc);
}
avg /= SAMPLES;

2. Filtro Digital:

Implemente média móvel ou filtro IIR para reduzir ruído.

Fórmula de Compensação de Temperatura (Sensor Interno):

$$ T (°C) = \frac{(V_{25} - V_{ADC})}{AvgSlope} + 25 $$
  • \( V_{25} \): Tensão a 25°C (datasheet).
  • \( AvgSlope \): Variação de tensão por °C (ex: 4.3 mV/°C).

DMA: Leituras Contínuas com Eficiência🔗

O DMA permite transferir dados do ADCImplementando um osciloscópio simples com STM32Implementando um osciloscópio simples com STM32Descubra como implementar um osciloscópio digital com STM32, desde a aquisição de sinais via ADC com DMA até a visualização e processamento em tempo real. para a memória sem uso da CPU, ideal para sistemas em tempo real.

Configuração:

uint16_t adc_buffer[100];  // Buffer para 100 leituras
// Habilite DMA no ADC
hadc.DMA_Handle = &hdma_adc1;
hadc.Init.ContinuousConvMode = ENABLE;
HAL_ADC_Start_DMA(&hadc, (uint32_t*)adc_buffer, 100);

Fluxo de Dados:

graph LR ADC -->|DMA Request| DMA -->|Transferência| Memory

Exemplos Práticos: Sensor de Temperatura Interna e LM35🔗

Exemplo 1: Sensor de Temperatura Interna

1. Habilite o sensor:

sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
HAL_ADC_ConfigChannel(&hadc, &sConfig);

2. Leitura e conversão:

HAL_ADC_Start(&hadc);
HAL_ADC_PollForConversion(&hadc, 100);
uint32_t raw = HAL_ADC_GetValue(&hadc);
float temp = ((1.43 - (raw * 3.3 / 4095)) / 0.0043) + 25;

Exemplo 2: Leitura do LM35 (10 mV/°C)

float Read_LM35(void) {
  HAL_ADC_Start(&hadc);
  HAL_ADC_PollForConversion(&hadc, 100);
  uint32_t raw = HAL_ADC_GetValue(&hadc);
  float voltage = raw * (3.3f / 4095.0f);
  return voltage / 0.01f;  // Converte mV para °C
}

Troubleshooting: Erros e Soluções🔗

ProblemaCausa ProvávelSolução
Leituras inconsistentesRuído na alimentação ou fonte.Adicione capacitor de bypass (ex: 100nF).
Valores fixosClock não configurado.Verifique ADC_CLOCK_SYNC_PCLK_DIVx.
DMA não iniciaPrioridade de DMA incorreta.Ajuste com HAL_NVIC_SetPriority().
Offset elevadoCalibração não realizada.Execute HAL_ADCEx_Calibration_Start().
Temperatura incorretaVREF+ instável.Use fonte de referência externa.

Dica Final: Para aplicações críticas, valide as leituras com um multímetro ou osciloscópio e ajuste os parâmetros de amostragem conforme necessário.

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