Aumentando a exatidão do ADC do MSP430

ADC do MSP430

O conversor analógico digital (Analog-to-digital converter - ADC) é um dos componentes/periféricos mais importantes dentro da instrumentação moderna. Sua função é converter os sinais que estão no domínio contínuo (sinal analógico) para o domínio discreto (sinal digital), ou seja, converter um sinal analógico que pode assumir infinitos valores entre dois pontos, em uma sequência binária referente à discretização no tempo e amplitude.

 

O conversor ADC pode ser um componente externo ou mesmo um periférico interno ao microcontrolador, algo bastante comum atualmente. Neste artigo vou apresentar como utilizar os registros TLV para obter um valor mais próximo do real com relação à referência interna e também com o resultado da conversão do ADC em um microcontrolador da linha MSP430. Utilizarei como base a launchpad EXP430FR6989, mas o processo é semelhante em outros modelos e launchpads.

 

 

Breve Introdução

 

Atualmente, a maioria dos microcontroladores disponibiliza uma vasta gama de periféricos importantes para projetos envolvendo algum tipo de instrumentação. Podemos lembrar desde a referência interna de tensão analógica, conversores ADC, DAC, sensores internos de temperatura, AmpOps embutidos no próprio microcontrolador (alguns com ganho programável), comparadores, entre outros.

 

Junto com essa vasta gama surge um “problema”: Como garantir a exatidão das medidas, em especial se você não tiver acesso a instrumentos calibrados ou mais sofisticados? (caso tiver dúvidas sobre as diferenças entre exatidão, precisão e resolução, indico acessar este artigo).

 

Neste ponto, os usuários da linha MSP430 da Texas Instruments têm um trunfo nas mãos, os registros TLV.

 

Os registros TLV (tag length value) armazenam informações sobre o dispositivo em uso, desde o ID padrão do uC, informações sobre o DIE, periféricos disponíveis e também valores únicos de calibração, ou seja, constantes calculadas dispositivo a dispositivo durante o processo de teste e verificação da produção.

 

Infelizmente as informações sobre o uso dos registros TLV são bem esparsas e até incompletas na documentação, mas felizmente o fórum e2e tem alguns posts interessantes que me ajudaram a entender um pouco sobre a utilização. Um outro ponto é que nem todos os dispositivos possuem os mesmos registros TLV. Dispositivos marcados como XMS430 (versão pre-release) não apresentam uma tabela TLV válida, apenas dispositivos RTM silicons, então vale pesquisar no datasheet específico, user guide da série e no fórum.

 

 

Os registros TLV

 

Como comentando anteriormente, os registros TLV são uma região da memória (protegida contra gravação) que traz informações sobre o dispositivo. No caso do MSP430FR6989 presente na launchpad temos informações relacionada a:

  • Info Block: CRC, device ID, HW e SW version;
  • Die Record: informações sobre a origem do Die;
  • ADC12B: constantes de calibração para ganho, offset e sensor de temperatura interno;
  • Ref Calibration: constantes para calibração do valor real da referência interna;
  • Random number: número aleatório de 128 bits (que pode ser utilizado como seed para gerar números aleatórios, inclusive usando o hardware de CRC do msp430);
  • BSL Configuration.

 

 

Indo direto ao ponto

 

Para melhorar a exatidão das medições utilizando o ADC no MSP430 temos duas alternativas: utilizar uma referência externa com excelente exatidão inicial; ou medir/obter o valor real da referência interna.

 

Na maioria dos casos é mais prático (e barato) utilizar a referência interna, mas mesmo assim é necessário saber seu real valor, já que os valores listados no datasheet possuem certa margem de tolerância.

 

É aqui que o registro TLV se torna útil. Através das constantes armazenadas é possível calcular um valor mais próximo do real para a referência interna sem depender de um multímetro de 4,5 (quatro casas e meia) ou mais casas. Além disso, permite compensar o ganho do ADC e também seu Offset.

 

A DriverLib presente na MSP430Ware traz funções para obter essas constantes, ficando a nosso cargo apenas salvá-las em algumas variáveis para facilitar o processo. Para isso usei como base o exemplo “tlv_ex3_calibrateTempSensor” para entender como obter as constantes. As funções utilizadas estão apresentadas a seguir:

 

 

Apesar da memória ser protegida contra gravação, alguns processos podem alterar seu conteúdo, então é válido realizar uma checagem dos dados antes de calibrar algo. O início da tabela TLV apresenta dois bytes de CRC que podem ser calculados utilizando um algoritmo CRC16 CCITT, ou mesmo utilizando o HW do MSP430 para CRC16.

 

O user guide da família F (não da FR utilizada na launchpad para teste) apresenta o código para calcular o CRC utilizando o HW interno (capítulo 1.13.4), além disso o mesmo está disponível neste thread do e2e.

 

 

Por curiosidade resolvi testar/obter o CRC via software e me baseei neste thread do conhecido stackoverflow, e como esperado, o resultado é o mesmo.

 

 

O grande diferencial das duas implementações está na quantidade de tempo gasto. A versão baseada no hardware CRC16 gasta 2274 pulsos de clock para calcular o CRC, enquanto a versão baseada em software gasta 10608 pulsos de clock.

 

Com o CRC devidamente verificado temos apenas que utilizar as constantes nas correções.

 

O user guide apresenta a equação de como as constantes são obtidas. Como a referência de tensão interna possui 3 valores possíveis (1.2V, 2.0V e 2.5V) existe uma constante para cada valor, mas a fórmula é exatamente a mesma. Note que apesar de ser um valor envolvendo fração, é armazenado na forma de inteiro (fixed point).

 

Fator Calibração das referências de tensão
Figura 1 - Fator de calibração das referências internas

 

Invertendo essa equação podemos calcular o valor real da referência. Este fator será útil dependendo da abordagem utilizada para correção dos valores, como será possível avaliar logo mais. Este valor permite obter o valor mais preciso de resolução em Volts/bit de acordo com a resolução do ADC.

 

 

A constante de ganho do ADC é obtida de maneira semelhante.

 

Fator de calibração do ganho do ADC
Figura 2 - Fator de calibração do ganho do ADC

 

Dividindo a constante de ganho por 2^15 (decimal 32768) obteremos um valor fator multiplicador para compensar o ganho na conversão.

 

A seguir é apresentado o trecho onde as correções são aplicadas. Achei interessante mostrar o impacto de cada constante no resultado. Então temos 5 resultados para a mesma conversão, desde nenhuma correção até aplicando todos os fatores.

 

Os trechos que mais nos interessam são o passo 1, que apresenta o resultado sem nenhuma compensação; o passo 4, com todas as compensações realizadas através de variáveis float; e o passo 5, que realiza grande parte dos cálculo no domínio dos inteiros, utilizando float apenas para converter o valor do ADC corrigido em tensão propriamente dita. Note que neste último caso utilizamos o valor Volts/bit ideal, pois a correção da referência já foi realizada dentro dos cálculos envolvendo os números inteiros.

 

 

Para os testes utilizei como base a referência de tensão, que desenvolvi nesta série, junto com um multímetro HP3478A. Irei considerar apenas os valores das 4 primeiras casas após a vírgula, visto que a resolução teórica máxima é de 12 bits, o que levaria a 610µ/Vbit, ou seja, com apenas 2 bits a mais já incrementamos mais de 1mV. Na prática a resolução efetiva será menor se considerarmos o ENOB e outros fatores.

 

No teste coletei 4 resultados aleatórios de conversão, dois utilizando a média de 16 amostras e dois utilizando a média de 64 amostras, ambas com objetivo de minimizar o efeito dos ruídos com característica gaussiana (ruído branco). O resultado do teste é apresentado a seguir:

 

 Medição 1 - Média 16 pontosMedição 2 - Média 16 pontosMedição 3 - Média 64 pontosMedição 4 - Média 64 pontos
 (V)Erro(V)Erro(V)Erro(V)Erro
Tensão HP1,2500-1,2500-1,2500-1,2500-
         
ADC_correct11,2469-0,25%1,2481-0,15%1,2475-0,20%1,2487-0,10%
ADC_correct41,2481-0,15%1,2493-0,06%1,2487-0,10%1,2499-0,01%
ADC_correct51,2475-0,20%1,2487-0,10%1,2481-0,15%1,2493-0,06%

 

Como é possível verificar, pode-se obter uma melhora considerável de exatidão, minimizando bastante o erro. Note que o resultado referente ao passo 5, utilizando prioritariamente variáveis inteiras, possui sempre um erro maior devido à perda dos bits menos significativos nas operações de divisão (rotacionamento para direita).

 

Como sabemos, nas áreas relacionadas à engenharia nunca se ganha de todos os lados, ou seja, temos que escolher o que é mais importante, tempo/carga de processamento ou exatidão. No passo 4, utilizando apenas floats, são gastos 1015 pulsos de clock (Code Composer Studio), enquanto no passo 5 são gastos 519 pulsos de clock.

 

O código completo deste exemplo está disponível no meu github.

 

Até o próximo artigo.

NEWSLETTER

Receba os melhores conteúdos sobre sistemas eletrônicos embarcados, dicas, tutoriais e promoções.

Obrigado! Sua inscrição foi um sucesso.

Ops, algo deu errado. Por favor tente novamente.

Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.

Haroldo Amaral
Doutorando em Eng. Elétrica pela Poli-USP, mestre em Eng. Elétrica pela UNESP-Bauru e graduado em Tecnologia em Sistemas Biomédicos pela FATEC-Bauru.Um apaixonado por eletrônica que adora passar seu tempo "queimando alguns componentes" e escovando alguns bits. Entre outras paixões estão a música, uma boa reunião com os amigos, papear sobre tecnologia e afins.

Deixe um comentário

avatar
 
  Notificações  
Notificar