Optimización de energía STM32: una guía práctica

Hola Habr!

Hay muchos artículos en la red sobre el funcionamiento de los microcontroladores STM32 en dispositivos de eficiencia energética, generalmente dispositivos alimentados por batería, sin embargo, entre ellos es lamentable que no entiendan este tema fuera de la lista de modos de ahorro de energía y comandos SPL / HAL que los incluyen (sin embargo, se aplica el mismo reclamo) a la gran mayoría de artículos sobre cómo trabajar con STM32).

Mientras tanto, debido al rápido desarrollo de hogares inteligentes y todo tipo de IoT, el tema se está volviendo cada vez más relevante: en tales sistemas, muchos componentes funcionan con baterías y se esperan años de operación continua de ellos.

Llenaremos este vacío con el ejemplo de STM32L1, un controlador muy popular, bastante económico y al mismo tiempo que tiene algunos problemas específicos de esta serie. Casi todo lo anterior también se aplicará a STM32L0 y STM32L4, y en términos de problemas y enfoques comunes, a otros controladores basados ​​en núcleos Cortex-M.



El resultado práctico debería parecerse a la foto de arriba (y sí, también hablaremos sobre la aplicabilidad de multímetros y otros instrumentos de medición a tareas similares).

Modos de ahorro de energía en STM32L1


Los conceptos básicos del ahorro de batería son los principales modos de ahorro de energía del procesador. Cada fabricante y cada serie de controladores tienen los suyos (un conjunto específico es una extensión del proveedor de los modos de núcleo Cortex-M estándar con varios matices con respecto a la periferia, los voltajes de suministro, etc.).

Específicamente, el STM32L1, que pertenece a la serie económica de controladores, y en relación con esto, entre otras cosas, recibió un conjunto ampliado de configuraciones de energía, tenemos lo siguiente:

  • Ejecutar - modo normal. Todo incluido, todos los periféricos disponibles, frecuencia de hasta 32 MHz.
  • Low Power Run (LP Run) : un modo especial con una frecuencia de funcionamiento dentro de 131 kHz y un consumo máximo, considerando toda la periferia , 200 μA. En el modo LP Run, el regulador de potencia del procesador entra en un modo económico especial, que ahorra hasta cincuenta microamperios en comparación con el funcionamiento a la misma frecuencia en el modo Run.
  • Suspender : suspensión del núcleo, pero con la preservación de todas las frecuencias de reloj. Los periféricos del procesador pueden continuar funcionando si el núcleo no lo necesita, pero se puede apagar automáticamente.
  • Low Power Sleep (LP Sleep) : una combinación de Sleep con la transición del estabilizador al modo económico. La frecuencia del reloj no es superior a 131 kHz, el consumo total no es superior a 200 μA.
  • Parar : una parada completa de todas las frecuencias de reloj, excepto el generador de "reloj" 32768 Hz, externo o interno. En el caso de STM32L1, solo el reloj en tiempo real continúa funcionando en este modo, todo lo demás se detiene por completo; En los procesadores más nuevos, algunos periféricos pueden sincronizarse a bajas frecuencias. Casi todas las patas del procesador conservan su estado. El contenido de la RAM se guarda, las interrupciones externas continúan funcionando.
  • En espera : un apagado completo del núcleo del procesador, la RAM y todos los periféricos, excepto los relojes en tiempo real. La RAM no se guarda (es decir, desde el punto de vista del software, dejarlo en modo de espera es casi lo mismo que la distorsión de potencia; comience de nuevo), el RTC continúa marcando. Las interrupciones externas no funcionan, excepto por tres patas especiales WKUPx, cuyo cambio de 0 a 1 despierta el procesador.

Ingresar a cada uno de los modos es bastante simple: debe configurar los indicadores en tres a cinco registros, después de lo cual (para los modos de suspensión) llame a la instrucción WFI o WFE, esta es la instrucción estándar de Cortex-M, significa "Esperar interrupción" y "Esperar evento" . Dependiendo de los indicadores (se describen en el Manual de referencia del procesador, para STM32L1 es RM0038 ), el procesador mismo entrará en este modo con este comando.

Además, sería bueno prohibir las interrupciones (esto no afectará la capacidad de los eventos externos e internos para despertar al procesador del modo de suspensión) y esperar a que los datos se guarden de los registros a la memoria si sucede de repente, usando el comando DSB.

Por ejemplo, así es como se ve el 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); 

WFI es una instrucción de bloqueo, en él el procesador entrará en suspensión profunda y no saldrá hasta que ocurra algún tipo de interrupción. Sí, repito, a pesar de que desactivamos explícitamente las interrupciones, el procesador responderá a ellas y se despertará, pero solo comenzará a procesarse después de que las volvamos a encender. Y esto tiene un significado profundo.

En el código anterior, después de WFI, algún tipo de reinicialización de las frecuencias de operación no es así: el hecho es que L1 siempre deja el sueño profundo a la frecuencia de 4.2 MHz y con el generador interno MSI como fuente de esta frecuencia. En muchas situaciones, obviamente no desea que el controlador de interrupciones que activa el procesador comience a funcionar a esta frecuencia, por ejemplo, porque las frecuencias de todos los temporizadores, UART y otros buses se volarán; por lo tanto, primero restauramos las frecuencias de operación (o, si queremos permanecer en MSI, recalculamos los buses necesarios por debajo de 4.2 MHz), y luego nos sumergimos en las interrupciones.

En la práctica, los dos modos más utilizados son Run y ​​Stop. El hecho es que LP Run es dolorosamente lento y no tiene sentido si el procesador necesita realizar algunos cálculos y no solo esperar eventos externos, y Sleep y LP Sleep no son demasiado económicos (consumo de hasta 2 mA) y son necesarios si lo necesita ahorre al menos un poco, pero al mismo tiempo deje los periféricos en funcionamiento y / o proporcione la reacción más rápida posible del procesador a los eventos. Tales requisitos existen, pero en general no muy a menudo.

El modo de espera generalmente no se usa, porque después de que es imposible continuar desde donde lo dejó debido a la puesta a cero de RAM, también hay algunos problemas con dispositivos externos, que analizaremos a continuación, que requieren soluciones de hardware. Sin embargo, si el dispositivo se diseñó teniendo esto en cuenta, el modo de espera se puede utilizar como modo "apagado", por ejemplo, durante el almacenamiento a largo plazo de este dispositivo.

En realidad, en la presentación de esto, la mayoría de los manuales generalmente se rompen triunfalmente.

El problema es que, siguiéndolos, obtendrá triste 100-200 μA de consumo real en lugar de los prometidos 1.4 μA en Stop con las horas de trabajo, incluso en la depuración de referencia de Nucleo, que no tiene chips externos, sensores, etc. a lo que podría atribuirse.

Y no, su procesador está funcionando, no hay nada en las erratas, e hizo todo bien.

Simplemente no hasta el final.

Síndrome de piernas inquietas


El primer problema STM32L1, sobre el cual algunos artículos mencionan, pero que con mayor frecuencia solo se recuerdan en foros, cuando en el tercer día de discusión, de dónde provienen los 100-200 μA, alguien recuerda la existencia de AN3430 y llega a la página 19 en él. estado de las piernas por defecto.

Observo que incluso STMicro se refiere al problema a través de las fundas, y en la mayoría de los documentos donde se considera la optimización del consumo de energía, se limita a una o dos frases con el consejo de tirar las piernas no utilizadas al suelo o ponerlas en modo de entrada analógica, sin explicar las razones.

Lo triste es que, por defecto, todas las patas están configuradas como entradas digitales (0x00 en el registro GPIOx_MODER). Un disparador Schmitt siempre está en la entrada digital, lo que mejora la inmunidad al ruido de esta entrada, y es completamente independiente: es un elemento lógico simple, un búfer con histéresis que no requiere reloj externo.

En nuestro caso, esto significa que apagamos el reloj en modo Stop, y los disparadores Schmitt continuaron funcionando como si nada hubiera sucedido; dependiendo del nivel de la señal de entrada, cambian sus salidas a 0 y 1.

Al mismo tiempo, parte de las patas del procesador en un circuito típico cuelga en el aire, es decir, no hay señal inteligible en ellas. Sería un error pensar que la ausencia de una señal clara significa que en estos tramos 0 no es, en estos tramos debido a su alta impedancia de entrada, hay algún ruido aleatorio de un valor indeterminado, desde las pastillas y la corriente que fluye desde las pistas vecinas hasta el primer canal de televisión, si el pie es lo suficientemente largo como para servir como antena (sin embargo, los televisores analógicos en Rusia pronto se apagarán, lo que debería conducir a una disminución en el consumo de energía de los microcontroladores configurados incorrectamente).

De acuerdo con estas fluctuaciones, el tramo de alguna manera aleatoria cambia entre 0 y 1. La lógica CMOS consume corriente al cambiar. Es decir, una pata de procesador suspendida en el aire, configurada en modo de entrada digital, consume una corriente notable en sí misma .

La solución a esto es simple: cuando inicia el programa, debe configurar todas las patas para el estado de la entrada analógica; STM32 lo tiene formalmente para todas las patas sin excepción, independientemente de si están conectadas al ADC o no, y difiere de la entrada digital solo en ausencia de un disparador Schmitt en la entrada.



Para hacer esto, es suficiente escribir el valor 0xFF ... FF en todos los registros GPIOx_MODER, es más fácil hacer esto, como se mencionó anteriormente, justo al comienzo, y luego durante el transcurso de la reproducción, reconfigurar las piernas individuales según sea necesario en este dispositivo.

Aquí, sin embargo, surge un problema de segundo orden: es bueno si su firmware funciona en un controlador específico y, por lo tanto, siempre sabe qué es x en GPIOx. Peor aún si el firmware es universal: el STM32 puede tener hasta 8 puertos, pero puede ser más pequeño; cuando intente escribir en un puerto que no existe en este modelo del controlador, obtendrá una falla grave, es decir caída del núcleo

Sin embargo, incluso este caso se puede eludir: Cortex-M le permite verificar la validez de las direcciones, además, en el caso de M3 y M4, el cheque generalmente es bastante trivial, pero en M0 requiere algo de magia, pero es realizable (los detalles se pueden leer aquí , no veremos este artículo). )

Es decir, en general, el procesador inició, sintonizó las frecuencias e inmediatamente pasó por todos los puertos GPIO disponibles, escribiéndolos en los MODEROS (el código a continuación está escrito para RIOT OS, pero en general es claro sin comentarios y puede transferirse a tres minutos cualquier otra 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 esto solo se aplica a la serie L1, en L0 y L4 se tuvo en cuenta la experiencia y, de forma predeterminada, configuran todos los puertos como entradas analógicas al inicio.

Después de haber realizado todos estos procedimientos cuidadosamente, llene el firmware en el dispositivo terminado ... y obtenga 150 uA en modo Stop en el procesador y todos los chips externos apagados, a pesar de que sus estimaciones son las más pesimistas, provenientes de las hojas de datos de todo lo que ha soldado en la placa dar no más de 10 μA.

Además, intenta llevar el procesador al modo de espera en lugar de detenerlo, es decir simplemente apáguelo casi por completo, y en lugar de caerse, el consumo de energía aumenta tres veces, ¡acercándose a casi medio miliamperio!

No hay necesidad de entrar en pánico. Como habrás adivinado, hiciste todo bien. Pero no hasta el final.

Síndrome de piernas inquietas - 2


El siguiente problema tiene dos partes.

La primera es bastante obvia: si su dispositivo no consta de un microcontrolador, entonces es importante no olvidar que los chips externos también tienen señales de entrada en las que los activadores Schmitt se cuelgan y que, además, pueden despertar la lógica interna del chip. Por ejemplo, un chip que es retirado y retirado de su sueño por el equipo de UART intentará leer datos de él con cualquier movimiento en este autobús.

En consecuencia, si todas estas patas están colgadas en el aire, no obtendremos nada bueno.

¿En qué condiciones terminan en el aire?

En primer lugar, cuando el controlador entra en modo de espera, todos los GPIO se transfieren al estado High-Z, con alta resistencia, es decir, de hecho, los chips externos conectados a ellos están en el aire. Es imposible arreglar esto mediante programación en STM32L1 (en otras series y otros controladores ocurre de diferentes maneras), por lo tanto, la única salida es en un sistema que usa el modo de espera, las entradas de chips externos deben ser puestas a tierra o alimentadas por resistencias externas.

Se elige un nivel específico para que la línea esté inactiva desde el punto de vista del chip:

  • 1 para UART TX
  • 0 para SPI MOSI
  • 0 para SPI CLK en el modo SPI 0 o 1
  • 1 para SPI CLK con SPI Mode 2 o 3
  • 1 para SPI CS

En segundo lugar, en STM32 cuando se utiliza el modo Stop (sic!) , El estado de los GPIO conectados a los bloques de hardware internos de las interfaces puede ser ... diferente. Es decir, la misma interfaz SPI, cuando está configurada, en Stop de repente resulta ser una entrada digital o, en general, High-Z, con las consecuencias correspondientes para los chips externos que la cuelgan. Si bien la documentación establece que las patas están en buenas condiciones, a priori puede confiar en ellas solo si las usa como GPIO normales.

No puede entenderlo y perdonarlo, pero puede recordarlo y solucionarlo: para las interfaces que se comportan de esta manera, debe agregar el cambio forzado a GPIO normal con niveles correspondientes a niveles inactivos de esta interfaz en la función de cuidado del sueño. Después de salir del sueño, las interfaces se pueden restaurar.

Por ejemplo, el mismo SPI antes de ir a dormir (por simplicidad, tomo el código del sistema operativo RIOT, está claro que lo mismo es fácil de implementar en los 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); } } 

Tenga en cuenta que las salidas aquí están configuradas no como GPIO_OUT con un nivel de 0 o 1, sino como entradas con un pull-up a 0 o 1; este no es un punto fundamental, pero proporciona seguridad adicional si comete un error e intenta jugar pull-push con algún tipo de un chip externo tirando de esta pata hacia el otro lado. Con GPIO_OUT puede organizar un cortocircuito, con GPIO_IN con un pull-up, nunca.

Además, la señal SPI CS no se ve afectada; en este caso, se genera mediante programación, es decir, por un GPIO normal, y mantiene su estado en un sueño con confianza.

Para restaurar el estado de la pierna al salir del sueño, es suficiente escribir los valores de los registros que se cambiarán (MODER, PUPDR, OTYPER, OSPEEDR - vea la situación en un caso particular) en la entrada, en variables, y vuelva a colocarlos en los registros al salir del sueño de las variables .

Y ahora ... ta daaam! Imagen del título Uno y medio microamperios.

Pero es muy temprano para celebrar. En esto hemos terminado la optimización estática del consumo de energía, y por delante tenemos una dinámica .

Aquiles vs tortuga


¿Qué es mejor: comer más y correr más rápido o comer menos, pero correr más lento? En el caso de los microcontroladores, la respuesta a esta pregunta es dos veces no trivial.

En primer lugar, las frecuencias de funcionamiento se pueden cambiar en un rango muy amplio: de 65 kHz (LP Run) a 32 MHz en modo normal. Como cualquier chip CMOS, STM32 tiene dos componentes en el consumo de energía: estático y dinámico; el segundo depende de la frecuencia, el primero es constante. Como resultado, el consumo de energía no disminuirá tan rápido como la frecuencia de operación y la productividad, y dependiendo de la tarea, la frecuencia óptima desde el punto de vista de la eficiencia energética puede ser diferente, donde debe esperar algún evento, pero por alguna razón no puede ir a dormir, habrá las frecuencias bajas son efectivas, donde solo necesita trillar los números: altos. En las tareas típicas de "promedio hospitalario", generalmente no tiene sentido ir por debajo de 2-4 MHz.

En segundo lugar, y este es un momento menos trivial, la tasa de sueño depende de la frecuencia de trabajo y la forma en que se recibe.

El peor de los casos es salir del sueño a una frecuencia de 32 MHz de un cuarzo externo (permítame recordarle que STM32L1 se despierta en un oscilador interno de 4 MHz), porque consta de tres etapas:

  • en realidad el procesador se despierta del sueño
  • estabilización de generación de cuarzo (1-24 MHz)
  • Estabilización de generación PLL (32 MHz)

En realidad, sacar el procesador del modo inactivo aquí es el problema más pequeño, a una frecuencia de 4.2 MHz se necesitan unos 10 μs. Pero la estabilización del cuarzo puede tomar hasta 1 ms (aunque generalmente para resonadores de alta velocidad aún es más rápido, del orden de varios cientos de microsegundos), el acceso al modo PLL es de otros 160 μs.

Estas demoras pueden no ser significativas desde el punto de vista del consumo de energía para un sistema que rara vez se despierta (no más de una vez por segundo), pero donde el período entre las activaciones es de decenas de milisegundos y menos, y las activaciones en sí son cortas, la sobrecarga comienza a hacer una adición ya medible incluso teniendo en cuenta que durante la activación, el procesador consume una corriente relativamente pequeña.

¿Qué se puede hacer con esto? En general, la respuesta es obvia: trate de evitar el uso de cuarzo externo. Por ejemplo, un programa en el que hay subtareas pesadas raras que requieren un reloj preciso (por ejemplo, de las triviales: intercambio de datos UART) y subtareas simples frecuentes, puede decidir dentro de sí mismo cada vez que se despierte si es necesario irse por ahora cuarzo externo, o será más fácil (¡y más rápido!) realizar la tarea actual en el generador MSI, en el que el procesador ya se ha despertado sin perder mucho tiempo inicializando las frecuencias.

En este caso, sin embargo, puede ser necesario ajustar las frecuencias de reloj de la periferia, así como ajustar los modos de acceso a la memoria flash (el número de ciclos de retraso), el voltaje del núcleo del procesador (en STM32L1 se selecciona entre tres valores posibles), etc. Sin embargo, con respecto a los modos de funcionamiento del núcleo y la memoria, a menudo es posible ajustarlos eligiendo los recomendados para la frecuencia máxima utilizada, ya que el funcionamiento no óptimo del núcleo a frecuencias más bajas no dará un cambio significativo en el rendimiento práctico y el consumo de energía debido al pequeño volumen de tareas en estas frecuencias. realizado.

Aunque todas estas medidas ya se aplican al ajuste de modos (y, por ejemplo, la mayoría de los sistemas operativos y las bibliotecas ni siquiera saben nada parecido), en algunos casos pueden reducir el consumo promedio en una escala de unidades de porcentaje, y a veces incluso más. Imagine, por ejemplo, un medidor de agua que sondea los contactos de un interruptor de láminas cada 50 ms, mientras que la encuesta real toma varias decenas de microsegundos: ¿desea agregar ~ 500 μs en este momento para activar el controlador?

Segundo insoportablemente largo


Otro problema que no está directamente relacionado con la conservación de energía, sino que surge inevitablemente en relación con él: ¿cómo contar los intervalos de tiempo de menos de 1 segundo?

El hecho es que en STM32L1 solo hay un temporizador que funciona en el modo Stop: este es RTC, la unidad de tiempo estándar para la cual es 1 segundo. Al mismo tiempo, en los programas hay intervalos de tiempo constantes de unidades, decenas y cientos de milisegundos, para tomar al menos el mismo medidor de agua.

Como ser ¿Funciona en procesadores con temporizadores LPTIM, con reloj a 32768 Hz? Una buena opción, de hecho, pero no siempre necesaria. Es posible sin ella.

No en todos los STM32L1, pero comenzando con Cat. 2 (estos son los procesadores STM32L151CB-A, STM32L151CC y más nuevos), el bloque RTC se complementó con un nuevo registro: SSR, SubSeconds Register. Más precisamente, no se complementó tanto como lo hizo visible para el usuario, además de que se agregaron las alarmas de segundos ALRMASSR y ALRMBSSR.

Este registro no contiene unidades de tiempo claras; fue creado desde un contador técnico interno. En STM32L1, un reloj que marca a 32768 Hz pasa a través de dos contadores divisores, asíncronos y sincrónicos, que en total normalmente lo dividen por 32768 para obtener un tic de 1 segundo para el reloj. Entonces, SSR es solo el valor actual del segundo contador.

Aunque el SSR no cuenta en milisegundos, sino en sus unidades, la dimensión de estas unidades se puede cambiar cambiando la relación de los divisores del contador síncrono y asíncrono, manteniendo su coeficiente total igual a 32768 para obtener el estándar de 1 segundo en la entrada RTC. Conociendo estos coeficientes, podemos calcular el precio de una división de SSR en milisegundos, y desde aquí podemos proceder a programar alarmas de segundos.

Cabe señalar que un contador previo asíncrono es más económico que un SSR síncrono y, por lo tanto, establecerlo en 1 y dividir la frecuencia de entrada en SSR por 32768, habiendo recibido un recuento de solo 30 μs, es energéticamente desventajoso. Para nosotros, determinamos el valor óptimo para el divisor preliminar 7, para síncrono - 4095 ((7 + 1) * (4095 + 1) = 32768). Con una disminución adicional en el divisor preliminar, el consumo de energía de RTC comienza a crecer de manera medible, en una fracción de una microamperia, pero dado que comparamos esto con la "referencia" 1.4 μA en modo Stop, incluso las fracciones son importantes. Por defecto, para STM32L1 estos valores son 127 y 255, es decir el precio de referencia es de aproximadamente 4 ms, lo cual es un poco aproximado.

Si desea profundizar en el código, a su debido tiempo finalizamos el controlador RTC estándar de RIOT OS para admitir RTC_SSR e intervalos de milisegundos. Desde entonces, lo hemos estado usando literalmente en cada paso (y desde que trabajamos en el sistema operativo, un servicio también se cuelga encima de él, lo que le permite colgar casi cualquier número de tareas con períodos arbitrarios en un temporizador de hardware con un simple movimiento de la muñeca).

El mismo enfoque se transfiere a los controladores STM32L0 y STM32L4, todos los modelos tienen el registro RTC_SSR; Esto elimina la necesidad de temporizadores LPTIM y unifica el código para diferentes plataformas.

Cómo entender que un multímetro miente


Por supuesto, después de todas las optimizaciones, surge la pregunta legítima: ¿qué, de hecho, hemos logrado? Sin saber la respuesta, uno podría limitarse por completo a un WFE con indicadores configurados correctamente, ir a dormir y obtener su 200-500 μA.

La forma más tradicional de medir la corriente es, por supuesto, un multímetro. Comprender que está acostado sobre una carga como un microcontrolador con su consumo dinámico es muy simple: si está encendido, está mintiendo.

Esto, sin embargo, no significa que el multímetro sea inútil en este asunto. Solo necesita poder aplicarlo.

En primer lugar, un multímetro es algo muy lento, un tiempo típico para un recuento en él es una segunda escala, un tiempo típico para cambiar el estado de un microcontrolador es una escala de microsegundos. En un sistema que cambia su consumo a ese ritmo, el multímetro simplemente mostrará valores aleatorios.

Sin embargo, una de las variables no aleatorias de interés para nosotros es el consumo del microcontrolador en modo de suspensión; Si excede significativamente el valor que estimamos en las hojas de datos, entonces algo está claramente mal. Este es el consumo de un sistema estático , es decir, se puede medir con un multímetro.

El método más trivial que se muestra en la foto del título es un multímetro en modo microamperímetro, que ahora se encuentra en la mayoría de los modelos de rango medio, y tiene buena precisión y excelente resolución. UT120C tiene una resolución de 0.1 μA con una precisión certificada de ± 1% ± 3 descargas, lo cual es suficiente para nosotros.

Solo hay un problema con este modo: los multímetros tienen una gran resistencia en serie, una escala de cientos de ohmios, por lo que en modo normal, un microcontrolador con un multímetro de este tipo en el circuito de alimentación simplemente no se iniciará. Afortunadamente, las posiciones de "mA" y "uA" en casi todos los instrumentos de la báscula están cercanas, los zócalos para medir en ambos rangos son los mismos, por lo que puede iniciar el controlador de forma segura en el límite de "mA", y cuando se vaya a dormir, haga clic en "uA" "- esto sucede lo suficientemente rápido como para que el controlador no tenga tiempo de perder energía y reiniciar.

Tenga en cuenta que si el controlador experimenta picos en la actividad, este método no es aplicable. Por ejemplo, el temporizador de vigilancia se reinicia cada 15 segundos en el firmware del dispositivo; en estos momentos, el multímetro logra mostrar algo en la región de 27 μA, que, por supuesto, no tiene nada que ver con el clima en Marte. Si ocurre algo arbitrariamente corto en su sistema con más frecuencia que una vez cada 5-10 segundos, el multímetro simplemente mentirá.

Otra forma de medir la estática.(Estoy destacando directamente esta palabra) el consumo por un multímetro es una medida de la caída en una derivación externa. Si desea medir corrientes ultrapequeñas en la escala de unas pocas decenas de microamperios, debe colocar una derivación grande (por ejemplo, 1 kOhm) y, en paralelo, un diodo Schottky en conexión directa. Si la derivación cae más de 0.3 V, el diodo se abrirá y limitará la caída de voltaje, y hasta 0.3 V puede medir la caída con seguridad con un multímetro en el rango de milivoltios, 1 mV = 1 μA.

Por desgracia, no funcionará medir la caída en una derivación de baja impedancia con un multímetro típico: los dispositivos de clase media, incluso si muestran algo por debajo de 100 μV, la precisión en este rango es lamentable. Si tiene un buen dispositivo de escritorio que puede mostrar 1 uV, ya no necesita mi consejo.

Sin embargo, las estadísticas son buenas, pero ¿qué pasa con la dinámica? ¿Cómo evaluar el mismo efecto de diferentes frecuencias en el consumo de energía promedio?

Aquí todo es complicado.

Anotemos los requisitos básicos:

  • rango de corriente de al menos 1 μA - 100 mA (10 ^ 5)
  • período de medición no más de 10 μs
  • caída de tensión no superior a 100 mV
  • duración de la medición: ilimitada

Si simplemente traducimos esto directamente a números, obtenemos un ADC relativamente rápido y no menor de 18 bits con un sesgo de entrada de menos de 30 μV, un extremo frontal analógico capaz de medir voltajes de 1 μV y una interfaz rápida a la computadora que nos permitirá transferir todo esto y guardar

Y todo esto para un solo uso.

Ya ves, sí, ¿por qué esas cosas no se encuentran en cada esquina de diez dólares? Keysight N6705C en la primera aproximación cumple con nuestros requisitos, solo cuesta $ 7960.

Entre las soluciones de presupuesto, por ejemplo, SiLabs integra la medición actual en sus depuraciones: las características de su Sistema de monitoreo de energía avanzado (AEM) dependen del modelo de depuración específico y tienen el mayor problema con la velocidad de medición. En los antiguos "kits de inicio", el STK3300 / 3400 es solo de 100 Hz, en los nuevos debugs el STK3700 / 3800 (fácilmente reconocible por textolite negro) - 6.25 kHz, y en los modelos más antiguos de la serie DK puede alcanzar hasta 10 kHz, pero también cuesta ya son $ 300 +. Para tareas serias, SiLabs recomienda oficialmente el mencionado Keysight.

En principio, dicho dispositivo puede ser diseñado por usted mismo: en primer lugar, necesita amplificadores operacionales muy buenos con un sesgo de entrada mínimo, como OPA2335. Dichos amplificadores operacionales se colocan en la misma derivación de 2-3 piezas con diferentes factores de amplificación, todos ellos están conectados a diferentes entradas de ADC (con este enfoque, es muy posible usar el microcontrolador incorporado), luego cada adquisición de datos determina programáticamente cuál de los amplificadores operacionales en este el momento no está sobrecargado, se cuentan las lecturas del mismo.

El problema de la velocidad de transferencia de datos a una computadora se resuelve de manera bastante simple, ya que para fines prácticos estamos interesados ​​principalmente en el consumo promedio del sistema en la vida real, las lecturas de microsegundos se pueden recopilar en el microcontrolador incorporado del medidor y el promedio aritmético para una escala razonable de milisegundos se puede enviar.

Además, como muestra la práctica, es muy útil tener un medidor-registrador, aunque simple y no demasiado preciso, pero siempre a mano, para no tener sorpresas con algún tipo de cambio de firmware interrumpido por el ahorro de energía.

Por ejemplo, incorporamos uno en nuestro adaptador USB estándar UMDK-RF, que se usa constantemente para depurar firmware: ya tiene un programador SWD con soporte para el protocolo DAPLink, un puente USB-UART y lógica de administración de energía, respectivamente, tiene un medidor de consumo Casi gratis. El medidor en sí es un shunt de 1 Ohm y un amplificador INA213 (ganancia 50 veces, compensación cero típica de 5 μV): el



amplificador está conectado directamente a la entrada del ADC del microcontrolador (STM32F042F6P6), el ADC procesa con un período de 10 μs usando un temporizador de hardware, y hasta a través de USB los datos promediados se emiten para un intervalo de 100 ms. Como resultado, al cambiar algo en la lógica del firmware, puede simplemente fumar o tomar un café, dejar el dispositivo sobre la mesa y regresar, ver un horario como este:



La precisión de un dispositivo "libre" de este tipo, por supuesto, no es alta: con un ADC de 12 bits y un amplificador, la cantidad mínima es de 16 μA, pero es extremadamente útil para evaluar de forma rápida y regular el comportamiento de los dispositivos depurados desde el punto de vista del consumo de energía. Al final, si haces algo mal en el firmware o dispositivo, entonces con una garantía muy alta podrás salir de unidades de microamperios al menos cientos, y esto será claramente visible.



Otra ventaja adicional es que, dado que los datos se envían al puerto COM virtual en forma de texto (valores en microamperios), puede colocar la ventana del terminal junto a la ventana que muestra la consola del dispositivo y ver el consumo de energía al mismo tiempo que los mensajes de depuración.

Me jacto de esto por una razón, pero para ofrecer a todos los que quieran usar este programador de depuración mínimo (¡y muy barato!) En sus propios proyectos.

Puede dibujar el diagrama aquí ( fuente en DipTrace ), arrastrar el firmware aquí (brunch umdk-rf, al construir el objetivo es UMDK-RF, basado en el proyecto dap42 ). El diagrama se dibuja desordenado, pero espero que los puntos principales estén claros, el firmware está escrito en C usando libopencm3 y se ensambla con el arm-none-eabi-gcc habitual. Como funciones adicionales, el firmware tiene administración de energía, captura señales de sobrecarga de las teclas de control e ingresa el controlador conectado a él en su cargador de arranque nativo con solo presionar un botón.

NB: si desea que el botón de arranque incorpore el controlador del programador en su gestor de arranque de manera regular, debe cambiar la polaridad de la conexión, la edición de bytes de opción del controlador en el primer arranque y la entrada del programa en el cargador de arranque eliminado, y la polaridad de interrupción para regular funciones de este botón.

Puede ver cómo se realiza la medición actual en un par de amplificadores operacionales con diferentes factores de ganancia (por ejemplo, para mejorar el depurador descrito anteriormente para sus tareas), aquí (p. 9), una alternativa más tradicional, con un amplificador operacional y un costoso ADC de 24 bits - TI lo tiene (EnergyTrace en la página 5).

PD Tenga en cuenta que durante la depuración con un UART o JTAG / SWD conectado, una pequeña corriente puede filtrarse a través de sus patas, lo que no sucederá durante el funcionamiento real del dispositivo. Entonces, en UMDK-RF, se filtran aproximadamente 15 μA en el SWD (y, por lo tanto, en la foto del encabezado, las mediciones con un multímetro se realizan en la versión anterior de la placa, sin SWD), y en el STM32 Nucleo hubo casos con flujo espurio a través del SWD de aproximadamente 200 μA . Las placas de depuración utilizadas para la medición deben verificarse para tales características, ya sea desconectando sus líneas de interfaz, si existe esa posibilidad, o comparando los resultados con el consumo medido del dispositivo sin instalarlo para la depuración, por ejemplo, con un multímetro en modo estático.

En lugar de una conclusión


Espero que ya haya entendido qué error cometió al elegir la programación de microcontroladores como su especialidad principal.

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


All Articles