реклама на сайте
подробности

 
 
> STM32L151 режим STOP
data_stack
сообщение Feb 16 2016, 14:49
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 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 не помогло. Ввожу в стоп не в прерывании.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 10)
AlanDrakes
сообщение Feb 16 2016, 15:01
Сообщение #2


Частый гость
**

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



В прерывании нельзя засыпать.
Но есть возможность заснуть по выходе из прерывания.
Вам потребуется бит SLEEPONEXIT: SCB->SCR |= SCB_SCR_SLEEPONEXIT;
Эта инструкция должна быть максимально последней перед завершением обработчика прерывания.
Проверьте.
Go to the top of the page
 
+Quote Post
data_stack
сообщение Feb 16 2016, 15:10
Сообщение #3


Участник
*

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



Специально же написал: Ввожу в стоп не в прерывании.
Go to the top of the page
 
+Quote Post
AlanDrakes
сообщение Feb 16 2016, 15:14
Сообщение #4


Частый гость
**

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



Тогда вариант более простой - на обработчике событий.
Создаёте глобальную переменную. В прерывании кнопки устанавливаете её в, допустим, 1.
В бесконечном цикле проверяете, равна ли переменная единице и если так - усыпляете кристалл. От прерывания отвязались.

Переменная, кстати, volatile? Можете проверить в отладчике, меняется ли она вообще. И посмотреть дизассемблированный код, который был сгенерирован.
Некоторые переменные порой... выбрасываются.

Сообщение отредактировал AlanDrakes - Feb 16 2016, 15:24
Go to the top of the page
 
+Quote Post
data_stack
сообщение Feb 16 2016, 15:26
Сообщение #5


Участник
*

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



Цитата(AlanDrakes @ Feb 16 2016, 15:14) *

Вы издеваетесь надо мной? Так и сделано stop_enable глобальная переменная, если 1 уходим в стоп, проблема в том, что не уходит он так в стоп. Переменная volatile.

Сообщение отредактировал data_stack - Feb 16 2016, 15:26
Go to the top of the page
 
+Quote Post
AlanDrakes
сообщение Feb 16 2016, 16:05
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
data_stack
сообщение Mar 4 2016, 10:32
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 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 нужно сбросить некий бит, что он отработал. Перерыл референс мануал но ничего не нашел похожего
Go to the top of the page
 
+Quote Post
adnega
сообщение Mar 4 2016, 10:39
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(data_stack @ Mar 4 2016, 13:32) *
Упростил задачу

Лихо упростили.
while(1){} не забыли?
Go to the top of the page
 
+Quote Post
data_stack
сообщение Mar 4 2016, 11:46
Сообщение #9


Участник
*

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



Цитата(adnega @ Mar 4 2016, 11:39) *
Лихо упростили.
while(1){} не забыли?

не забыл, в любом случае после входа в стендбай контроллер перезагружается
Go to the top of the page
 
+Quote Post
veteq
сообщение Mar 6 2016, 10:43
Сообщение #10


Участник
*

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



Цитата(data_stack @ Mar 4 2016, 14:46) *
не забыл, в любом случае после входа в стендбай контроллер перезагружается


Насколько я помню выход из режима standby сопровождается запуском программы сначала... Сохраняются только регистры бэкапа

И да, там есть какая-то еррата насчет режима standby...

Сообщение отредактировал veteq - Mar 6 2016, 10:46
Go to the top of the page
 
+Quote Post
data_stack
сообщение Mar 9 2016, 11:45
Сообщение #11


Участник
*

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



чутье не подвело, существует флаг, который нужно очищать, иначе каждый раз после входа в standby сразу же из него выходит. В SPL делаю так: PWR_ClearFlag(PWR_FLAG_WU);
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 29th June 2025 - 15:50
Рейтинг@Mail.ru


Страница сгенерированна за 0.01442 секунд с 7
ELECTRONIX ©2004-2016