Otimização de energia STM32: um guia prático

Olá Habr!

Existem muitos artigos na rede sobre a operação de microcontroladores STM32 em dispositivos com eficiência de energia - geralmente dispositivos com bateria - no entanto, dentre eles, é lamentável que eles não entendam esse tópico fora da lista de modos de economia de energia e comandos SPL / HAL que os incluem (no entanto, a mesma reivindicação se aplica para a grande maioria dos artigos sobre como trabalhar com o STM32).

Enquanto isso, devido ao rápido desenvolvimento de residências inteligentes e todos os tipos de IoT, o tópico está se tornando cada vez mais relevante - nesses sistemas, muitos componentes são alimentados por bateria e são esperados anos de operação contínua a partir deles.

Vamos preencher essa lacuna com o exemplo do STM32L1 - um controlador muito popular, bastante econômico e, ao mesmo tempo, com alguns problemas específicos para esta série. Quase todas as opções acima também se aplicam ao STM32L0 e STM32L4 e, em termos de problemas e abordagens comuns, a outros controladores baseados nos núcleos Cortex-M.



O resultado prático deve se parecer com a foto acima (e sim, também falaremos sobre a aplicabilidade de multímetros e outros instrumentos de medição para tarefas semelhantes).

Modos de economia de energia no STM32L1


Os princípios básicos da economia de bateria são os principais modos de economia de energia do processador. Cada fabricante e cada série de controladores têm seus próprios (um conjunto específico é uma extensão de fornecedor dos modos principais do Cortex-M padrão com várias nuances em relação à periferia, tensões de alimentação etc.).

Especificamente, o STM32L1, que pertence à série econômica de controladores e, em conexão com isso, entre outras coisas, recebeu um conjunto expandido de configurações de energia, temos o seguinte:

  • Executar - modo normal. Tudo incluído, todos os periféricos disponíveis, frequência de até 32 MHz.
  • Low Power Run (LP Run) - um modo especial com uma frequência de operação dentro de 131 kHz e consumo máximo, considerando toda a periferia , 200 μA. No modo LP Run, o regulador de energia do processador entra em um modo econômico especial, que economiza até cinquenta microamperes em comparação com o trabalho com a mesma frequência no modo Run.
  • Sono - suspensão do núcleo, mas com a preservação de todas as frequências do relógio. Os periféricos do processador podem continuar funcionando se o kernel não precisar, mas pode ser desligado automaticamente.
  • Low Power Sleep (LP Sleep) - uma combinação de Sleep com a transição do estabilizador para o modo econômico. A frequência do relógio não é superior a 131 kHz, o consumo total não é superior a 200 μA.
  • Stop - uma parada completa de todas as frequências do relógio, exceto o gerador de "relógio" 32768 Hz, externo ou interno. No caso do STM32L1, apenas o relógio em tempo real continua funcionando nesse modo, tudo o resto para completamente; nos processadores mais recentes, alguns periféricos podem ter freqüência baixa. Quase todas as pernas do processador mantêm seu estado. O conteúdo da RAM é salvo, as interrupções externas continuam a funcionar.
  • Em espera - um desligamento completo do núcleo do processador, RAM e todos os periféricos, exceto os relógios em tempo real. A RAM não é salva (ou seja, do ponto de vista do software, sair no modo de espera é quase o mesmo que distorcer a fonte de alimentação - comece do começo), o RTC continua a funcionar. Interrupções externas não funcionam, exceto por três pernas especiais do WKUPx, cuja alternância de 0 para 1 desperta o processador.

A entrada de cada um dos modos é bastante simples - você precisa definir os sinalizadores em três a cinco registros, após o qual (para modos de suspensão) chama a instrução WFI ou WFE, esta é a instrução Cortex-M padrão, significa "Wait For Interrupt" e "Wait For Event" . Dependendo dos sinalizadores (eles são descritos no Manual de Referência do processador, para STM32L1 é RM0038 ), o próprio processador entrará neste modo neste comando.

Além disso, seria bom proibir interrupções (isso não afetará a capacidade de eventos externos e internos de acordar o processador do modo de suspensão) e aguardar que os dados sejam salvos dos registros na memória, caso ocorra repentinamente, usando o comando DSB.

Por exemplo, é assim que parece o modo de parada:

/*  PDDS    Stop  Standby,    */ PWR->CR &= ~(PWR_CR_PDDS); /*  Wakeup   ,      */ PWR->CR |= PWR_CR_CWUF; /*    low-power ,    Stop -    */ PWR->CR |= PWR_CR_LPSDSR; /*    Vref   */ PWR->CR |= PWR_CR_ULP; /*     Cortex-M,  Stop,  Standby -   Deep Sleep */ /*      Deep Sleep */ SCB->SCR |= (SCB_SCR_SLEEPDEEP_Msk); /*  ;       */ unsigned state = irq_disable(); /*      */ __DSB(); /*  */ __WFI(); /*    */ init_clk(); /*     */ irq_restore(state); 

O WFI é uma instrução de bloqueio; nele, o processador entra em sono profundo e não sai até que ocorra algum tipo de interrupção. Sim, repito, apesar do fato de termos desativado explicitamente as interrupções, o processador responderá a elas e acordará - mas só iniciará o processamento depois que as ligarmos novamente. E isso tem um significado profundo.

No código acima, após o WFI, algum tipo de reinicialização das frequências de operação não está acontecendo apenas - o fato é que L1 sempre deixa o sono profundo a uma frequência de 4,2 MHz e com um gerador MSI interno como fonte dessa frequência. Em muitas situações, obviamente, você não deseja que o manipulador de interrupção que ativa o processador comece a funcionar nessa frequência - por exemplo, porque as frequências de todos os timers, UART e outros barramentos desaparecerão; portanto, primeiro restauramos as frequências operacionais (ou, se quisermos permanecer no MSI, recalculamos os barramentos necessários em 4,2 MHz) e depois mergulhamos em interrupções.

Na prática, os dois modos mais usados ​​são Run e Stop. O fato é que o LP Run é extremamente lento e não faz sentido se o processador precisar executar alguns cálculos e não apenas esperar por eventos externos, e o Sleep e o LP Sleep não são muito econômicos (consumo de até 2 mA) e são necessários se você precisar economize pelo menos um pouco, mas ao mesmo tempo deixe os periféricos em funcionamento e / ou forneça a reação mais rápida do processador aos eventos. Tais requisitos existem, mas no geral não com muita frequência.

O modo de espera geralmente não é usado, porque depois que é impossível continuar de onde você parou devido ao zeramento da RAM, também existem alguns problemas com dispositivos externos, que discutiremos abaixo, que exigem soluções de hardware. No entanto, se o dispositivo foi projetado com isso em mente, o modo de espera pode ser usado como um modo "desligado", por exemplo, durante o armazenamento prolongado deste dispositivo.

Na verdade, na apresentação disso, a maioria dos manuais geralmente se rompe triunfante.

O problema é que, seguindo-os, você ficará triste com 100-200 μA de consumo real em vez dos prometidos 1,4 μA em Stop com o horário de trabalho - mesmo na depuração de referência Nucleo, que não possui chips, sensores externos etc. a que poderia ser atribuído.

E não, seu processador está funcionando, não há nada na errata e você fez tudo certo.

Só não até o fim.

Síndrome das pernas inquietas


O primeiro problema STM32L1, sobre o qual alguns artigos mencionam, mas geralmente são lembrados apenas em fóruns, quando no terceiro dia de discussão, de onde vieram os 100-200 μA, alguém se lembra da existência do AN3430 e chega à 19ª página nele - isso estado das pernas por padrão.

Observo que até o próprio STMicro se refere ao problema pelas mangas, e na maioria dos documentos em que a otimização do consumo de energia é considerada, ela é limitada a uma ou duas frases com o conselho de puxar as pernas não usadas no chão ou colocá-las no modo de entrada analógica, sem explicar os motivos.

O triste é que, por padrão, todas as pernas estão configuradas como entradas digitais (0x00 no registro GPIOx_MODER). Um gatilho Schmitt está sempre na entrada digital, o que melhora a imunidade a ruídos dessa entrada e é completamente independente - é um elemento lógico simples, um buffer com histerese que não requer relógio externo.

No nosso caso, isso significa que desligamos o relógio no modo Stop e os gatilhos de Schmitt continuaram a funcionar como se nada tivesse acontecido - dependendo do nível do sinal de entrada, eles trocam suas saídas para 0 e 1.

Ao mesmo tempo, parte das pernas do processador em um circuito típico fica suspensa no ar - ou seja, não há sinal inteligível nelas. Seria errado pensar que a ausência de um sinal claro significa que nessas pernas 0 não existe, nessas pernas devido à sua alta impedância de entrada, há algum ruído aleatório de valor indeterminado, desde captadores e corrente que flui das faixas vizinhas até o primeiro canal de televisão, se o pé for longo o suficiente para servir como antena (no entanto, as TVs analógicas na Rússia serão desligadas em breve, o que deve levar a uma redução no consumo de energia dos microcontroladores configurados incorretamente).

De acordo com essas flutuações, a perna, de alguma maneira aleatória, alterna entre 0 e 1. A lógica do CMOS consome corrente ao alternar. Ou seja, uma perna do processador suspensa no ar, configurada no modo de entrada digital, consome uma corrente perceptível em si mesma .

A saída disso é simples - quando você inicia o programa, você precisa configurar todas as pernas para o estado da entrada analógica; O STM32 possui formalmente todas as pernas, sem exceção, independentemente de estarem ou não conectadas ao ADC, e difere da entrada digital somente na ausência de um gatilho Schmitt na entrada.



Para fazer isso, basta escrever o valor 0xFF ... FF em todos os registros GPIOx_MODER; é mais fácil fazer isso, como mencionado acima, logo no início e, durante o decorrer da peça, você reconfigurará as pernas individuais, conforme necessário neste dispositivo.

Aqui, no entanto, surge um problema de segunda ordem - é bom se o seu firmware funcionar em um controlador específico e, portanto, você sempre sabe o que x existe no GPIOx. Pior ainda se o firmware for universal - o STM32 pode ter até 8 portas, mas pode ser menor; Quando você tenta gravar em uma porta que não existe nesse modelo de controlador, você recebe Hard Fault, ou seja, falha no kernel.

No entanto, mesmo este caso pode ser contornado - o Cortex-M permite que você verifique os endereços quanto à sua validade; além disso, no caso de M3 e M4, a verificação é geralmente trivial e, no M0, requer alguma mágica, mas é realizável ( detalhes podem ser lidos aqui , não vamos apreciar este artigo )

Ou seja, em geral, o processador foi iniciado, sintonizou as frequências - e passou imediatamente por todas as portas GPIO disponíveis, gravando-as em MODER (o código abaixo foi escrito para o RIOT OS, mas, em geral, é claro sem comentários e pode ser transferido para três minutos qualquer outra plataforma).

 #if defined(CPU_FAM_STM32L1) /* switch all GPIOs to AIN mode to minimize power consumption */ GPIO_TypeDef *port; /* enable GPIO clock */ uint32_t ahb_gpio_clocks = RCC->AHBENR & 0xFF; periph_clk_en(AHB, 0xFF); for (uint8_t i = 0; i < 8; i++) { port = (GPIO_TypeDef *)(GPIOA_BASE + i*(GPIOB_BASE - GPIOA_BASE)); if (cpu_check_address((char *)port)) { port->MODER = 0xffffffff; } else { break; } } /* restore GPIO clock */ uint32_t tmpreg = RCC->AHBENR; tmpreg &= ~((uint32_t)0xFF); tmpreg |= ahb_gpio_clocks; periph_clk_en(AHB, tmpreg); #endif 

Observo que isso se aplica apenas às séries L1, em L0 e L4 a experiência foi levada em consideração e, por padrão, configuram todas as portas como entradas analógicas na inicialização.

Depois de executar todos esses procedimentos com cuidado, você preenche o firmware no dispositivo finalizado ... e coloca 150 uA no modo Stop no processador e todos os chips externos desligados, apesar de suas estimativas serem as mais pessimistas, provenientes das folhas de dados de tudo o que você soldou na placa dar não superior a 10 μA.

Além disso, você tenta levar o processador para o modo de espera em vez de parar, ou seja, basta desligá-lo quase completamente - e, em vez de cair, o consumo de energia aumenta em três vezes, chegando perto de meio miliampere!

Não há necessidade de entrar em pânico. Como você deve ter adivinhado, você fez tudo certo. Mas não até o fim.

Síndrome das Pernas Inquietas - 2


O próximo problema tem duas partes.

O primeiro é bastante óbvio: se o seu dispositivo não consiste em um microcontrolador, é importante não esquecer que os chips externos também têm sinais de entrada nos quais os gatilhos Schmitt ficam travados e que, além disso, podem despertar a lógica interna do chip. Por exemplo, um chip que é retirado e retirado do modo de suspensão pela equipe do UART tentará ler dados dele com qualquer movimento nesse barramento.

Assim, se todas essas pernas estiverem penduradas no ar, não teremos nada de bom.

Sob quais condições eles acabam no ar?

Primeiro, quando o controlador entra no modo de espera, todos os GPIOs são transferidos para o estado High-Z, com alta resistência - ou seja, os chips externos conectados a eles estão no ar. É impossível consertar isso programaticamente no STM32L1 (em outras séries e outros controladores, isso acontece de maneiras diferentes); portanto, a única saída - em um sistema que usa o modo de espera, as entradas de chips externos devem ser puxadas para o terra ou alimentadas por resistores externos.

Um nível específico é escolhido para que a linha fique inativa do ponto de vista do chip:

  • 1 para UART TX
  • 0 para SPI MOSI
  • 0 para SPI CLK no modo SPI 0 ou 1
  • 1 para SPI CLK com modo SPI 2 ou 3
  • 1 para SPI CS

Em segundo lugar, no STM32 ao usar o modo Stop (sic!) , O estado dos GPIOs conectados aos blocos de hardware internos das interfaces pode ser ... diferente. Ou seja, a mesma interface SPI, quando configurada, em Stop, de repente se torna uma entrada digital ou, em geral, High-Z - com as conseqüências correspondentes para chips externos pendurados nela. Enquanto a documentação declara que as pernas estão em boas condições, você pode confiar a priori somente se usar as pernas como GPIOs regulares.

Você não pode entendê-lo e perdoá-lo, mas pode-se lembrar e corrigi-lo: para interfaces que se comportam dessa maneira, você deve adicionar a troca forçada ao GPIO normal com níveis correspondentes aos níveis inativos dessa interface na função de cuidados com o sono. Depois de adormecer, as interfaces podem ser restauradas.

Por exemplo, o mesmo SPI antes de dormir (por uma questão de simplicidade, pego o código do RIOT OS, fica claro que o mesmo é fácil de implementar nos registros):

 /* specifically set GPIOs used for external SPI devices */ /* MOSI = 0, SCK = 0, MISO = AIN for SPI Mode 0 & 1 (CPOL = 0) */ /* MOSI = 0, SCK = 1, MISO = AIN for SPI Mode 2 & 3 (CPOL = 1) */ for (i = 0; i < SPI_NUMOF; i++) { /* check if SPI is in use */ if (is_periph_clk(spi_config[i].apbbus, spi_config[i].rccmask) == 1) { /* SPI CLK polarity */ if (spi_config[i].dev->CR1 & (1<<1)) { gpio_init(spi_config[i].sclk_pin, GPIO_IN_PU); } else { gpio_init(spi_config[i].sclk_pin, GPIO_IN_PD); } gpio_init(spi_config[i].mosi_pin, GPIO_IN_PD); gpio_init(spi_config[i].miso_pin, GPIO_AIN); } } 

Observe que as saídas aqui são configuradas não como GPIO_OUT com nível 0 ou 1, mas como entradas com pull-up de 0 ou 1 - este não é um ponto fundamental, mas fornece segurança adicional se você cometer um erro e tentar executar pull-push com algum tipo de um chip externo puxando essa perna para o outro lado. Com o GPIO_OUT, você pode organizar um curto-circuito, com o GPIO_IN com um pull-up - nunca.

Além disso, o sinal SPI CS não é afetado - nesse caso, é gerado programaticamente, ou seja, por um GPIO normal e mantém seu estado em um sonho com confiança.

Para restaurar o estado da perna ao sair do sono, basta escrever os valores dos registros que serão alterados (MODER, PUPDR, OTYPER, OSPEEDR - veja a situação em um caso particular) na entrada, em variáveis, e revertê-los nos registros ao sair do sono .

E agora ... ta daaam! Imagem do título. Um micro e meio.

Mas é muito cedo para comemorar. Nisso concluímos a otimização estática do consumo de energia e, à nossa frente, é dinâmico .

Achilles vs Turtle


O que é melhor - coma mais e corra mais rápido ou coma menos, mas corra mais devagar? No caso de microcontroladores, a resposta a essa pergunta é duas vezes não trivial.

Primeiro, as frequências de operação podem ser alteradas em uma faixa muito ampla - de 65 kHz (LP Run) a 32 MHz no modo normal. Como qualquer chip CMOS, o STM32 possui dois componentes no consumo de energia - estático e dinâmico; o segundo depende da frequência, o primeiro é constante. Como resultado, o consumo de energia não diminuirá tão rapidamente quanto a frequência e a produtividade operacionais e, dependendo da tarefa, a frequência ideal do ponto de vista da eficiência energética pode ser diferente - onde você precisa esperar por algum evento, mas, por algum motivo, não consegue dormir, haverá baixas frequências são eficazes, onde você só precisa trilhar números - altos. Em tarefas típicas de "média hospitalar", geralmente não faz sentido ficar abaixo de 2-4 MHz.

Em segundo lugar, e este é um momento menos trivial, a taxa de adormecer depende da frequência de trabalho e da maneira como é recebida.

O pior caso é adormecer a uma frequência de 32 MHz a partir de um quartzo externo (lembre-se de que o STM32L1 acorda em um oscilador interno de 4 MHz), porque consiste em três estágios:

  • na verdade, o processador acorda do sono
  • estabilização de geração de quartzo (1-24 MHz)
  • Estabilização de geração de PLL (32 MHz)

Na verdade, tirar o processador do sono aqui é o menor problema, com uma frequência de 4,2 MHz e leva cerca de 10 μs. Mas a estabilização do quartzo pode levar até 1 ms (embora normalmente para ressonadores de alta velocidade ainda seja mais rápido, da ordem de várias centenas de microssegundos), o acesso ao modo PLL é de mais 160 μs.

Esses atrasos podem não ser significativos do ponto de vista do consumo de energia para um sistema que raramente acorda (não mais que uma vez por segundo), mas onde o período entre as ativações é de dezenas de milissegundos e menos, e as ativações são curtas, a sobrecarga começa a fazer uma adição já mensurável levando em consideração que durante a ativação, o processador consome uma corrente relativamente pequena.

O que pode ser feito com isso? Em geral, a resposta é óbvia: tente evitar o uso de quartzo externo. Por exemplo, um programa no qual existem subtarefas pesadas raras que exigem relógio preciso (digamos, das triviais - troca de dados UART) e subtarefas simples e frequentes, podem decidir por si mesmo a cada despertar, se é necessário ir para quartzo externo, ou será mais fácil (e mais rápido!) executar a tarefa atual no gerador MSI, no qual o processador já acordou sem gastar muito tempo inicializando as frequências.

Nesse caso, no entanto, pode ser necessário ajustar as frequências do relógio da periferia, bem como ajustar os modos de acesso à memória flash (o número de ciclos de atraso), à tensão do núcleo do processador (no STM32L1 é selecionado entre três valores possíveis), etc. No entanto, no que diz respeito aos modos de operação do kernel e da memória, muitas vezes é possível ajustá-los escolhendo os recomendados para a frequência máxima usada, pois a operação não ideal do núcleo em frequências mais baixas não dará uma mudança significativa no desempenho prático e no consumo de energia devido ao pequeno volume de tarefas nessas frequências. realizada.

Embora todas essas medidas já se apliquem ao ajuste fino de modos (e, por exemplo, a maioria dos sistemas operacionais e bibliotecas nem sequer sabem nada próximo da caixa), em alguns casos, elas podem levar a uma diminuição no consumo médio na escala de unidades de porcentagem, e às vezes até mais. Imagine, por exemplo, um hidrômetro que examine os contatos de um comutador de palheta a cada 50 ms, enquanto a pesquisa real leva várias dezenas de microssegundos - você deseja adicionar ~ 500 μs a essa altura para ativar o controlador?

Insuportavelmente longo segundo


Outro problema que não está diretamente relacionado à conservação de energia, mas inevitavelmente surge em conexão com ela - como contar intervalos de tempo inferiores a 1 segundo?

O fato é que no STM32L1 existe apenas um timer que funciona no modo Stop - este é o RTC, a unidade de tempo padrão durante 1 segundo. Ao mesmo tempo, nos programas, existem constantemente intervalos de tempo de unidades, dezenas e centenas de milissegundos, para levar pelo menos o mesmo medidor de água.

Como ser Funciona em processadores com temporizadores LPTIM, com clock de 32768 Hz? Uma boa opção, de fato, mas nem sempre é necessária. É possível sem ele.

Não em todos os STM32L1, mas começando com o gato. 2 (esses são os processadores STM32L151CB-A, STM32L151CC e mais recentes), o bloco RTC foi complementado com um novo registro - SSR, SubSeconds Register. Mais precisamente, não foi tão complementado quanto tornado visível para o usuário, além dos alarmes de segundo segundo ALRMASSR e ALRMBSSR foram adicionados.

Este registro não contém nenhuma unidade de tempo compreensível; foi extraído de um contador técnico interno. No STM32L1, um relógio que marca a 32768 Hz passa por dois contadores divisores, assíncrono e síncrono, que no total normalmente o dividem por 32768 para obter um tique de 1 segundo para o relógio. Portanto, SSR é apenas o valor atual do segundo contador.

Embora o SSR conte não em milissegundos, mas em suas unidades, a dimensão dessas unidades pode ser alterada alterando a proporção dos divisores do contador síncrono e assíncrono, mantendo seu coeficiente total igual a 32768 para obter o padrão de 1 segundo na entrada do RTC. Conhecendo esses coeficientes, podemos calcular o preço de uma divisão do SSR em milissegundos e, a partir daqui, podemos avançar para a programação de alarmes de subsegundos.

Deve-se notar que um pré-contador assíncrono é mais econômico que um SSR síncrono e, portanto, defini-lo como 1, e já dividindo a frequência de entrada no SSR por 32768, tendo recebido apenas 30 μs, é energicamente desvantajoso. Para nós mesmos, determinamos o valor ideal para o divisor preliminar 7, para síncrono - 4095 ((7 + 1) * (4095 + 1) = 32768). Com uma redução adicional no divisor preliminar, o consumo de energia do RTC começa a crescer de forma mensurável - por uma fração de um microampere, mas, como o comparamos com a "referência" 1,4 μA no modo Stop, até as frações são importantes. Por padrão, para STM32L1 esses valores são 127 e 255, ou seja, o preço de referência é de cerca de 4 ms, o que é um pouco difícil.

Se você quiser se aprofundar no código, finalizamos no momento oportuno o driver RTC padrão do RIOT OS para oferecer suporte a intervalos RTC_SSR e milissegundos. Desde então, o usamos literalmente em todas as etapas (e, como trabalhamos no sistema operacional, um serviço também fica em cima dele, o que permite que você pendure praticamente qualquer número de tarefas com períodos arbitrários em um temporizador de hardware com um toque no pulso).

A mesma abordagem é transferida para os controladores STM32L0 e STM32L4, todos os modelos com o registro RTC_SSR; isso elimina a necessidade de temporizadores LPTIM e unifica o código para diferentes plataformas.

Como entender que um multímetro está mentindo


Certamente, depois de todas as otimizações, surge a pergunta legítima: o que, de fato, conseguimos?Sem saber a resposta, é possível limitar-se completamente a um WFE com sinalizadores configurados corretamente, dormir e obter seus 200-500 μA.

A maneira mais tradicional de medir corrente é, obviamente, um multímetro. Entender que ele está deitado sobre uma carga como um microcontrolador com seu consumo dinâmico é muito simples - se estiver ligado, está mentindo.

Isso, no entanto, não significa que o multímetro seja inútil nessa questão. Você só precisa poder aplicá-lo.

Primeiramente, um multímetro é uma coisa muito lenta, um tempo típico para uma contagem é uma segunda escala, um tempo típico para alterar o estado de um microcontrolador é uma escala de microssegundos. Em um sistema que altera seu consumo nesse ritmo, o multímetro simplesmente mostra valores aleatórios.

No entanto, uma das variáveis ​​não aleatórias de interesse para nós é o consumo do microcontrolador no modo de suspensão; se exceder significativamente o valor estimado em folhas de dados, então algo está claramente errado. Este é o consumo de um sistema estático , ou seja, pode ser medido com um multímetro.

O método mais trivial mostrado na foto-título é um multímetro no modo microamperímetro, que agora está na maioria dos modelos de gama média e possui boa precisão e excelente resolução. O UT120C possui uma resolução de 0,1 μA com uma precisão certificada de ± 1% ± 3 descargas, o que é suficiente para nós.

Existe apenas um problema nesse modo - os multímetros possuem uma resistência em série grande, uma escala de centenas de ohms; portanto, no modo normal, um microcontrolador com esse multímetro no circuito de potência simplesmente não inicia. Felizmente, as posições de "mA" e "uA" em quase todos os instrumentos da balança estão próximas, os soquetes para medição em ambos os intervalos são os mesmos, para que você possa iniciar com segurança o controlador no limite de "mA" e, quando dormir, clique em "uA "- isso acontece rápido o suficiente para que o controlador não tenha tempo para perder energia e reiniciar.

Observe que, se o controlador apresentar picos de atividade, esse método não será aplicável. Por exemplo, o timer do watchdog é redefinido a cada 15 segundos no firmware do dispositivo - nesses momentos, o multímetro consegue mostrar algo na região de 27 μA, o que, obviamente, não tem nada a ver com o clima em Marte. Se algo arbitrariamente curto ocorrer no seu sistema com mais frequência do que uma vez a cada 5 a 10 segundos, o multímetro simplesmente estará mentindo.

Outra maneira de medir a estática(Estou destacando diretamente essa palavra) o consumo de um multímetro é uma medida da queda em uma derivação externa. Se você deseja medir correntes ultra-pequenas na escala de algumas dezenas de microamperes, precisará colocar uma derivação grande (por exemplo, 1 kOhm) e paralelamente a ela - um diodo Schottky em conexão direta. Se o shunt cair mais de 0,3 V, o diodo abrirá e limitará a queda de tensão, e até 0,3 V você poderá medir com segurança a queda com um multímetro na faixa de milivolts, 1 mV = 1 μA.

Infelizmente, não funcionará para medir uma queda em um desvio de baixa impedância com um multímetro típico - dispositivos de classe média, mesmo que mostrem algo abaixo de 100 μV, são infelizes nesta faixa. Se você possui um bom dispositivo de mesa que pode mostrar 1 uV, não precisa mais do meu conselho.

No entanto, as estáticas são boas, mas e a dinâmica? Como avaliar o mesmo efeito de diferentes frequências no consumo médio de energia?

Tudo é complicado aqui.

Vamos anotar os requisitos básicos:

  • faixa de corrente de pelo menos 1 μA - 100 mA (10 ^ 5)
  • período de medição não superior a 10 μs
  • queda de tensão não superior a 100 mV
  • duração da medição - ilimitada

Se simplesmente traduzirmos isso diretamente em números, obteremos um ADC relativamente rápido e não inferior a 18 bits com um viés de entrada inferior a 30 μV, um front end analógico capaz de medir tensões de 1 μV e uma interface rápida para o computador que nos permitirá transferir tudo isso e salve.

E tudo isso para um único uso.

Você vê, sim, por que essas coisas não estão em cada canto de dez dólares? O Keysight N6705C na primeira aproximação atende aos nossos requisitos, apenas custa US $ 7960.

Nas soluções de orçamento, por exemplo, o SiLabs integra a medição atual em seus depurações - as características do sistema Advanced Energy Monitoring (AEM) dependem do modelo de depuração específico e têm o maior problema com a velocidade da medição. Nos antigos "kits de iniciação", o STK3300 / 3400 é de apenas 100 Hz, nos mais recentes debuga o STK3700 / 3800 (facilmente reconhecível pelo textolite preto) - 6,25 kHz, e em modelos mais antigos da série DK debuga, pode atingir até 10 kHz, mas também custa eles já são $ 300 +. Para tarefas sérias, a SiLabs recomenda oficialmente o mencionado Keysight.

Em princípio, esse dispositivo pode ser projetado por você mesmo - primeiro, você precisa de amplificadores operacionais muito bons com viés mínimo de entrada, como o OPA2335. Esses amplificadores operacionais são colocados no mesmo shunt de 2 a 3 peças com diferentes fatores de amplificação, todos eles são enrolados em entradas ADC diferentes (com essa abordagem é bem possível usar o microcontrolador embutido), então, a cada aquisição de dados, é determinado programaticamente qual dos amplificadores operacionais em um determinado o momento não está sobrecarregado, as leituras são contadas.

O problema da velocidade de transferência de dados para um computador é resolvido de maneira simples - uma vez que, para fins práticos, estamos interessados ​​principalmente no consumo médio do sistema na vida real, as leituras de microssegundos podem ser coletadas no microcontrolador integrado do medidor e a média aritmética de uma escala razoável de milissegundos pode ser enviada.

Além disso, como mostra a prática, é muito útil ter um medidor de registro, embora simples e pouco preciso, mas sempre à mão - para não ser surpreendido com algum tipo de alteração de firmware interrompida pela economia de energia.

Por exemplo, incorporamos um em nosso adaptador USB padrão UMDK-RF, que é constantemente usado na depuração de firmware - ele já possui um programador SWD com suporte para o protocolo DAPLink, uma ponte USB-UART e lógica de gerenciamento de energia, respectivamente, e possui um medidor de consumo quase de graça. O medidor em si é um shunt de 1 Ohm e um amplificador INA213 (ganho de 50 vezes, deslocamento de zero típico de 5 μV): O



amplificador é conectado diretamente à entrada do ADC do microcontrolador (STM32F042F6P6), o ADC processa com um período de 10 μs usando um temporizador de hardware e via USB os dados médios são emitidos por um intervalo de 100 ms. Como resultado, alterando algo na lógica do firmware, você pode simplesmente fumar ou tomar um café, deixar o dispositivo em cima da mesa e, retornando, observe uma programação como esta:



Obviamente, a precisão de um dispositivo "livre" não é alta - com um ADC de 12 bits e um amplificador, o quantum mínimo é de 16 μA, mas é extremamente útil para avaliar rápida e regularmente o comportamento de dispositivos depurados do ponto de vista do consumo de energia. No final, se você fizer algo errado no firmware ou no dispositivo, com uma garantia muito alta, poderá sair de unidades de microamperes pelo menos centenas, e isso será claramente visível.



Outro bônus interessante é que, como os dados são enviados para a porta COM virtual em forma de texto (valores em microamperes), você pode posicionar a janela do terminal ao lado da janela que mostra o console do dispositivo e observar o consumo de energia ao mesmo tempo em que as mensagens de depuração.

Eu me gabo disso por um motivo, mas para oferecer a todos que desejam usar esse programador de depurador mínimo (e muito barato!) Em seus próprios projetos.

Você pode desenhar o diagrama aqui ( fonte no DipTrace ), arrastar o firmware aqui (brunch umdk-rf, ao criar o destino é UMDK-RF, com base no projeto dap42 ). O diagrama é confuso, mas espero que os pontos principais sejam claros, o firmware seja escrito em C usando o libopencm3 e seja montado com o usual arm-none-eabi-gcc. Como funções adicionais, o firmware possui gerenciamento de energia, captando sinais de sobrecarga das teclas de controle e inserindo o controlador conectado ao seu carregador de inicialização nativo com um longo toque em um botão.

Nota: se você deseja que o botão de inicialização traga regularmente o controlador do programador para o carregador de inicialização, ele deve ter a polaridade da conexão alterada, a opção de edição de bytes do controlador na primeira inicialização e a entrada do programa no carregador de inicialização removida e a polaridade de interrupção para regular funções deste botão.

Você pode ver como a corrente é medida em um par de amplificadores operacionais com diferentes fatores de ganho (por exemplo, para melhorar o depurador descrito acima para suas tarefas), aqui (página 9), uma opção alternativa mais tradicional - com um amplificador operacional e um ADC de 24 bits caro - A TI possui (EnergyTrace na página 5).

PS Observe que durante a depuração com um UART ou JTAG / SWD conectado, uma pequena corrente também pode vazar pelas pernas, o que não acontecerá durante a operação real do dispositivo. Portanto, no UMDK-RF, cerca de 15 μA vazam no SWD (e, portanto, na foto do cabeçalho, medições com um multímetro são feitas na versão antiga da placa, sem SWD), e no STM32 Nucleo houve casos com fluxo espúrio no SWD de cerca de 200 μA . As placas de depuração usadas para medição devem ser verificadas quanto a esses recursos - desconectando suas linhas de interface, se houver essa possibilidade, ou comparando os resultados com o consumo do dispositivo medido sem a instalação para depuração, por exemplo, com um multímetro no modo estático.

Em vez de uma conclusão


Espero que você já tenha entendido o erro que cometeu ao escolher a programação de microcontroladores como sua principal especialidade.

Source: https://habr.com/ru/post/pt430218/


All Articles