如何在 ATMega328P 上配置未使用的 I/O 引脚以实现最低功耗?

电器工程 Arduino
2022-01-02 21:38:26

我正在尝试在我创建的 Arduino 板上尽可能降低功耗。应该如何配置未使用的输入引脚?已经有一些答案(这里这里),但我追求的是 ATMega328P 的特定内容。

  1. 将引脚设置为输入,将引脚驱动为高电平以进行内部上拉
  2. 将引脚设置为输入,将引脚驱动为低电平
  3. 将引脚设置为输入,外部上拉
  4. 将引脚设置为输入,外部下拉
  5. 将引脚设置为输出低电平
  6. 设置引脚输出高
  7. 将引脚设置为输出低电平,外部下拉
3个回答

在挖掘数据表后,我发现了这一点:

14.2.6 未连接的引脚

如果某些引脚未使用,建议确保这些引脚具有定义的电平。尽管大多数数字输入在上述深度睡眠模式下被禁用,但应避免浮动输入以减少在启用数字输入的所有其他模式(复位、活动模式和空闲模式)中的电流消耗。

确保未使用引脚的定义电平的最简单方法是启用内部上拉电阻。在这种情况下,上拉电阻将在复位期间被禁用。如果复位期间的低功耗很重要,建议使用外部上拉或下拉。不建议将未使用的引脚直接连接到 VCC 或 GND,因为如果该引脚被意外配置为输出,这可能会导致电流过大。

关于评论/问题的更新:

根据表 14-1,上拉电阻只有在满足以下条件时才有效:

  1. 引脚设置为输入(DDxn 位为逻辑低)
  2. PORTxn 设置为逻辑高
  3. PUD 为逻辑低电平

获得大量电流流过上拉电阻器的唯一方法是在启用上拉电阻的情况下引脚经历低电平。这意味着要么 Atmel 搞砸了(不太可能),要么您将引脚配置为输入并启用了上拉电阻,并且引脚以某种方式接地。

部分14.2.5讨论数字输入启用和睡眠模式。总而言之,数字输入在施密特触发器的输入处被钳位到地,以防止在睡眠模式下出现浮动电平,除非该引脚被配置为外部中断。我不知道在睡眠模式下是否禁用了数字输出。根据图,它看起来并没有被禁用14-2,但如果是的话我不会太惊讶。最好的办法是使用内部或外部上拉电阻。

  1. 将引脚设置为输入,将引脚驱动为高电平以使用内部上拉:我认为这应该是:“通过使用内部上拉使输入变为高电平”。(我只会在你主动这样做时使用“驱动”这个词,通过 FET 连接到 Vcc 或接地。)很明显,你想要一个定义的电平,而上拉会处理这个问题。确保启用上拉是重置后要做的第一件事。这通常适用于 I/O 初始化。唯一的电流将是推挽对的 NFET 的漏电流和输入 FET 的栅极漏电流。小于 1 µA:好的。
  2. 将引脚设置为输入,将引脚驱动为低电平:不是一个好主意。如果软件运行失败并将引脚切换为输出高电平,则您将引脚短路,从而损坏互补对的 PFET。
  3. 将引脚设置为输入,外部上拉:与 1) 相同,只是更贵。但优点是引体向上始终存在;您可能忘记启用内部上拉(默认情况下禁用)。如果 I/O 意外切换到输出低电平,您的电流消耗会很小。
  4. 将引脚设置为输入,外部下拉:再次是电阻器的成本(是的,我知道它们很便宜,但便宜 + 不必要 = 昂贵。)如果引脚会变为高电平,则电流与 3)相同。
  5. 将引脚设置为输出低:比配置为输入时具有更高的泄漏电流,但仍低于 1 µA,因此无需担心。我仍然会启用内部上拉。它不会在 I/O 作为输出时处于活动状态,但如果它意外切换到输入,则该引脚将不会保持浮动。
  6. 将引脚设置为输出高电平:同 5)
  7. 将引脚设置为输出低,外部下拉:下拉电阻是不必要的成本:它会使输出变低,而输出已经很低。但与 5) 相比,您可以确定如果意外切换到输入,引脚不会浮动。

我会选择 1):带内部上拉的输入;无需外部部件。在 FMEA 5) 中可能会更好,但这取决于您估计忘记启用内部上拉的风险有多高。软件设计同行评审应该给你保险。

引脚本身通常不会产生巨大的影响。您会看到每个引脚也有特定的功能 - 禁用引脚的功能

volatile uint8_t timer2sum; // see interrupt handler

void Initialize()
{
    // configure pin for output
    DDR_LED |= LED;

    // set Power Reduction Register
    PRR = (1<<PRTWI)     // turn off TWI
        | (1<<PRTIM0)    // turn off Timer/Counter0
        | (1<<PRTIM1)    // turn off Timer/Counter1 (leave Timer/Counter2 on)
        | (1<<PRSPI)     // turn off SPI
        | (1<<PRUSART0)  // turn off USART (will turn on again when reset)
        | (1<<PRADC);    // turn off ADC

    // select POWER SAVE mode for sleeping, which allows Timer/Counter2 to wake us up
    set_sleep_mode(SLEEP_MODE_PWR_SAVE);

    // configure Timer/Counter2 to wake us up as infrequently as possible
    TCCR2B |= (1<<CS22) | (1<<CS21) | (1<<CS20); // clock at 14400 Hz
    TIMSK2 |= (1<<TOIE2);                        // interrupt on overflow, 56.25 Hz
    timer2sum = 0;                               // see interrupt handler
    sei();                                       // enable interrupts
}

取自http://www.nerdkits.com/library/lowpowerexample/谁也使用相同的芯片。