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

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

Понадобилось тут "усыпить" STM32F030R8 чтобы только часы работали от резервной батарейки. Сделал вроде все по уму - висячие и не нужные ноги сконфигурировал выходами, где надо pullup/pulldown в нужную сторону, усыпляю - жрет 500 мкА. Перешерстил схему, код, прощупал все в поисках неправильных подтяжек и паразитных питаний - все ОК. Перечитал Reference manual, Datasheet и еррату. Все по науке, криминала не нашел. Поменял контроллер - предположил что подпаленный - результат тот же, - 450-500 мкА.
Вернулся к коду. В начале main инициализирую RCC и GPIO, усыпляю - потребляет 30 мкА, как и должно. Значит проблема в какой-то периферии далее. Копаю дальше не маленький код, тыкаю осциллографом, листаю регистры в отладчике, построчно комментирую. Проблема то появится то исчезнет, на ее локализацию ушло полдня и много нервных клеток.
Причина: используется у меня ножка GPIOB1 как вход для внешнего прерывания в режиме когда подключено основное питание. Подтянута вверх. Во сне эта ножка не нужна и я ее подтягиваю к земле, чтобы не давала паразитного питания на остальную схему которая обесточена. Перед этим, естественно, запрещаю соответствующее прерывание. Причем запрещал только в NVIC, а в регистрах EXTI->IMR, EXTI->FTSR оставлял разрешенным. В результате, как только я (перед сном sm.gif )дрыгаю этой ногой вниз, взводится флаг в EXTI->PR, но прерывание не возникает, поскольку запрещено в NVIC. Так вот, если контроллер теперь положить в любой из энергосберегающих режимов, с установленными битами в PR - он будет потреблять лишние 450 мкА!
Решение:
1. Если надо запретить внеш. прерывание, делать это сначала в периф. модуле, а уж потом, если есть необходимость - в NVIC.
2. После запрета в NVIC - вручную сбросить pending bits, если таковые появились.
3. После выполнения п.2 сразу переводить МК в low power mode, не дрыгая ногами.
Код для "воспроизведения" граблей:
CODE
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();
// Тут отладчик отвалится, смотрим на амперметр.
// Также надо отключить разъем отладчика - он тоже потребляет ток.
}


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

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


Ссылка на сообщение
Поделиться на другие сайты
Цитата(stas00n @ Jan 25 2018, 10:44) <{POST_SNAPBACK}>
усыпляю - потребляет 30 мкА, как и должно.

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

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


Ссылка на сообщение
Поделиться на другие сайты
Цитата(KnightIgor @ Jan 25 2018, 13:13) <{POST_SNAPBACK}>
Порядком не ошиблись? Чего-то много...

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

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


Ссылка на сообщение
Поделиться на другие сайты
Цитата(stas00n @ Jan 25 2018, 12:45) <{POST_SNAPBACK}>
При измерении не ошибся - 33 мкА. А по даташиту действительно обещается около 3.5 мкА. Видать что-то еще поджирает, будем искать...

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

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


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

Цитата(KnightIgor @ Jan 25 2018, 14:05) <{POST_SNAPBACK}>
Вы там ноги вниз тянете перед сном. Может где pull-up включен, вот он и жрёт?

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

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

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


Ссылка на сообщение
Поделиться на другие сайты
Цитата(stas00n @ Jan 25 2018, 13:40) <{POST_SNAPBACK}>
Действительно, забыл подать клок на секцию 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

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


Ссылка на сообщение
Поделиться на другие сайты
QUOTE (KnightIgor @ Apr 27 2018, 19:16) <{POST_SNAPBACK}>
Кто хавает
Фу. Не в подворотне же.

Из техописания на F030, раздел "I/O system current consumption"
QUOTE
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.
Не забывайте, что у кристалла есть выводы, которые не выведены на ноги корпуса.

QUOTE (KnightIgor @ Apr 27 2018, 19:16) <{POST_SNAPBACK}>
По ходу обнаружил интересную вещь: у меня используется только внутренний генератор, внешние ножки OSC не используются. Так вот, потребление процессора уменьшается ощутимо, если посадить вход OSC на землю. Правда, я еще не достиг таким образом желаемых 4мкА, но всем может быть полезно: заземляйте вход OSC, если не используется!

Из руководства пользователя F030, F070:
QUOTE
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.

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


Ссылка на сообщение
Поделиться на другие сайты
Цитата(Сергей Борщ @ Apr 27 2018, 21:19) <{POST_SNAPBACK}>
Фу. Не в подворотне же.

После дня борьбы с этими двумя платами с такими разными токами в 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.
В итоге - пока не нащупал, где утекает.


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


Ссылка на сообщение
Поделиться на другие сайты
Цитата(KnightIgor @ Apr 29 2018, 23:07) <{POST_SNAPBACK}>
Предупреждая идеи, касаемые отдельного генератора для ADC: я его намеренно не использую, тактируя ADC в итоге от HSI, хотя генератор ADC тоже должен стоять в STOP.

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

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


Ссылка на сообщение
Поделиться на другие сайты
Цитата(aaarrr @ Apr 29 2018, 21:25) <{POST_SNAPBACK}>
Хм. На F070 тактирование ADC от HSI приводит к лютому потреблению в STOP.

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

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


Ссылка на сообщение
Поделиться на другие сайты
Цитата(KnightIgor @ Apr 30 2018, 01:33) <{POST_SNAPBACK}>
Интересно... Надо попробовать. Вроде же все генераторы стоят в STOP. Да и запрещаю я ADC (выключаю ENABLE бит) перед STOP.

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

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


Ссылка на сообщение
Поделиться на другие сайты
Цитата(aaarrr @ Apr 29 2018, 23:55) <{POST_SNAPBACK}>
Проверьте. Причину такого поведения не искал, т.к. тактирование АЦП от 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 удавалось добиваться потребления в соответствии с документацией без танцев с бубном.

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


Ссылка на сообщение
Поделиться на другие сайты
Цитата(amiller @ May 1 2018, 08:16) <{POST_SNAPBACK}>
. . . . А периферию, ненужную во время сна, нужно было питать от другого (отключаемого) источника. . . .
На макетных испытаниях (платформа MSP430+CPLD) по такой схеме потребление не только не понизилось, а наоборот, возросло и "плавало".
(возможно - из-за образования "неопределенных" уровней на входах контроллера). Пробовали подтягивать входы вверх-вниз - ерунда получалась.
Кроме отключения АЦП надо проверять неактивность REF. Возможно вход АЦП перевести в режим цифрового входа.
Если остался неподключенный цифровой вход, или цифровой вход, на который приходит импульсный-частотный сигнал - ОНО будет потреблять
динамический ток переключения цепей входной периферии. Ток потребления (всей схемы) смотреть с низкоомного шунта, подключенного к земле.
Или использовать изм. усилитель (тогда можно шунт ставить "вверху" и смотреть по узлам схемы).

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


Ссылка на сообщение
Поделиться на другие сайты
Цитата(k155la3 @ May 1 2018, 13:23) <{POST_SNAPBACK}>
На макетных испытаниях (платформа MSP430+CPLD) по такой схеме потребление не только не понизилось, а наоборот, возросло и "плавало".

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

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


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

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти