FAVORITAR

Trabalhando com ADC no Franzininho C0: Tutorial Completo no STM32CubeIDE

Introdução

Quando pensamos em eletrônica digital, é comum imaginar que tudo funcione apenas com valores binários (0 e 1). No entanto, sistemas embarcados são dispositivos que interagem com o mundo real, e no mundo real, as informações são “analógicas” e não “digitais”. Nesse artigo vamos explorar o ADC no Franzininho C0 com exemplos usando polling, interrupção e DMA.

O Que é um Conversor Analógico-Digital (ADC)?

Para um microcontrolador poder compreender valores analógicos, como a temperatura captada por um sensor, é necessário um conversor analógico-digital. O ADC é o dispositivo que traduz um sinal analógico em um sinal digital que o microcontrolador pode processar.

Como funciona um ADC?

Vamos pegar o exemplo de um microfone. O áudio captado por ele é um sinal analógico. Com a ajuda de um ADC, podemos transformar esses sinais analógicos em sinais digitais, permitindo que um software processe o som. No caso, o ADC do STM32 usa um método chamado “aproximação sucessiva”, que gera um conjunto de tensões discretas e as compara com a amostra de tensão de entrada.

Características dos ADCs

Os ADCs têm duas características principais:

Potencializando a automação com conectores menores, mais rápidos e mais fortes

Conecte-se com Confiança: Suporte à Indústria 4.0, Manufatura Inteligente e a Transição para a Indústria 5.0

Saiba mais

  • Resolução [bits]: O número de bits usados para representar o sinal digital.
  • Taxa de amostragem [Hz]: A velocidade com que o ADC funciona.

Por exemplo, um ADC de 8 bits com uma taxa de amostragem de 1 kHz possui 256 (2⁸) níveis para representar o sinal digital e leva 1 milissegundo para converter um sinal analógico em digital.

Um sinal analógico é expresso em tensão [V], e alguns aspectos importantes são:

  • Tensão em escala real: O valor máximo da tensão de entrada que pode ser convertido em digital.
  • Resolução de tensão: A tensão total dividida pelo número de níveis.

Por exemplo, um ADC de 8 bits com uma tensão total de 3,3 V tem uma resolução de 3,3/256 níveis = 12,9 mV.  A resolução é o menor valor de tensão que o ADC pode diferenciar. 

Polling, Interrupção e DMA: Qual é a Melhor Opção para Gerenciar Leitura ADC?

Ao trabalhar com leituras ADC, você pode escolher entre três métodos principais: Polling, Interrupção e DMA. Cada um tem suas vantagens e desvantagens, dependendo das necessidades da sua aplicação.

Polling

O microcontrolador inicia a leitura do ADC e aguarda até que a conversão seja concluída antes de continuar com outras tarefas.

  • Prós: Simples de implementar e não requer periféricos adicionais.
  • Contras:  Desperdiça o tempo da CPU, pois fica esperando o ADC terminar.

Interrupção

O microcontrolador começa a leitura do ADC e continua executando outras tarefas. Quando a conversão termina, o ADC envia uma “interrupção” para o microcontrolador, que então pausa o que está fazendo para processar a leitura.

  • Prós: Economiza tempo de CPU e permite que o microcontrolador execute outras tarefas enquanto espera.
  • Contras: Pode ser ineficiente se houver muitas interrupções frequentes, pois o processador ficará ocupado gerenciando-as.

DMA (Direct Memory Access)

O microcontrolador instrui o DMA, uma unidade de controle independente, para iniciar e gerenciar a conversão do ADC. Durante essa operação, o microcontrolador continua suas tarefas. Quando a conversão termina, o DMA envia uma interrupção ao microcontrolador.

  • Prós: Libera a CPU das operações do ADC, permitindo que ela se concentre em outras tarefas.
  • Contras: O DMA pode ser mais lento que a CPU para operações simples e é mais complexo de configurar em comparação com Polling e Interrupção.

Qual Método Escolher?

Não há um método universalmente melhor; a escolha depende da sua aplicação específica:

  • Polling é ideal para tarefas simples onde a espera pela conversão não é um problema.
  • Interrupção é útil quando você precisa que a CPU esteja disponível para outras tarefas, mas as interrupções não são tão frequentes.
  • DMA é indicado para aplicações que exigem alta eficiência e minimização da carga da CPU, especialmente com grandes volumes de dados.

ADC no Franzininho C0: Projeto de Leitura de Potenciômetro Usando Polling, Interrupção e DMA

Neste tutorial, vamos demonstrar como implementar a leitura de um potenciômetro utilizando três métodos diferentes: Polling, Interrupção e DMA.

Materiais Necessários:

  • 1 Franzininho C0
  • 1 Potenciômetro de 10k ohms
  • Cabos de conexão

Montagem do Circuito para leitura do ADC no Franzininho C0

ADC no Franzininho C0

ADC no Franzininho C0

Método Polling

Configurando CubeMX:

  1. Abra STM32Cube , crie um novo projeto e selecione o microcontrolador de destino “STM32C011F6P6”. 
  1. 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”, depois volte para a página de configuração dos pinos, selecione “Trace and Debug” e  habilite “Serial Wire.
ADC no Franzininho C0
ADC no Franzininho C0
  1. Em seguida, vamos configurar a UART. Em SYS, habilite o uso dos pinos PA9 e PA10. Depois, selecione PA10 como “USART1_RX” e PA9 como “USART1_TX” e em “Connectivity” selecione a opção “USART1” e escolha o Mode “Asynchronous”. 
ADC no Franzininho C0
ADC no Franzininho C0
  1. Para configuração do ADC, clique em Analog > ADC e selecione “IN7”, pois estamos utilizando a porta PA7, que corresponde ao canal 7 do ADC de acordo com o pinout da Franzininho C0. Para o modo polling, mantenha as demais configurações do ADC nos parâmetros padrão.
ADC no Franzininho C0
  1. Também vamos habilitar o TIM3 e configurá-lo para gerar uma interrupção a cada 1 segundo. Para isso, use o valor do Prescaler como 48000-1 e do contador como 1000-1.
ADC no Franzininho C0
  1. Gere o código em “Project” > “Generate Code”.

Código:

  1. Em Core > Src > main.c ,adicione as bibliotecas de entrada/saída padrão e a biblioteca para manipulação de strings no início do arquivo:
  1. Modifique a função principal, int main, com o código abaixo.
  1. Na imagem abaixo é possível ver o código.
  1. Ao finalizar o código, partiremos para gravação. Nessa etapa você pode utilizar o ST-Link ou utilizar um cabo usb como apresentado em um dos tutoriais desta série. 

Explicação do código

Neste código, configuramos o ADC (Conversor Analógico-Digital) e a UART para ler um valor analógico de um potenciômetro e transmiti-lo pela UART a cada atualização do temporizador.

A função main começa inicializando várias bibliotecas e periféricos necessários. Depois dessas inicializações, HAL_TIM_Base_Start(&htim3) inicia o Timer 3, que é usado para controlar a frequência das leituras do ADC. Para garantir que o ADC forneça leituras precisas, HAL_ADCEx_Calibration_Start(&hadc1) executa uma calibração do ADC.

Dentro do loop while(1), quando o Timer 3 atingi o tempo configurado para realizar uma nova leitura, o ADC é iniciado (HAL_ADC_Start(&hadc1)) e o código espera até que a conversão seja concluída (HAL_ADC_PollForConversion(&hadc1, 1000)) com um timeout de 1000 milissegundos. Uma vez concluída, o valor convertido é obtido (uint32_t leituraPotenciometro = HAL_ADC_GetValue(&hadc1)) e a conversão é parada (HAL_ADC_Stop(&hadc1)). Após obter o valor lido do ADC, o código formata este valor em uma string (sprintf(msg, "Leitura Potenciometro: %lu\r\n", leituraPotenciometro)) e o transmite via UART (HAL_UART_Transmit(&huart1, (uint8_t *)msg, strlen(msg), 1000) ). 

Funcionamento

Método Interrupção

Configurando CubeMX:

  1. Considerando as configurações já feitas para o método polling, o único detalhe que devemos realizar é habilitar a interrupção. Dessa forma, clique sobre o arquivo “.ioc”, vá em Analog > ADC > NVIC Settings e habilite a interrupção.
  1. Caso deseje, você pode desativar o clock. Não utilizaremos neste exemplo.
  1. Gere o código novamente.

Código:

  1. Em Core > Src > main.c ,adicione novamente as bibliotecas de entrada/saída padrão e a biblioteca para manipulação de strings no início do arquivo:
  1. Crie a função de Callback ADC abaixo:
  1. No código principal, int main, adicione a função de calibração do ADC e inicie o ADC para trabalhar no modo interrupção. 
  1. Na imagem abaixo é possível ver o código.
  1. Ao finalizar o código, partiremos para gravação. Nessa etapa você pode utilizar o ST-Link ou utilizar um cabo usb como apresentado em um dos tutoriais desta série. 

Explicação do código:

Neste código, você está configurando o ADC para ler o valor do potenciômetro usando interrupções. A cada leitura concluída, uma interrupção será gerada, e a função de callback HAL_ADC_ConvCpltCallback será chamada automaticamente. Esta função coleta o valor lido, o formata e transmite via UART.

Funcionamento

Método DMA

Configurando CubeMX:

  1. Considerando as configurações já feitas para o método polling, a única coisa que devemos fazer é habilitar a interrupção. Dessa forma, clique sobre o arquivo “.ioc”. Depois clique em Analog > ADC > DMA Setting, selecione o “ADC1” e clique em “ADD”. 
  1. Após adicionar o novo canal DMA, configure o modo como “normal” e habilite “memory”.
  1. Volte em “Parameter Setting” e deixe habilitado (Enabled) a conversão em modo contínuo e também às requisições DMA. 
  1. Gere o código.

Código:

  1. Em Core > Src > main.c ,adicione novamente as bibliotecas de entrada/saída padrão e a biblioteca para manipulação de strings no início do arquivo:
  1. Declare  um array para armazenar a leitura do ADC. Nesse exemplo estamos lendo apenas um canal, então o tamanho do array é 1.
  1. Adicione a função callback que será chamada automaticamente quando o DMA completar a transferência dos dados do ADC para o array adc_data

É válido destacar que HAL_ADC_Stop_DMA(&hadc1) é opcional e depende da configuração do seu projeto. Ela garante que o DMA não continue funcionando até que seja explicitamente reiniciado. Além disso, a linha if (hadc->Instance == ADC1) verifica se a interrupção foi gerada pelo ADC1, considerando que em outros projetos é possível utilizar mais de um ADC.

  1. Na função principal, int main, adicione a linha para calibrar o ADC.
  1. Na função principal, dentro do loop de repetição while, inicie o ADC com DMA.
  1. Na imagem abaixo é possível ver o código.
  1. Ao finalizar o código, partiremos para gravação. Nessa etapa você pode utilizar o ST-Link ou utilizar um cabo usb como apresentado em um dos tutoriais desta série. 

Explicação do código:

Neste trecho de código, utilizamos o DMA para realizar a leitura do ADC. A função HAL_ADC_ConvCpltCallback é chamada automaticamente quando o DMA completa a transferência, formatando o valor lido e enviando-o via UART. Este método é muito eficiente para leituras contínuas e rápidas de sensores analógicos, principalmente quando estamos utilizando mais de um canal ADC.

Funcionamento

Conclusão

Neste artigo, explicamos como trabalhar com ADC no Franzininho C0 usando os métodos Polling, Interrupção e DMA. Agora você compreende as diferenças entre esses métodos e sabe como aplicá-los para ler valores analógicos, como os de um potenciômetro, e transmiti-los via UART. 

Outros artigos da série

<< Como usar display 7 segmentos com a Franzininho C0Entendendo o Controle PWM e Aplicando no Franzininho C0 >>
Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.
Comentários:
Notificações
Notificar
0 Comentários
Inline Feedbacks
View all comments
Home » Hardware » Microcontroladores » Trabalhando com ADC no Franzininho C0: Tutorial Completo no STM32CubeIDE

EM DESTAQUE

WEBINARS

LEIA TAMBÉM

JUNTE-SE HOJE À COMUNIDADE EMBARCADOS

Talvez você goste:


Seminário de
Sistemas Embarcados e IoT 2024
 
Data: 25/06 | Local: Hotel Holiday Inn Anhembi, São Paulo-SP
 
GARANTA SEU INGRESSO

 
close-link