Перейти к содержанию
    

Грабли с энергосбережением STM32F0

Понадобилось тут "усыпить" STM32F030R8 чтобы только часы работали от резервной батарейки. Сделал вроде все по уму - висячие и не нужные ноги сконфигурировал выходами, где надо pullup/pulldown в нужную сторону, усыпляю - жрет 500 мкА. Перешерстил схему, код, прощупал все в поисках неправильных подтяжек и паразитных питаний - все ОК. Перечитал Reference manual, Datasheet и еррату. Все по науке, криминала не нашел. Поменял контроллер - предположил что подпаленный - результат тот же, - 450-500 мкА.

Вернулся к коду. В начале main инициализирую RCC и GPIO, усыпляю - потребляет 30 мкА, как и должно. Значит проблема в какой-то периферии далее. Копаю дальше не маленький код, тыкаю осциллографом, листаю регистры в отладчике, построчно комментирую. Проблема то появится то исчезнет, на ее локализацию ушло полдня и много нервных клеток.

Причина: используется у меня ножка GPIOB1 как вход для внешнего прерывания в режиме когда подключено основное питание. Подтянута вверх. Во сне эта ножка не нужна и я ее подтягиваю к земле, чтобы не давала паразитного питания на остальную схему которая обесточена. Перед этим, естественно, запрещаю соответствующее прерывание. Причем запрещал только в NVIC, а в регистрах EXTI->IMR, EXTI->FTSR оставлял разрешенным. В результате, как только я (перед сном :) )дрыгаю этой ногой вниз, взводится флаг в EXTI->PR, но прерывание не возникает, поскольку запрещено в NVIC. Так вот, если контроллер теперь положить в любой из энергосберегающих режимов, с установленными битами в PR - он будет потреблять лишние 450 мкА!

Решение:

1. Если надо запретить внеш. прерывание, делать это сначала в периф. модуле, а уж потом, если есть необходимость - в NVIC.

2. После запрета в NVIC - вручную сбросить pending bits, если таковые появились.

3. После выполнения п.2 сразу переводить МК в low power mode, не дрыгая ногами.

Код для "воспроизведения" граблей:

void Exti_Leak_Test()
{
 // Включаем тактирование..
 RCC_AHBPeriphClockCmd((RCC_AHBPeriph_GPIOA |
                        RCC_AHBPeriph_GPIOB |
                        RCC_AHBPeriph_GPIOC |
                        RCC_AHBPeriph_GPIOD |
                        RCC_AHBPeriph_GPIOF ), ENABLE);
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

 // ..и инициализируем GPIO
 GPIO_InitTypeDef io;
 // Все "не нужные" входы подтягиваем:
 io.GPIO_Mode = GPIO_Mode_IN;
 io.GPIO_OType = GPIO_OType_PP;
 io.GPIO_PuPd = GPIO_PuPd_DOWN;
 io.GPIO_Speed = GPIO_Speed_Level_1;
 // Пины SWD не трогаем
 io.GPIO_Pin = (GPIO_Pin_All & (~GPIO_Pin_13) & (~GPIO_Pin_14));
 GPIO_Init(GPIOA, &io);

 io.GPIO_Pin = GPIO_Pin_All;
 GPIO_Init(GPIOB, &io);
 GPIO_Init(GPIOC, &io);
 GPIO_Init(GPIOD, &io);
 GPIO_Init(GPIOF, &io);

 // Настраиваем внешнее прерывание:
 SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource1);

 EXTI_InitTypeDef exti;
 exti.EXTI_Line = EXTI_Line1;
 exti.EXTI_Trigger = EXTI_Trigger_Rising;
 exti.EXTI_Mode = EXTI_Mode_Interrupt;
 // ..и разрешаем его в периф. модуле, но не разрешаем в NVIC
 exti.EXTI_LineCmd = ENABLE;
 EXTI_Init(&exti);

 // "Генерируем" прерывание дергая подтяжку на PB1
 GPIOB->PUPDR &= ~(0xC);
 GPIOB->PUPDR |= 4;    

 // Ждем нарастания фронта
 volatile uint32_t delay = 1000;
 while(--delay);

 // Возвращаем подтяжку PB1 к земле
 GPIOB->PUPDR &= ~(0xC);
 GPIOB->PUPDR |= 8;

 // Если не сбросить бит в EXTI->PR, будет лишнее потребление тока
 //EXTI->PR = 2;

 // Переходим в режим STOP
 //PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
 // ..или StandBy
 PWR_EnterSTANDBYMode();
 // Тут отладчик отвалится, смотрим на амперметр.
 // Также надо отключить разъем отладчика - он тоже потребляет ток.
}

 

Может кому поможет. Сам я не нашел ни предупреждений в документации, ни прецедентов в гугле.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

усыпляю - потребляет 30 мкА, как и должно.

Порядком не ошиблись? Чего-то много...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Порядком не ошиблись? Чего-то много...

При измерении не ошибся - 33 мкА. А по даташиту действительно обещается около 3.5 мкА. Видать что-то еще поджирает, будем искать...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

При измерении не ошибся - 33 мкА. А по даташиту действительно обещается около 3.5 мкА. Видать что-то еще поджирает, будем искать...

Вы там ноги вниз тянете перед сном. Может где pull-up включен, вот он и жрёт?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Действительно, забыл подать клок на секцию PWR. Поэтому был режим не standby, а Sleep. Сейчас 3.1 мкА. Спасибо.

 

Вы там ноги вниз тянете перед сном. Может где pull-up включен, вот он и жрёт?

не, уже разобрался - см. выше. пулапы проверены были в первую очередь. Да и в standby режиме все подтяжки отключаются автоматом.. Я еще думал почему у меня порты сохраняют состояние, хотя в ДШ написано обратное.

 

И, кстати, не сброшенный флаг в EXTI->PR "жрет", получается, только в Sleep mode, а в Stop и Standby - не влияет.

Изменено пользователем stas00n

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Действительно, забыл подать клок на секцию PWR. Поэтому был режим не standby, а Sleep. Сейчас 3.1 мкА. Спасибо.

Вернулся к теме, т.к. теперь сам тут вожусь с F051, загоняю его в STOP режим и получаю...

 

Вот тут уже интересно.

У меня два экземпляра платы, совершенно идентичные, однако одна жрет в STOP (если исключить другие чипы, которые в сумме едят 26мкА) где-то 125мкА, а другая 370мкА! Причем та самая внешняя периферия на обеих платах ест одинаково 26мкА, что я определил, усадив F051 экспериментально в полный Standby.

 

- Тактирование PWR модуля включено.

 

- Перед входом в STOP:

+ PWR->CR |= PWR_CR_LPDS;

+ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;

+ USART выключается на всякий.

+ ADC выключается, а также запрещаются VREF и TEMP.

+ DAC не используется (он там есть вообще?).

 

Кто хавает ток в темноте, не знаю...

 

По ходу обнаружил интересную вещь: у меня используется только внутренний генератор, внешние ножки OSC не используются. Так вот, потребление процессора уменьшается ощутимо, если посадить вход OSC на землю. Правда, я еще не достиг таким образом желаемых 4мкА, но всем может быть полезно: заземляйте вход OSC, если не используется!

Изменено пользователем KnightIgor

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кто хавает
Фу. Не в подворотне же.

 

Из техописания на F030, раздел "I/O system current consumption"

Caution: Any floating input pin can also settle to an intermediate voltage level or switch inadvertently,

as a result of external electromagnetic noise. To avoid current consumption related to

floating pins, they must either be configured in analog mode, or forced internally to a definite

digital value. This can be done either by using pull-up/down resistors or by configuring the

pins in output mode.

Не забывайте, что у кристалла есть выводы, которые не выведены на ноги корпуса.

 

По ходу обнаружил интересную вещь: у меня используется только внутренний генератор, внешние ножки OSC не используются. Так вот, потребление процессора уменьшается ощутимо, если посадить вход OSC на землю. Правда, я еще не достиг таким образом желаемых 4мкА, но всем может быть полезно: заземляйте вход OSC, если не используется!

Из руководства пользователя F030, F070:

The PC13/PC14/PC15 GPIO functionality is lost when the core supply domain is powered

off (when the device enters Standby mode). In this case, if their GPIO configuration is not

bypassed by the RTC configuration, these pins are set in an analog input mode.

For details about I/O control by the RTC, refer to Section21.4: RTC functional description

on page485

А уже по ссылке написано, что в RTC есть специальные биты для задания режима этих ног в Standby.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Фу. Не в подворотне же.

После дня борьбы с этими двумя платами с такими разными токами в STOP и безрезультатными попытками посадить процессоры на диету я просто явно себе представил, как эти два процессора, словно две гиены в темноте саванны, издеваются надо мной, совершенно внаглую обгладывают шину питания, срывая с нее электроны, утробно урча и злобно озираясь при этом. Мне удалось выразить мои ощучения одним словом. В любом случае, это лучше, чем "мочить в сортире" из Питерских подворотень.

 

Касаемо замечания по RTC: моя цель - не standby, а STOP процессора F051K8 (LQFP32). RTC не используется вообще, PC13..PC15 в моем корпусе отсутствуют, но если PC13..PC15 уходят в analog input, то по цитате, "they must either be configured in analog mode" - это просто то, что нужно! Идея с имеющимися, но невыведенными ногами портов, весьма интересна. Попробую, хотя странно это.

 

Предупреждая идеи, касаемые отдельного генератора для ADC: я его намеренно не использую, тактируя ADC в итоге от HSI, хотя генератор ADC тоже должен стоять в STOP.

В итоге - пока не нащупал, где утекает.

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Предупреждая идеи, касаемые отдельного генератора для ADC: я его намеренно не использую, тактируя ADC в итоге от HSI, хотя генератор ADC тоже должен стоять в STOP.

Хм. На F070 тактирование ADC от HSI приводит к лютому потреблению в STOP.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Хм. На F070 тактирование ADC от HSI приводит к лютому потреблению в STOP.

Интересно... Надо попробовать. Вроде же все генераторы стоят в STOP. Да и запрещаю я ADC (выключаю ENABLE бит) перед STOP. Пока этого не делал, ADC кушал почти 1mA, о чем, однако, предупреждают в DS или RM (точно уже не помню, где именно).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Интересно... Надо попробовать. Вроде же все генераторы стоят в STOP. Да и запрещаю я ADC (выключаю ENABLE бит) перед STOP.

Проверьте. Причину такого поведения не искал, т.к. тактирование АЦП от HSI использовал исключительно в порядке эксперимента.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Проверьте. Причину такого поведения не искал, т.к. тактирование АЦП от HSI использовал исключительно в порядке эксперимента.

Проверил.

- Ничего не меняется в STOP, тактируй я ADC от HSI (PLL/4) или своего родного HSI14. Было ожидаемо: оба HSI в STOP стоят согласно докам. Главное вырубить сам ADC, который ест 0.9mA всегда.

- Ноги OSC - это PF0 и PF1. Перевел их в OUT и определил 0 на выходы. Ну да, теперь можно не заземлять OSC_IN. Этот вопрос решен. Спасибо, Сергей Борщ.

- Пробовал ту же тему с PC13..PC15, которые на моем F051K8 просто отсутствуют. Никаких изменений в какую либо сторону.

- Вроде нашел причину, почему две платы кушали разные токи в STOP. В схеме есть SN65HVD72. Когда укладывал систему спать, я выключал UART2, хотя, наверное, можно этого и не делать. При этом на TX почему-то появлялся потенциал ощутимо меньший логической "1" (в районе 2V вместо 3.3V). Предположительно, этот промежуточный потенциал переводил вход SN65HVD72 в состояние линейного усилителя, потребление которого разнится от экземпляра к экземпляру. Теперь я перед сном "забираю" линию TX у UART2 и программирую её как обычный GPIO c выходом логической "1". Понятное дело, -RE и DE чипа SN65HVD72 управляются от отдельных GPIO, которые устанавливаются в запреты перед сном. Разброс потребления между экземплярами ушел, оба потребляют 125мкА, 25мкА из которых съедает внешняя периферия: SN65HVD72, FM24LC04B, BQ24232, MCP1702 и некий Pull-up в 1M, если в подробности не вдаваться.

 

Короче, 100мкА куда-то текут. Цель - 4мкА из дока - пока не достигнута.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А ток потребления измеряете до линейника 3V3 или после? 100 мкА вполне может оказаться собственным потреблением LDO, если он выбран неправильно.

А периферию, ненужную во время сна, нужно было питать от другого (отключаемого) источника. Иначе возникает сомнение, где тут ток периферии, а где ток контроллера, теоретические умозаключения?

При соблюдении этих условий на F1 и F4 удавалось добиваться потребления в соответствии с документацией без танцев с бубном.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

. . . . А периферию, ненужную во время сна, нужно было питать от другого (отключаемого) источника. . . .
На макетных испытаниях (платформа MSP430+CPLD) по такой схеме потребление не только не понизилось, а наоборот, возросло и "плавало".

(возможно - из-за образования "неопределенных" уровней на входах контроллера). Пробовали подтягивать входы вверх-вниз - ерунда получалась.

Кроме отключения АЦП надо проверять неактивность REF. Возможно вход АЦП перевести в режим цифрового входа.

Если остался неподключенный цифровой вход, или цифровой вход, на который приходит импульсный-частотный сигнал - ОНО будет потреблять

динамический ток переключения цепей входной периферии. Ток потребления (всей схемы) смотреть с низкоомного шунта, подключенного к земле.

Или использовать изм. усилитель (тогда можно шунт ставить "вверху" и смотреть по узлам схемы).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На макетных испытаниях (платформа MSP430+CPLD) по такой схеме потребление не только не понизилось, а наоборот, возросло и "плавало".

Может я некорректно выразился, но здесь я имел в виду не ту периферию, что входит в состав МК, а внешние микросхемы, которые питаются от одного с МК источника (как я понял ТС).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...