能源优化STM32:实用指南

哈Ha!

网络上有很多关于STM32微控制器在节能设备(通常是电池供电的设备)中运行的文章,但是不幸的是,其中很少有人不了解节能模式和包含它们的SPL / HAL命令之外的主题(尽管如此) (有关使用STM32的绝大多数文章)。

同时,由于智能家居和各种IoT的飞速发展,这个话题变得越来越重要-在这样的系统中,许多组件都由电池供电,并且有望持续多年运行。

我们将通过STM32L1的示例来填补这一空白-STM32L1是一种非常流行的控制器,非常经济,同时存在该系列产品特有的问题。 几乎所有上述内容还将适用于STM32L0和STM32L4,并且在常见问题和方法方面,也适用于其他基于Cortex-M内核的控制器。



实际结果应该类似于上面的照片(是的,我们还将讨论万用表和其他测量仪器对类似任务的适用性)。

STM32L1中的省电模式


省电的基本原理是处理器的主要省电模式。 每个制造商和每个系列的控制器都有自己的控制器(特定的一组是标准Cortex-M核心模式的供应商扩展,在外围设备,电源电压等方面存在细微差别)。

具体地说,属于经济型控制器系列的STM32L1与此相关,并且获得了扩展的电源设置,我们具有以下优势:

  • 运行 -正常模式。 全包,所有外围设备可用,频率高达32 MHz。
  • 低功耗运行(LP Run) -一种特殊模式,其工作频率在131 kHz以内,最大功耗( 考虑整个外围器件)为200μA。 在LP运行模式下,处理器功率调节器进入一种特殊的经济模式,与在运行模式下以相同频率工作相比,它最多可节省五十微安。
  • 睡眠 -暂停内核,但保留所有时钟频率。 如果内核不需要,处理器外围设备可以继续工作,但是可以自动将其关闭。
  • 低功耗睡眠(LP睡眠) -睡眠与稳定器向经济模式过渡的结合。 时钟频率不高于131 kHz,总功耗不高于200μA。
  • 停止 -完全停止所有时钟频率,但“时钟”发生器32768 Hz(外部或内部)除外。 在STM32L1的情况下,只有实时时钟在该模式下继续工作,其他所有操作都完全停止。 在较新的处理器中,某些外设可以采用低频时钟。 几乎所有处理器分支都保持其状态。 RAM的内容已保存,外部中断继续工作。
  • 备用 -完全关闭处理器内核,RAM和所有外设,实时时钟除外。 RAM未保存(即,从软件的角度来看,留在待机状态几乎与电源失真相同-重新开始),RTC继续计时。 外部中断不起作用,除了三个特殊的WKUPx支路(从0切换到1会唤醒处理器)。

进入每种模式非常简单-您需要在3到5个寄存器中设置标志,然后(对于睡眠模式)调用WFI或WFE指令,这是标准的Cortex-M指令,表示“等待中断”和“等待事件” 。 根据标志(它们在处理器的参考手册中进行了描述,对于STM32L1是RM0038 ),处理器本身将通过此命令进入此模式。

此外,最好禁止中断(这不会影响外部和内部事件将处理器从睡眠状态唤醒的能力),并等待完成使用DSB命令将数据从寄存器保存到内存的操作。

例如,这是进入停止模式的样子:

/*  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是一条阻塞指令,在该指令上,处理器将进入深度睡眠状态,直到发生某种中断后才退出。 是的,我重复一遍,尽管事实上我们明确地关闭了中断,但是处理器将响应并唤醒它们,但是只有在重新打开它们之后,处理器才会开始处理。 这具有深远的意义。

在上面的代码中,在WFI之后,工作频率的某种重新初始化不只是这样-事实是L1 始终以4.2 MHz的频率离开深度睡眠,并使用内部MSI发生器作为该频率的来源。 在许多情况下,您显然不希望唤醒处理器的中断处理程序以该频率开始运行-例如,因为所有计时器,UART和其他总线的频率都会飞散;因此,您可能不希望这样做。 因此,我们首先恢复工作频率(或者,如果要保留在MSI上,则重新计算4.2 MHz以下的必要总线),然后陷入中断。

实际上,两种最常用的模式是运行和停止。 事实是,LP运行非常缓慢,如果处理器需要执行一些计算而不仅仅是等待外部事件,则LP Run毫无意义,并且Sleep和LP Sleep不太经济(消耗高达2 mA的电流),如果需要,则需要至少可以节省一点,但同时要保留工作的外围设备和/或提供处理器对事件的最快反应。 确实存在这样的要求,但总的来说并不经常。

通常不使用待机模式,因为在由于RAM清零而无法从上次退出的位置继续之后,外部设备也存在一些问题,我们将在下面讨论这些问题,这些问题需要硬件解决方案。 但是,如果考虑到该设备的设计,例如在该设备的长期存储期间,可以将待机模式用作“关闭”模式。

实际上,在介绍这些内容时,大多数手册通常都会成功地发行。

问题在于,跟随它们,您将获得100-200μA的实际消耗量,而不是在工作时间的Stop中承诺的1.4μA的消耗-即使在Nucleo参考调试中也没有任何外部芯片,传感器等。它可以归因于此。

不,您的处理器正在运行,勘误表中没有任何内容,您做对了所有事情。

只是没有结束。

不安腿综合症


STM32L1是第一个问题, 一些文章提到此问题,但通常仅在论坛上才提到,在讨论的第三天,当100-200μA来自何处时,有人记得AN3430的存在并进入其中的第19页-这双腿默认状态。

我注意到,即使STMicro本身也是通过套管来解决问题,在大多数考虑能耗优化的文档中,它仅限于一两个短语,建议将未使用的脚拉到地面或置于模拟输入模式,而无需说明原因。

可悲的是,默认情况下,所有支路都配置为数字输入(GPIOx_MODER寄存器中的0x00)。 施密特触发器始终位于数字输入上,这提高了该输入的抗噪能力,并且是完全独立的-它是一个简单的逻辑元件,是具有迟滞的缓冲器,不需要外部时钟。

在我们的情况下,这意味着我们在“停止”模式下关闭了时钟,施密特触发器继续工作,就好像什么都没发生一样-根据输入信号的电平,它们将输出切换为0和1。

同时,典型电路中的处理器支路的一部分悬吊在空中-也就是说,它们上没有可听见的信号。 认为没有清晰的信号是错误的,这意味着在这些支路上,由于它们的高输入阻抗,在这些支路上没有0信号,而是由于拾音器和电流从相邻轨道流向电视的第一通道而产生一些不确定的随机噪声,如果脚足够长,可以用作天线(但是,俄罗斯的模拟电视很快就会关闭,这会导致不正确配置的微控制器的功耗有所降低)。

根据这些波动,支路以某种随机方式在0和1之间切换。CMOS逻辑在切换时会消耗电流。 也就是说, 以数字输入模式配置的悬于空中处理器支腿本身会消耗大量电流

解决方法很简单-启动程序时,需要将所有支路配置为模拟输入的状态。 STM32正式适用于所有支路,无论它们是否已连接到ADC,并且仅在输入端没有施密特触发器的情况下才与数字输入有所不同。



为此,只需将0xFF ... FF值写入所有GPIOx_MODER寄存器就足够了,如上所述,最简单的方法就是在开始时进行此操作,然后在播放过程中根据设备的需要重新配置各个支脚。

但是,这会产生一个二阶问题-如果固件在一个特定的控制器上运行就很好了,因此您总是知道GPIOx中的x 。 如果固件是通用的,更糟糕​​的是-STM32最多可以有8个端口,但可以更小; 当您尝试写入该控制器型号中不存在的端口时,将出现硬故障,即 内核崩溃。

但是,即使是这种情况也可以避免-Cortex-M允许您检查地址的有效性,而且,对于M3和M4,检查通常很简单,而在M0上,它需要一些魔术,但是它是可以实现的( 详细信息可以在此处阅读 ,我们不会在此发表文章) )

也就是说,通常,处理器启动,调谐频率-然后立即通过所有可用的GPIO端口,将它们写入MODER端口(以下代码是针对RIOT OS编写的,但通常无需注释即可清晰地将其转移到三分钟内任何其他平台)。

 #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 

我注意到,这仅适用于L1系列,在L0和L4中考虑了经验,默认情况下,它们在启动时将所有端口配置为模拟输入。

仔细完成所有这些步骤后,您将固件上传到完成的设备...,并在处理器的“停止”模式下获得150 uA的电流,并且所有外部芯片都关闭,尽管您的估计是最悲观的,但要从数据表中获得所有您焊接在板上的信息给出不高于10μA的电流。

此外,然后您尝试使处理器进入待机模式而不是停止模式,即 只需将其几乎完全关闭-功耗就不会降低,反而会降低三倍,接近半毫安!

不必惊慌。 您可能已经猜到了,您做对了所有事情。 但还没有结束。

腿不安综合症-2


下一个问题有两个部分。

第一个很明显:如果您的设备不包含一个微控制器,那么重要的是不要忘记外部芯片也有输入信号,施密特触发器挂起了这些输入信号,而且这些输入信号还可以唤醒芯片的内部逻辑。 例如,由UART小组从睡眠中撤出并移出的芯片将尝试通过该总线上的任何移动来读取其数据。

因此,如果所有这些腿都悬在空中,我们将无能为力。

在什么条件下它们最终会消失?

首先,当控制器进入待机模式时,所有GPIO都以高阻态转换为High-Z状态-也就是说,实际上,连接到它们的外部芯片都处于悬空状态。 不可能以编程方式在STM32L1中修复此问题(在其他系列和其他控制器中以不同的方式发生),因此唯一的出路是在使用待机模式的系统中,必须将外部芯片的输入接地或由外部电阻供电。

选择特定级别,以便从芯片的角度来看,该线路处于非活动状态:

  • 1个用于UART TX
  • SPI MOSI为0
  • SPI模式0或1时SPI CLK为0
  • SPI模式2或3的SPI CLK为1
  • SPI CS为1

其次,在STM32上, 当使用Stop (sic!) 模式时,连接到接口内部硬件模块的GPIO 状态可以...不同。 也就是说,在Stop中配置了相同的SPI接口后,突然变成了数字输入,或者通常是High-Z,这给挂在其上的外部芯片带来了相应的后果。 虽然文档指出支脚状况良好,但只有将支脚用作常规GPIO时,您才能优先使用它。

您不能理解和原谅它,但是您可以记住并修复它:对于以这种方式工作的接口,必须在睡眠护理功能中向该接口的非活动级别添加强制切换到普通GPIO。 进入睡眠状态后,可以恢复接口。

例如,在进入睡眠之前使用相同的SPI(为简单起见,我从RIOT OS中获取了代码,很显然,在寄存器上易于实现相同的代码):

 /* 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); } } 

请注意,此处的输出不是配置为0或1的GPIO_OUT,而是配置为上拉为0或1的输入-这不是基本点,但是如果您犯了错误并尝试使用某种类型的上拉功能,则可以提供额外的安全性。一个外部芯片以另一种方式拉动这条腿。 使用GPIO_OUT,您可以安排短路,而使用GPIO_IN则具有上拉电路-永不。

此外,SPI CS信号不受影响-在这种情况下,它是通过程序生成的,即通过普通的GPIO生成的,并且可以将其状态自信地保持在梦中。

要在离开睡眠状态时恢复腿部状态,只需将要更改的寄存器值(入口处的MODER,PUPDR,OTYPER,OSPEEDR-参见特定情况)写入变量,然后在从变量离开睡眠状态时将它们回滚到寄存器中就足够了。 。

现在... ta daaam! 标题图片。 一个半安培。

但这还为时过早。 在此基础上,我们完成了能耗的静态优化,而前面是动态的

阿喀琉斯vs龟


哪个更好-吃得更多,跑得更快或更少,但跑得更慢? 对于微控制器,这个问题的答案是不平凡的两倍。

首先,可以在非常宽的范围内更改工作频率-从65 kHz(LP Run)到正常模式下的32 MHz。 像任何CMOS芯片一样,STM32在功耗方面有两个组成部分-静态和动态。 第二个取决于频率,第一个是常数。 结果,能耗将不会像工作频率和生产率那样快地降低,并且根据任务的不同,从能源效率的角度来看,最佳频率可能会有所不同-您需要等待某些事件,但由于某些原因您无法入睡,低频是有效的,您只需要对数字进行脱粒-高。 在典型的“医院平均”任务中,低于2-4 MHz通常没有意义。

其次,这是一个不那么琐碎的时刻,失眠的速度取决于工作频率和接收方式。

最坏的情况是外部石英以32 MHz的频率进入睡眠状态(请记住,STM32L1在内部4 MHz振荡器上唤醒),因为它包括三个阶段:

  • 实际上处理器从睡眠中唤醒
  • 石英产生稳定度(1-24 MHz)
  • PLL生成稳定度(32 MHz)

实际上,使处理器脱离睡眠是最小的问题,在4.2 MHz的频率下大约需要10μs。 但是石英的稳定可能需要长达1 ms的时间(尽管通常对于高速谐振器来说,它仍然要快得多,大约为数百微秒),进入PLL模式的时间又需要160μs。

从很少唤醒(每秒不超过一次)的系统的能耗来看,这些延迟可能并不重要,但是在唤醒之间的时间间隔为数十毫秒或更短,并且唤醒本身很短的情况下,开销开始造成本来就可以测量的增加考虑到在唤醒过程中处理器消耗的电流相对较小。

该怎么办? 通常,答案是显而易见的:尽量避免使用外部石英。 例如,一个程序中有很少的繁重子任务需要精确的时钟(例如,琐碎的子任务-UART数据交换),而频繁的简单子任务可以在每次唤醒时自行决定是否有必要进入外部石英,或者在MSI发生器上执行当前任务会更容易(并且更快!),在该处理器上,MSI发生器已经醒来,而无需花费大量时间初始化频率。

但是,在这种情况下,可能需要调整外围设备的时钟频率,并调整对闪存的访问模式(延迟周期数),处理器内核的电压(在STM32L1中从三个可能的值中选择)等。 但是,关于内核和内存操作模式,通常可以通过选择建议的最大使用频率来对其进行微调,因为在较低频率下内核的非最佳操作将不会在实际性能和功耗上产生重大变化,因为在这些频率下任务量很小执行。

尽管所有这些措施都已经适用于模式的微调(例如,大多数OS和库甚至都不了解盒子中的任何内容),但在某些情况下,它们可能导致平均消耗量以百分比为单位降低,有时甚至更高。 想象一下,例如,一个水表每50毫秒对磁簧开关的触点进行一次轮询,而实际的测量则需要数十微秒的时间-您是否希望此时增加〜500μs的时间来唤醒控制器?

难以忍受的长秒


另一个与节能不直接相关但又不可避免地出现的问题-如何计算少于1秒的时间间隔?

事实是,在STM32L1上,只有一个定时器在“停止”模式下工作-这是RTC,标准时间单位是1秒。 同时,在程序中,至少要使用相同的水表,单位时间间隔通常为数十和数百毫秒。

如何成为 在带有LPTIM定时器,时钟频率为32768 Hz的处理器上运行? 实际上,这是一个不错的选择,但并非总是必要的。 没有它是可能的。

并非在所有STM32L1上,而是从Cat。开始。 2(这些处理器是STM32L151CB-A,STM32L151CC和更高版本),在RTC模块中补充了一个新寄存器-SSR,SubSeconds寄存器。 更准确地说,它并没有增加太多的附加内容,而是使其对用户可见,还添加了亚秒级警报ALRMASSR和ALRMBSSR。

该寄存器不包含任何可理解的时间单位;它是从技术内部计数器中提取的。 在STM32L1中,以32768 Hz滴答作响的时钟经过两个分频器计数器(异步和同步),这些计数器通常将其除以32768,以得到1秒的时钟滴答声。 因此,SSR只是第二个计数器的当前值。

尽管SSR的计数不是毫秒,而是以单位为单位,但是可以通过更改同步和异步计数器的除数比来更改这些单位的尺寸,同时保持其总系数等于32768以在RTC输入上获得标准的1秒。 知道了这些系数,我们就可以计算出毫秒级SSR的价格,从这里我们可以开始编写亚秒级警报。

应该注意的是,异步预计数器比同步SSR更经济,因此将其设置为1,并且已经将输入频率除以32768的SSR(接收到的计数仅为30μs)在能量上是不利的。 对于我们自己,我们为同步确定了初步除法器7的最佳值-4095((7 + 1)*(4095 +1)= 32768)。 随着预分频器的进一步减小,RTC的能耗开始可测量地增长-微微安培的几分之一,但是由于我们将其与停止模式下的“参考” 1.4μA进行了比较,因此即使是分数也很重要。 默认情况下,对于STM32L1,这些值为127和255,即 参考价格约为4毫秒,这有点粗糙。

如果您想深入研究代码,那么我们将在适当的时候完成 RIOT OS 的标准RTC驱动程序 ,以支持RTC_SSR和毫秒间隔。 从那时起,我们几乎一直在使用它(并且由于我们在OS中工作,因此服务也挂在它的顶部,这使您只需轻按一下就能在一个硬件计时器上以任意时间段挂起几乎任何数量的任务)。

相同的方法转移到STM32L0和STM32L4控制器上,它们的所有模型都具有RTC_SSR寄存器。 这消除了对LPTIM计时器的需求,并统一了不同平台的代码。

如何理解万用表在说谎


当然,在进行了所有优化之后,出现了合理的问题:实际上,我们取得了什么?在不知道答案的情况下,一个人可能完全将自己限制为具有正确配置的标志的WFE,进入睡眠状态并获得200-500μA的电流。

当然,最传统的电流测量方法是万用表。要知道它像微控制器一样负载在负载上,它的动态功耗非常简单-如果打开它,它就是在说谎。

但是,这并不意味着万用表在此问题上是无用的。您只需要能够应用它。

首先,万用表是很慢的事情,其中​​一个计数的典型时间是秒刻度,改变微控制器状态的典型时间是微秒刻度。在以这种速度改变功耗的系统中,万用表将仅显示随机值。

但是,我们感兴趣的非随机变量之一是睡眠模式下微控制器的功耗。如果它大大超过了我们在数据表上估计的值,那么显然是错误的。这是静态系统的消耗,即可以用万用表测量。

标题照片中显示的最简单的方法是使用微安表模式的万用表,该方法现已应用于大多数中档型号,并且具有良好的精度和出色的分辨率。 UT120C的分辨率为0.1μA,经认证的精度为±1%±3放电,对我们来说足够了。

这种模式只有一个问题-万用表具有较大的串联电阻,规模为数百欧姆,因此在正常模式下,电源电路中具有这种万用表的微控制器将无法启动。幸运的是,几乎所有秤上的“ mA”和“ uA”位置都很接近,两个量程上的测量插座都相同,因此您可以在“ mA”的极限下安全地启动控制器,当它进入睡眠状态时,单击“ uA” “-这发生得足够快,因此控制器没有时间失去电源并重新启动。

请注意,如果控制器出现活动高峰,则此方法不适用。例如,看门狗定时器会在设备的固件中每15秒钟重置一次-在这些时刻,万用表设法显示27μA左右的值,这当然与火星上的天气无关。如果您的系统上发生任意短路的频率大于每5-10秒一次,则万用表将说谎。

测量静电的另一种方法(我直接强调这个词)万用表的消耗量是对外部分流电阻下降的度量。如果要测量几十微安的超小电流,则需要放置一个大的分流器(例如1 kOhm),并与之并联-直接连接的肖特基二极管。如果分流器的压降超过0.3 V,则二极管将打开并限制电压降,当电压升高至0.3 V时,您可以用万用表在1 mV = 1μA的毫伏范围内安全地测量压降。

las,使用典型的万用表-中型设备来测量低阻抗分流器的压降是行不通的,即使它们显示的电压低于100μV,该范围内的精度也令人遗憾。如果您有一个可以显示1 uV的好的台式设备,则不再需要我的建议。

但是,静力学是好的,但动力学又如何呢?如何评估不同频率对平均功耗的相同影响?

这里的一切都很复杂。

让我们写下基本要求:

  • 电流范围至少为1μA-100 mA(10 ^ 5)
  • 测量周期不超过10μs
  • 电压降不高于100 mV
  • 测量时间-无限

如果我们直接将其转换成数字,我们将获得一个相对较快且不少于18位的ADC,其输入偏置小于30μV,一个模拟前端能够测量1μV的电压,并具有一个与计算机的快速接口,使我们能够传输所有这些信息并保存。

而且所有这些都是一次性使用的。

你看,是的,为什么这样的事情不会落在十美元的每个角落上?是德科技N6705C的第一个近似值满足了我们的要求,仅售价7960美元。

例如,通过预算解决方案,SiLabs将电流测量集成到其调试中-其高级能量监控(AEM)系统的特性取决于特定的调试模型,并且它们在测量速度方面存在最大的问题。在旧的“入门工具包”中,STK3300 / 3400仅为100 Hz,在较新的调试器中,STK3700 / 3800(很容易被黑色的textolite识别)-6.25 kHz,而在较旧的DK系列模型中,调试频率可高达10 kHz,但也要付出代价他们已经是$ 300 +。对于严峻的任务,SiLabs正式推荐上述Keysight。

原则上,这样的设备可以自己设计-首先,您需要像OPA2335这样的,具有最小输入偏置的非常好的运算放大器。此类运算放大器以相同的分流器放置在2-3个分流器上,具有不同的放大倍数,它们都缠绕到不同的ADC输入上(通过这种方法,很有可能使用内置微控制器),然后通过编程确定每次数据采集中给定的运算放大器中的哪一个。在不超载的那一刻,将对其进行计数。

数据传输到计算机的速度问题很简单-因为出于实际目的,我们主要对现实生活中系统的平均消耗感兴趣,因此可以在仪表的板载微控制器中收集微秒的读数,并且可以发送合理的毫秒级的算术平均值。

此外,如实践所示,拥有一个电表记录器非常有用,尽管它简单但不太准确,但始终在手边-以免因节能而导致某种固件变更而感到意外。

例如,我们在标准USB适配器UMDK-RF中内置了一个,该USB适配器在调试固件时会不断使用-它已经有一个SWD编程器,分别支持DAPLink协议,一个USB-UART桥和电源管理逻辑,并配备了一个功耗表几乎是免费的。仪表本身是一个1 Ohm分流器和一个INA213放大器(增益为50倍,典型零偏移为5μV):该



放大器直接连接至微控制器ADC(STM32F042F6P6)的输入,ADC通过硬件定时器以10μs的周期进行处理,并通过USB向上运行平均数据以100毫秒的间隔输出。结果,更改固件逻辑中的某些内容,您就可以抽烟或喝咖啡,将设备放在桌子上,然后返回,看一下这样的时间表:



这样的“免费”设备的精度当然不高-带有12位ADC和一个放大器,最小量子为16μA,但是对于从能耗的角度快速,定期评估调试设备的性能而言,它非常有用。最后,如果您在固件或设备中做错了什么,那么在非常高的保证下,您将至少可以脱离数百安培的微安,这是显而易见的。



另一个不错的好处是,由于数据以文本形式(以微安为单位)发送到虚拟COM端口,因此您可以将终端窗口放置在显示设备控制台的窗口旁边,并同时查看功耗和调试消息。

我之所以吹牛是有原因的,但是要提供给每个想要在自己的项目中使用这种最小(且非常便宜!)调试器程序员的人。

可以此处绘制示意图DipTrace中的源代码),在此处拖出固件(基于dap42项目,当构建目标为UMDK-RF时,为umdk-rf早午餐)。该图被绘制成凌乱的,但是我希望要点清楚,该固件使用libopencm3用C编写,并与通常的arm-none-eabi-gcc组装在一起。作为附加功能,该固件具有电源管理功能,可捕获来自控制键的过载信号,并通过长按按钮将与其连接的控制器输入其本机自举程序。

注意:如果您希望引导按钮定期将程序员自己的控制器带入其引导加载程序,则必须更改连接极性,在第一次引导时删除控制器的选项字节,并删除引导加载程序的程序输入,并定期更改中断极性该按钮的功能。

您可以查看如何在具有不同增益因子的一对运放上执行电流测量(例如,以改进上面针对您的任务描述的调试器),这里(第9页)是一种更传统的替代方案-具有一个运放和一个昂贵的24位ADC - 有TI的(第5页上EnergyTrace)。

PS请注意,在使用连接的UART或JTAG / SWD进行调试的过程中,小电流也可能通过其引脚泄漏,这在器件的实际操作中不会发生。因此,在UMDK-RF上,大约有15μA泄漏到SWD中(因此在标头照片上,是用万用表在不带SWD的旧版板上进行测量的),而在STM32 Nucleo上,存在通过SWD产生 200μA的杂散流的情况必须检查用于测量的调试板是否具有此类功能-通过断开其接口线(如果可能),或者将结果与未安装调试用的万用表(例如,在静态模式下安装)进行比较以比较所测量的设备的功耗。

而不是结论


我希望您已经了解通过选择微控制器编程作为主要专业所犯的错误。

Source: https://habr.com/ru/post/zh-CN430218/


All Articles