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

 
 
> Снова про пониженного энергопотребления в 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
Ответов
vladimir_orl
сообщение Nov 14 2013, 06:36
Сообщение #2


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

Группа: Участник
Сообщений: 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
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 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



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

 


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


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