http://homes-smart.ru/index.php/oborudo ... zagruzchik
Потребление микроконтроллера упало до 3 мА, отключив периферию, вставил код просто из бесплатного конструктора Codevision AVR, код Arduino IDE понимает вообще без проблем
Код: Выделить всё
// Analog Comparator initialization
// Analog Comparator: Off
// The Analog Comparator's positive input is
// connected to the AIN0 pin
// The Analog Comparator's negative input is
// connected to the AIN1 pin
ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) | (0<<ACIS1) | (0<<ACIS0);
ADCSRB=(0<<ACME);
// Digital input buffer on AIN0: On
// Digital input buffer on AIN1: On
DIDR1=(0<<AIN0D) | (0<<AIN1D);
// ADC initialization
// ADC disabled
ADCSRA=(0<<ADEN) | (0<<ADSC) | (0<<ADATE) | (0<<ADIF) | (0<<ADIE) | (0<<ADPS2) | (0<<ADPS1) | (0<<ADPS0);http://forum.amperka.ru/threads/%D0%A1% ... 0%BC.2032/
Код: Выделить всё
/*
5 режимов энергосбережения:
SLEEP_MODE_IDLE
SLEEP_MODE_ADC
SLEEP_MODE_PWR_SAVE
SLEEP_MODE_STANDBY
SLEEP_MODE_PWR_DOWN
*/
#include <avr/sleep.h>
extern volatile unsigned long timer0_millis;
void setup()
{
pinMode(13, OUTPUT);
interrupts(); // не обязательно по умолчанию и так включено
}
void loop()
{
while(timer0_millis < 1000) {
set_sleep_mode(SLEEP_MODE_IDLE); // выбор режима
sleep_mode(); // уходим в спячку
}
timer0_millis = 0; // сброс счётчика
bitSet(PINB, 5); // переключение светодиода
}Далее, в примере видно что "спячка" не полная и самая энергозатратная из всех возможных. Какое-то прерывание будит микроконтроллер из режима IDLE (из остальных уже нет). Предполагаю что это один из таймеров, но возможно, сторожевой таймер WDT. Будит примерно каждые 8.2 миллисекунды. Что это за процесс? От системного таймера ожидал бы задержку в 1 мс. Если в это время идет передача через UART то просыпается чаще чем 8.2 мс, вероятно тоже прерывание от UART будит микроконтроллер. Если перед засыпанием ожидать очищение буфере передачи Serial.flush() тогда частота пробуждений возвращается к 8.2 мс.
В принципе большую часть времени микроконтроллер спит, но можно ли как-то варьировать время сна? И как войти в это самое странное прерывание, чтобы обрабатывать его по нормальному своей функцией. В Ардуино IDE документированы только прерывания от PIN 2, PIN 3 и всё. Хотя есть странные конструкции
http://arduino.ru/Tutorial/Arduino_Interrupts_part3
Код: Выделить всё
ISR(TIMER2_OVF_vect) {...}Так же пробовал будить микроконтроллер по сторожевому таймеру WDT. Не получилось. Так же ставил код из Codevision AVR, чтобы работало только прерывание от WDT, но кристалл сбрасывается, а не просыпается. Предполагаю что прерывание от WDT срабатывает, но в прошивке Ардуины нет кода на это прерывание и кристалл перезагружается. Или там корректная заглушка, а причина в другом? пример из этой статьи:
http://robotosha.ru/arduino/arduino-interrupts.html
Хотелось настроить более глубокий режим сна STANDBY, но не получилось. Сам микроконтроллер из этого режима не просыпается, только перезагрузкой по WDT.
Еще подумал, можно сделать RC цепочку и перед уходом в STANDBY заряжать конденсатор. Через некоторое время RC цепочка разряжается и МК пробуждается по прерыванию от пина. Но вырастет потребление, даже 1 мегаом резистор это 2 мка тока утечки.


