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

Снова про пониженного энергопотребления в AVR

Здравствуйте. Я понимаю что данная тема многократно поднималась и документации должно быть много.

Я просто хотел уточнить, правильно ли я всё делаю.

 

Имеется AVR Studio 6. И tiny2313 Рабочая частота - 8 МГц. Напряжение - 5 В. Надо его на время переводить его в режим пониженного энергопотребления.

Имеются разрешённые и используемые внешние прерывания.

Собственно, говоря, внутри ISR этих прерываний вся программа и работает.

 

Почитав даташит, сделал так:

 

unsigned long        m_sleep_counter                        =    0;


...
...
...



main()
{
   .....
   .....
   .....

    while(1){
        if (++m_sleep_counter > 10000){
            m_sleep_counter = 0;
            sleep_enable();
            set_sleep_mode(0);

        }
   .....
}

 

К сожалению сейчас скорость выхода из спящего режима на макете оценить сложно. Поэтому имеются вопросы:

 

Ток потребления при переходе из активного режима в спящий (IDLE) падает с 12 до 5 мА.

Как-то много остаётся, или я ошибаюсь?

Какая скорость выхода из спящего режима (IDLE)?

Надо ли что-то конфигурировать для определения условия выхода из спящего режима?

 

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


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

Ток потребления при переходе из активного режима в спящий (IDLE) падает с 12 до 5 мА.

Как-то много остаётся, или я ошибаюсь?

Какая скорость выхода из спящего режима (IDLE)?

1. В даташите есть графики, показывающие потребление при разных тактовых частотах. 5 мА - подозрительно много. У вас, случайно, от ножек МК, выдающих единичку или настроенных на ввод с Pullup'ом, ничего не питается в состоянии сна ?

 

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

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


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

Да, спасибо, есть ноги на ввод с PullUpom. Попробую.

 

Скажите, а если придётся в режим power down переводить, какие возможные сложности могут возникнуть?

И скажите.

На этом форуме нашёл подобную тему ( Как правильно выйти из "спящего режима"). Там, в частности, написано:

И еще. Когда прерывание выводит процессор из спящего режима, то прежде чем перейти к обработчику прерывания, процессор выполнит сначала следующую за командой SLEEP команду. Поэтому следующей командой не стоит сразу ставить CLI, если хотите обеспечить обработку прерывания, а лучше поставить NOP.

 

Это может влиять на что-либо ещё?

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


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

О сложностях вы лучше в даташите прочтите, я делал это давно, деталей не помню и вводить вас в заблуждение не хочу.

 

Когда прерывание выводит процессор из спящего режима, то прежде чем перейти к обработчику прерывания, процессор выполнит сначала следующую за командой SLEEP команду. Поэтому следующей командой не стоит сразу ставить CLI, если хотите обеспечить обработку прерывания, а лучше поставить NOP.

Там неправильно написано. Правильно - в документации (сначала выполняется обработчик, а затем - команда):

 

If an enabled interrupt occurs while the

MCU is in a sleep mode, the MCU wakes up. The MCU is then halted for four cycles in

addition to the start-up time, executes the interrupt routine, and resumes execution from

the instruction following SLEEP.

Чуть ниже в том же документе рассказано, какие узлы и как влияют на потребление в спящем режиме. Вам придется все это изучить ...

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


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

Разобрался с режимом Idle. Там всё просто:

 

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>

unsigned long m_value = 0;
unsigned long m_counter = 0;


void my_delay(){
    for (m_value = 0; m_value < 300; ++m_value){
        asm("nop");
    }
}


ISR(INT1_vect)                      //  Выставление данных
{
    asm("nop");
    m_counter = 0;
    sleep_disable();
}

ISR(INT0_vect)                      //  Чтение данных
{
    asm("nop");
    m_counter = 0;
    sleep_disable();
}


int main(void)
{
    cli();    
    MCUCR = 0x0B;
    GIMSK = 1 << INT0 | 1 << INT1;
    DDRB = 0xFF; 
    asm("sei");
    
    while(1){
        my_delay();
        PORTB = 0;
        my_delay();
        PORTB = 0xFF;
        if (++m_counter > 5){
//            sleep_enable();
            set_sleep_mode(SLEEP_MODE_PWR_DOWN);
            set_sleep_mode(SLEEP_MODE_IDLE);
            asm("sleep");
        }
    }
}

 

Светодиод помигал 5 раз, МК остановился. Кнопочку нажали - обработка прерывания, опять работаем.

 

А вот с режимом Power Down как-то сложнее. Засыпает, но просыпаться не хочет.

Где-то читал, что внешние прерывания только по уровню должны быть. Думаю, как бы их переключить.

 

 

Точнее там в коде так:

 

            sleep_enable();
//            set_sleep_mode(SLEEP_MODE_PWR_DOWN);
            set_sleep_mode(SLEEP_MODE_IDLE);

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


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

Где-то читал, что внешние прерывания только по уровню должны быть.

В даташите написано:

 

Only an External Reset, a Watchdog Reset, a Brown-out Reset, USI

start condition interrupt, an external level interrupt on INT0, or a pin change interrupt can

wake up the MCU. This sleep mode basically halts all generated clocks, allowing operation

of asynchronous modules only.

Note that if a level triggered interrupt is used for wake-up from Power-down mode, the

changed level must be held for some time to wake up the MCU.

Т.е., или прерывание по уровню (не по фронту !), или "pin change interrupt" ...

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


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

Да. Вот только что попробовал Power Down на tiny2313. Ура! Ток потребления всего 1 мкА. Причём работает и по смене уровня.

 

Если можно, объясните, в чём отличие этих понятий "фронт" и "смена уровня".

 

И почему всё-таки работает и по спаду.

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


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

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

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

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

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

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

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

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

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

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