Немного о режимах низкого энергопотребления в AVR

Обсуждаем контроллеры компании Atmel.
Ответить
Прорезались зубы
Сообщения: 204
Зарегистрирован: Вт мар 31, 2009 09:14:47

Сообщение ferio »

Добрый день.
Есть устройство на борту которого Mega + 1СД + 1кнопка.
По нажатию кнопки, СД плавно гаснет до нуля, по "отжатию" плавно разгорается до 100% (ШИМ) .
Но задача чуть более сложнее, нужно в "крайних положениях" заставить МК потреблять как можно меньше тока.
Сейчас сделал увод МК в режим Idle, из которого МК выходит по INT1 any change. Но режим Idle не дает такой экономии, как PowerDown. А из Powerdown МК можно разбудить ножкой только по уровню..... Вот палка о двух концах :kill:
Подскажите, как выйти красиво в данной ситуации? Может каким то образом watchdog задействовать?
Спойлер

Код: Выделить всё

/*****************************************************
This program was produced by the
CodeWizardAVR V2.05.0 Professional
Automatic Program Generator
© Copyright 1998-2010 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project : 
Version : 
Date    : 13.01.2017
Author  : 
Company : 
Comments: 


Chip type               : ATmega32L
Program type            : Application
AVR Core Clock frequency: 16,000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 512
*****************************************************/

#include <mega32.h>
#include <delay.h>
#include <sleep.h>

// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
  
     
}



// Declare your global variables here
//int flag_on, flag_off;



void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTA=0xFF;
DDRA=0x00;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out 
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0 
PORTD=0x7F;
DDRD=0x80;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=0xFF
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: 1000,000 kHz
// Mode: Fast PWM top=0xFF
// OC2 output: Non-Inverted PWM
ASSR=0x00;
TCCR2=0x69;
TCNT2=0x00;
OCR2=0x00;


// External Interrupt(s) initialization
// INT0: Off
// INT1: On
// INT1 Mode: Any change
// INT2: Off
GICR|=0x80;
MCUCR=0x04;
MCUCSR=0x00;
GIFR=0x80;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// USART initialization
// USART disabled
UCSRB=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// ADC initialization
// ADC disabled
ADCSRA=0x00;

// SPI initialization
// SPI disabled
SPCR=0x00;

// TWI initialization
// TWI disabled
TWCR=0x00;

#asm("sei") 
while (1)
      {  
           if(PIND.3==1 && OCR2<0xFF) 
        {  
        TCCR2=0x6D; 
        OCR2=OCR2+0x01;
        delay_ms(10);     
        }    
                  
        if(PIND.3==0 && OCR2>0x00) //закрыли дверь
        {   
        TCCR2=0x6D; 
        OCR2=OCR2-0x01;
        delay_ms(10);  

        }    
        
        if(PIND.3==0 && OCR2==0x00)   //лампа погасла
        { 
         TCCR2=0x00;  //отключение ШИМ
         PORTD.7=0; 
         
         //MCUCR=0x00;
         sleep_enable();  //////  ЗДЕСЬ ЛОЖИМСЯ СПАТЬ
         idle();     //////        
        }  
        
        if(PIND.3==1 && OCR2==0xFF) 
        {  
        TCCR2=0x6D; 
        PORTD.7=1;        
        } 
Реклама
Родился
Сообщения: 18
Зарегистрирован: Чт ноя 24, 2016 20:16:46

Сообщение krash_artem »

Так а в чём проблема в пробуждении по уровню? МК также проснётся и начнёт гасить диод
Реклама
Прорезались зубы
Сообщения: 204
Зарегистрирован: Вт мар 31, 2009 09:14:47

Сообщение ferio »

мое событие - переход или из 1 в 0, или из 0 в 1. а не постоянный уровень.
Родился
Сообщения: 18
Зарегистрирован: Чт ноя 24, 2016 20:16:46

Сообщение krash_artem »

ferio писал(а):мое событие - переход или из 1 в 0, или из 0 в 1. а не постоянный уровень.
А если после нажатия менять настройку постоянного уровня? То есть проснулся по низкому уровню - отработал программу действий - установил прерывание на высокий уровень - уснул. Проснулся от высокого уровня - отработал программу действий - установил прерывание на низкий уровнень - уснул.
Реклама
Эиком - электронные компоненты и радиодетали
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

krash_artem писал(а):А если после нажатия менять настройку постоянного уровня?
В какой-то меге есть такая возможность?

Добавлено after 6 minutes 57 seconds:
ferio, Вам кнопку обязательно в роли тумблера использовать? Еще в мегах есть внешнее прерывание PCINT, не во всех.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Реклама
Это не хвост, это антенна
Аватара пользователя
Сообщения: 1314
Зарегистрирован: Пт ноя 27, 2009 19:47:13
Откуда: Казань

Сообщение НАПАЛМ »

СпойлерИзображение
Ну используйте ноги с pin change, а не int0/1 значит.
Реклама
Прорезались зубы
Сообщения: 204
Зарегистрирован: Вт мар 31, 2009 09:14:47

Сообщение ferio »

В какой-то меге есть такая возможность?
да, вот тоже идея ясна, а реализация нет. прерывание только по низкому уровню

ferio, Вам кнопку обязательно в роли тумблера использовать? Еще в мегах есть внешнее прерывание PCINT, не во всех.
По сути да. Чтобы проще было понять, это девайс для плавного розжига и гашения салонного света. Концевик двери - соответственно, тот самый "тумблер".

У меня мега 32, и похоже PCINT в ней нет.... Теоретически могу взять другой МК, если такой вариант заведется.
Родился
Сообщения: 18
Зарегистрирован: Чт ноя 24, 2016 20:16:46

Сообщение krash_artem »

Z_h_e писал(а):В какой-то меге есть такая возможность?
Ой, ошибся, почему-то подумалось что 4ый режим внешнего прерывания это высокий уровень, а не смена логического уровня.

Добавлено after 3 minutes 46 seconds:
ferio писал(а):
В какой-то меге есть такая возможность?
да, вот тоже идея ясна, а реализация нет. прерывание только по низкому уровню
Тогда почему бы не использовать прерывание по смене логического уровня? А уж в обработчике прерывания решать, что же именно делать.
Вложения
pin.jpg
(64.91 КБ) 530 скачиваний
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Какой смысл усыплять МК при включенном освещении?
При выключенном тоже, сомнительный смысл бороться за мкА при токе саморазряда в несколько мА.
И главное. Возьмет МК под задачу. Критерий выбора МК "у меня такой есть" тоже имеет месту быть, но он существенен когда взамен надо потратить деньги, а не 100 рублей.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Прорезались зубы
Сообщения: 204
Зарегистрирован: Вт мар 31, 2009 09:14:47

Сообщение ferio »

krash_artem писал(а): Тогда почему бы не использовать прерывание по смене логического уровня? А уж в обработчике прерывания решать, что же именно делать.
НАПАЛМ выше выложил скрин, что из powerdown можно вывести только уровнем(low level). Или я не понял вашей идеи.

Добавлено after 3 minutes 16 seconds:
Z_h_e , потому что при включенном освещении это освещение работает 30 минут и гаснет. Иначе высосанный АКБ за ночь.
А почему бы не побороться, и не потренироваться) Так мА там мА, и по всей машине может набраться вполне приличное потребление.
Я не против использования другого МК, если мне точно скажете , что вариант с PCINT рабочий, завтра пойду - куплю, мега32 просто под рукой была....
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

krash_artem писал(а):Тогда почему бы не использовать прерывание по смене логического уровня? А уж в обработчике прерывания решать, что же именно делать.
Вы крайне невнимательны. Данное прерывание не работает в зимней спячке в режиме power-down.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Родился
Сообщения: 18
Зарегистрирован: Чт ноя 24, 2016 20:16:46

Сообщение krash_artem »

Да уж и снова я мимо. Так, а если INT2? Оно же и из спячки будить умеет, и по разным фронтам работать. Оно не подойдёт?
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Я не против использования другого МК, если мне точно скажете , что вариант с PCINT рабочий, завтра пойду - куплю, мега32 просто под рукой была....
Смотрите ДШ и выберете МК под задачу. Мега32 имеет не лучшую периферию из avr и для такой задачи хват 1КБ флеш с запасом и количество пинов рабочих Вам только два нужно.

Сделайте проект в протеусе. Протеус, само собой не без глюков, но в целом работает очень не плохо. Затем допилите в железе. АВРы не усыплял, был давний опыт с ПИКом, не знаю как протеус сон отработает.

Вот к примеру tiny13
7.1.3 Power-down Mode
When the SM[1:0] bits are written to 10, the SLEEP instruction makes the MCU enter Powerdown mode. In this mode, the Oscillator is stopped, while the external interrupts, and the Watchdog continue operating (if enabled). Only an External Reset, a Watchdog Reset, a Brown-out
Reset, an external level interrupt on INT0, or a pin change interrupt can wake up the MCU. This
sleep mode halts all generated clocks, allowing operation of asynchronous modules only.
Добавлено after 1 minute 53 seconds:
krash_artem писал(а):Да уж и снова я мимо. Так, а если INT2?
Вы не гадайте. Берите МК, читайте на него ДШ.
Последний раз редактировалось Z_h_e Ср янв 18, 2017 19:37:37, всего редактировалось 1 раз.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Родился
Сообщения: 18
Зарегистрирован: Чт ноя 24, 2016 20:16:46

Сообщение krash_artem »

Z_h_e писал(а):Вы не гадайте. Берите МК, читайте на него ДШ.
Вот, вроде по даташиту на мегу32. Пробуждение от ИНТ2 имеется и оно работает только по фронтам.
Вложения
pin.jpg
(141.79 КБ) 265 скачиваний
int2.jpg
(197.94 КБ) 568 скачиваний
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Ага, вроде тут все так.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Прорезались зубы
Сообщения: 204
Зарегистрирован: Вт мар 31, 2009 09:14:47

Сообщение ferio »

krash_artem писал(а):
Z_h_e писал(а):Вы не гадайте. Берите МК, читайте на него ДШ.
Пробуждение от ИНТ2 имеется и оно работает только по фронтам.
захожу в генератор кода CVAR. по int2 там только или Falling или Rising, any change нет(

ps. я возьму другой мк и попробую PCINT, возможно получится
Родился
Сообщения: 18
Зарегистрирован: Чт ноя 24, 2016 20:16:46

Сообщение krash_artem »

ferio писал(а): захожу в генератор кода CVAR. по int2 там только или Falling или Rising, any change нет(

ps. я возьму другой мк и попробую PCINT, возможно получится
Ну да, просто работаем по фронтам. После срабатывания прерывания по одному фронту, переключаемся на срабатывание по другому фронту.
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

То Вам только уровень не нравится. То теперь фронт и спад :).
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Прорезались зубы
Сообщения: 204
Зарегистрирован: Вт мар 31, 2009 09:14:47

Сообщение ferio »

krash_artem писал(а): Ну да, просто работаем по фронтам. После срабатывания прерывания по одному фронту, переключаемся на срабатывание по другому фронту.
Хорошо. Попробую переключаться.
Прорезались зубы
Сообщения: 204
Зарегистрирован: Вт мар 31, 2009 09:14:47

Сообщение ferio »

отчитываюсь.
получилось, но наполовину.
при низком уровне - лампа гаснет, мк уходит в глубокий сон.
на высокий уровень -просыпается, лампа загорается, но в сон не уходит.
может я что то с регистром MCUCSR не так сделал.
посмотрите, пожалуйста:
Спойлер

Код: Выделить всё

/*****************************************************
This program was produced by the
CodeWizardAVR V2.05.0 Professional
Automatic Program Generator
© Copyright 1998-2010 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project : 
Version : 
Date    : 13.01.2017
Author  : 
Company : 
Comments: 


Chip type               : ATmega32L
Program type            : Application
AVR Core Clock frequency: 16,000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 512
*****************************************************/

#include <mega32.h>
#include <delay.h>
#include <sleep.h>

// External Interrupt 1 service routine
interrupt [EXT_INT2] void ext_int2_isr(void)
{
    
}


// Declare your global variables here
//int flag_on, flag_off;



void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTA=0xFF;
DDRA=0x00;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=P State1=T State0=T 
PORTB=0x04;
DDRB=0x00;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out 
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0 
PORTD=0x7F;
DDRD=0x80;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=0xFF
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: 1000,000 kHz
// Mode: Fast PWM top=0xFF
// OC2 output: Non-Inverted PWM
ASSR=0x00;
TCCR2=0x69;
TCNT2=0x00;
OCR2=0x00;


// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: On
// INT2 Mode: Rising Edge
GICR|=0x20;
MCUCR=0x00;
//MCUCSR=0x40;
GIFR=0x20;


// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// USART initialization
// USART disabled
UCSRB=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// ADC initialization
// ADC disabled
ADCSRA=0x00;

// SPI initialization
// SPI disabled
SPCR=0x00;

// TWI initialization
// TWI disabled
TWCR=0x00;

#asm("sei") //PIND.3==1 - INT1
while (1)
      {  
        if(PINB.2==1 && OCR2<0xFF) //открыли двери
        {  
        TCCR2=0x6D; 
        OCR2=OCR2+0x01;
        delay_ms(10);     
        }    
                  
        if(PINB.2==0 && OCR2>0x00) //закрыли дверь
        {   
        TCCR2=0x6D; 
        OCR2=OCR2-0x01;
        delay_ms(10);  

        }    
        
        if(PINB.2==0 && OCR2==0x00)   //лампа погасла
        { 
         TCCR2=0x00;  //отключение ШИМ
         PORTD.7=0; 
         
         //MCUCR=0x00; 
         MCUCSR=0x40;
         sleep_enable();  //////  ЗДЕСЬ ЛОЖИМСЯ СПАТЬ
         powerdown();     //////        
        }  
        
        if(PINB.2==1 && OCR2==0xFF) //лампа зажглась
        {  
        TCCR2=0x6D; 
        PORTD.7=1; 
        MCUCSR=0x00;
         sleep_enable();  
         powerdown();                

        }    

         
      }
}
Ответить

Вернуться в «AVR»