|
STM32L151 режим STOP |
|
|
|
Feb 16 2016, 14:49
|
Участник

Группа: Участник
Сообщений: 28
Регистрация: 16-10-15
Пользователь №: 88 891

|
Мозг дымится, прям беда какая то, никак не приручить STOP режим Есть кнопка 1, на которую нужно однократно нажать и ввести мк в стоп. Будить планирую другой кнопкой. Код void EXTI2_IRQHandler(void) { if(EXTI_GetITStatus(EXTI_Line2) != RESET) { NVIC_DisableIRQ(EXTI2_IRQn); stop_enable = 1; LED1_TOGGLE(); EXTI_ClearITPendingBit(EXTI_Line2); } } В основном цикле чекаю флаг кнопки. После его срабатывания ухожу в стоп. Но беда в том, что контроллер не засыпает. Детектирую это светодиодом 2. Код while(1) { if(stop_enable == 1) { PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI); stop_enable = 0; LED2_TOGGLE(); NVIC_EnableIRQ(EXTI2_IRQn); } } Если вводить в сон не по кнопке, то все ок, но нужно именно по кнопке. Создалось впечатление что NVIC_DisableIRQ(EXTI2_IRQn) не отрабатывает, проверил отдельно от этого куска кода - работает. По отдельности все работает, сама проблема в том что именно этот кусок не работает, как сделать по другому не понятно. ЗЫ видел аналогичные темы, выдергивание swd не помогло. Ввожу в стоп не в прерывании.
|
|
|
|
|
 |
Ответов
(1 - 10)
|
Feb 16 2016, 15:10
|
Участник

Группа: Участник
Сообщений: 28
Регистрация: 16-10-15
Пользователь №: 88 891

|
Специально же написал: Ввожу в стоп не в прерывании.
|
|
|
|
|
Feb 16 2016, 15:14
|

Частый гость
 
Группа: Участник
Сообщений: 101
Регистрация: 2-05-15
Из: Россия, Омск
Пользователь №: 86 474

|
Тогда вариант более простой - на обработчике событий. Создаёте глобальную переменную. В прерывании кнопки устанавливаете её в, допустим, 1. В бесконечном цикле проверяете, равна ли переменная единице и если так - усыпляете кристалл. От прерывания отвязались.
Переменная, кстати, volatile? Можете проверить в отладчике, меняется ли она вообще. И посмотреть дизассемблированный код, который был сгенерирован. Некоторые переменные порой... выбрасываются.
Сообщение отредактировал AlanDrakes - Feb 16 2016, 15:24
|
|
|
|
|
Feb 16 2016, 15:26
|
Участник

Группа: Участник
Сообщений: 28
Регистрация: 16-10-15
Пользователь №: 88 891

|
Цитата(AlanDrakes @ Feb 16 2016, 15:14)  Вы издеваетесь надо мной? Так и сделано stop_enable глобальная переменная, если 1 уходим в стоп, проблема в том, что не уходит он так в стоп. Переменная volatile.
Сообщение отредактировал data_stack - Feb 16 2016, 15:26
|
|
|
|
|
Feb 16 2016, 16:05
|

Частый гость
 
Группа: Участник
Сообщений: 101
Регистрация: 2-05-15
Из: Россия, Омск
Пользователь №: 86 474

|
У меня работает отлично вот такой код: Код volatile char test = 0;
void EXTI2_IRQHandler(void) { test = 1; EXTI->PR = 4; // Очищаем бит ожидающего прерывания }; (В main()) <...> EXTI->RTSR |= 4; // По фронту импульса EXTI->IMR |= 4; // Разрешить генерировать прерывание NVIC_EnableIRQ(EXTI2_IRQn); // Разрешить само прерывание while (1) { if (test == 1) { test = 0; PWR->CR |= PWR_CR_PDDS | PWR_CR_LPSDSR; // Маломощный сон SCB->SCR |= SCB_SCR_SLEEPDEEP; // Последний бит, позволяющий именно STOP __WFI(); }; }; <...> Буквально только что заставил работать код на реальном железе. Да, у меня есть плата с этим кристаллом. Останавливается именно после команды __WFI(); и ждёт ближайшего следующего прерывания.
Сообщение отредактировал AlanDrakes - Feb 16 2016, 16:11
|
|
|
|
|
Mar 4 2016, 10:32
|
Участник

Группа: Участник
Сообщений: 28
Регистрация: 16-10-15
Пользователь №: 88 891

|
Поднимаю тему, перетестил много раз - не работает. Упростил задачу, нужно включить контроллер и уйти сразу в standby, если wakeup нажат, то проснуться пересброситься и снова уйти в сон. Код int main() { RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); PWR_WakeUpPinCmd(PWR_WakeUpPin_3, ENABLE); delay_ms(5000); PWR_EnterSTANDBYMode(); } Что выходит на деле: в первый раз все по феньшую - контроллер уходит в сон, жмакаем wakeup и все ломается, контроллер просыпается, тут же засыпает, тут же снова пересбрасывается и так до бесконечности, пока не ресетнешь. Такое впечатление что после того как нажат wakeup нужно сбросить некий бит, что он отработал. Перерыл референс мануал но ничего не нашел похожего
|
|
|
|
|
Mar 4 2016, 11:46
|
Участник

Группа: Участник
Сообщений: 28
Регистрация: 16-10-15
Пользователь №: 88 891

|
Цитата(adnega @ Mar 4 2016, 11:39)  Лихо упростили. while(1){} не забыли? не забыл, в любом случае после входа в стендбай контроллер перезагружается
|
|
|
|
|
Mar 6 2016, 10:43
|
Участник

Группа: Участник
Сообщений: 28
Регистрация: 5-12-06
Пользователь №: 23 160

|
Цитата(data_stack @ Mar 4 2016, 14:46)  не забыл, в любом случае после входа в стендбай контроллер перезагружается Насколько я помню выход из режима standby сопровождается запуском программы сначала... Сохраняются только регистры бэкапа И да, там есть какая-то еррата насчет режима standby...
Сообщение отредактировал veteq - Mar 6 2016, 10:46
|
|
|
|
|
Mar 9 2016, 11:45
|
Участник

Группа: Участник
Сообщений: 28
Регистрация: 16-10-15
Пользователь №: 88 891

|
чутье не подвело, существует флаг, который нужно очищать, иначе каждый раз после входа в standby сразу же из него выходит. В SPL делаю так: PWR_ClearFlag(PWR_FLAG_WU);
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|