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

 
 
> Снова про пониженного энергопотребления в AVR
vladimir_orl
сообщение Nov 12 2013, 07:44
Сообщение #1


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

Группа: Участник
Сообщений: 191
Регистрация: 18-09-12
Из: Орёл
Пользователь №: 73 591



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

Имеется 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)?
Надо ли что-то конфигурировать для определения условия выхода из спящего режима?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 8)
kovigor
сообщение Nov 12 2013, 08:43
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295



Цитата(vladimir_orl @ Nov 12 2013, 10:44) *
Ток потребления при переходе из активного режима в спящий (IDLE) падает с 12 до 5 мА.
Как-то много остаётся, или я ошибаюсь?
Какая скорость выхода из спящего режима (IDLE)?

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

2. Так ведь это легко измерить двухлучевым осциллографом. Сразу при пробуждении по внешнему прерыванию зажигаете светодиод и осциллографом измеряете промежуток между сигналом прерывания и моментом зажигания светодиода ...
Go to the top of the page
 
+Quote Post
vladimir_orl
сообщение Nov 12 2013, 09:44
Сообщение #3


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

Группа: Участник
Сообщений: 191
Регистрация: 18-09-12
Из: Орёл
Пользователь №: 73 591



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

Скажите, а если придётся в режим power down переводить, какие возможные сложности могут возникнуть?
И скажите.
На этом форуме нашёл подобную тему ( Как правильно выйти из "спящего режима"). Там, в частности, написано:
Цитата
И еще. Когда прерывание выводит процессор из спящего режима, то прежде чем перейти к обработчику прерывания, процессор выполнит сначала следующую за командой SLEEP команду. Поэтому следующей командой не стоит сразу ставить CLI, если хотите обеспечить обработку прерывания, а лучше поставить NOP.


Это может влиять на что-либо ещё?
Go to the top of the page
 
+Quote Post
kovigor
сообщение Nov 12 2013, 10:20
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295



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

Цитата(vladimir_orl @ Nov 12 2013, 13:44) *
Когда прерывание выводит процессор из спящего режима, то прежде чем перейти к обработчику прерывания, процессор выполнит сначала следующую за командой 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
.

Чуть ниже в том же документе рассказано, какие узлы и как влияют на потребление в спящем режиме. Вам придется все это изучить ...
Go to the top of the page
 
+Quote Post
vladimir_orl
сообщение Nov 12 2013, 10:34
Сообщение #5


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

Группа: Участник
Сообщений: 191
Регистрация: 18-09-12
Из: Орёл
Пользователь №: 73 591



Спасибо. Будем изучать.
Go to the top of the page
 
+Quote Post
kovigor
сообщение Nov 12 2013, 10:35
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295



Цитата(vladimir_orl @ Nov 12 2013, 14:34) *
Спасибо. Будем изучать.

Не за что sm.gif
Go to the top of the page
 
+Quote Post
vladimir_orl
сообщение Nov 14 2013, 06:36
Сообщение #7


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

Группа: Участник
Сообщений: 191
Регистрация: 18-09-12
Из: Орёл
Пользователь №: 73 591



Разобрался с режимом 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);
Go to the top of the page
 
+Quote Post
kovigor
сообщение Nov 14 2013, 07:02
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295



Цитата(vladimir_orl @ Nov 14 2013, 10:36) *
Где-то читал, что внешние прерывания только по уровню должны быть.

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

Цитата
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" ...
Go to the top of the page
 
+Quote Post
vladimir_orl
сообщение Nov 14 2013, 07:57
Сообщение #9


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

Группа: Участник
Сообщений: 191
Регистрация: 18-09-12
Из: Орёл
Пользователь №: 73 591



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

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

И почему всё-таки работает и по спаду.
Go to the top of the page
 
+Quote Post

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

 


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


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