Включение энергосберегающих режимов микроконтроллера AVR на примере микроконтроллера ATtiny88 в среде программирования Arduino IDE.
В экспериментах будем использовать микроконтроллер ATtiny88 работающий от внутреннего генератора на частоте 8 MHz. Фьюзы микроконтроллера:
E:FF, H:DE, L:EE
К первой ножке микроконтроллера ATtiny88 мы подключили подтягивающий на плюс источника питания резистор 1 кОм и кнопку, замыкающую на минус источника питания. Источник питания 5 Вольт. К 17-й ножке микроконтроллера ATtiny88 мы подключили через резистор 2 кОм синий светодиод, катодом на минус источника питания.
Рис. 1. Принципиальная электрическая схема с микроконтроллером ATtiny88.
Выдержка из datasheet микроконтроллера ATtiny88:
ATtiny88 использует следующие режимы для экономии электроэнергии:
- Режим ожидания: останавливает процессор, позволяя таймеру/счетчику, АЦП, аналоговому компаратору, SPI, TWI и системе прерываний продолжать работать.
- Режим шумоподавления АЦП: минимизирует шум переключения во время преобразования АЦП за счет остановки процессора и всех модулей ввода-вывода, кроме АЦП.
- Режим отключения питания: регистры сохраняют свое содержимое, все функции микросхемы отключены до следующего прерывания или аппаратного сброса.
Напишем программу для микроконтроллера ATtiny88 с использованием прерываний.
const byte ledPin = 13;
const byte buttonPin = 3;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(3, INPUT);
attachInterrupt(digitalPinToInterrupt(buttonPin), blink, FALLING);
}
void loop() {
}
void blink(){
digitalWrite(ledPin, !digitalRead(ledPin));
}
Скетч 1. Программа для микроконтроллера ATtiny88 с использованием прерывания.
С загруженной в микроконтроллер ATtiny88 программой (скетч 1), кнопка включает и выключает светодиод. Потребление тока с включённым/выключенным светодиодом 5,1 мА / 4,0 мА.
Начнём с Ассемблера, функция asm("sleep") переводит микроконтроллер в энергосберегающий режим. Выбор режима (mode) энергосбережения задаётся в младших битах регистра ввода/вывода CMCR.
const byte ledPin = 13;
const byte buttonPin = 3;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(3, INPUT);
attachInterrupt(digitalPinToInterrupt(buttonPin), blink, FALLING);
//SMCR = 0b00000000; // 9,7мА/8,7мА Запрещение спящего режима
//SMCR = 0b00000001; // 6,4мА/5,3мА Idle Mode (Led ON / Led OFF)
//SMCR = 0b00000011; // 5,57мА/4,47мА ADC Noise Reduction Mode
SMCR = 0b00000101; // 1,38мА/0,22мА Power-down Mode
}
void loop() {
__asm__ volatile ("sleep\n\t"); // Спящий режим CPU
}
void blink() {
digitalWrite(ledPin, !digitalRead(ledPin));
}
Скетч 2. Программа для микроконтроллера ATtiny88 с функцией asm("sleep").
Попробуем отключать, в дополнение к CPU, другие модули микроконтроллера ATtiny88. За основу возьмём скетч 2.
Отключаем модуль детектора пониженного напряжения питания BOD (Brown-out Detector). BOD непрерывно контролирует напряжение питания микроконтроллера ATtiny88 и при этом сам потребляет электроэнергию. Разрешает отключение BOD при переходе микроконтроллера в режим энергосбережения установленный в 1 бит BODS в регистре ввода/вывода MCUCR. Бит BODS защищён от записи битом BODSE регистра MCUCR установленным в 0. Бит BODS автоматически очищается после трех тактов.
const byte ledPin = 13;
const byte buttonPin = 3;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(3, INPUT);
attachInterrupt(digitalPinToInterrupt(buttonPin), blink, FALLING);
SMCR = 0b00000101; // 1,327мА/0,224мА CPU Power-down Mode
}
void loop() {
register byte temp = MCUCR | 1 << BODS; // Управление отключением BOD (детектор пониженного напряжения питания)
MCUCR |= 1 << BODSE; // Разрешение записи в BODS
MCUCR = temp; // Разрешение спящего режима BOD
__asm__ volatile ("sleep\n\t"); // 1,316мА/0,213мА sleep CPU + BOD
}
void blink() {
digitalWrite(ledPin, !digitalRead(ledPin));
delay(50); // Защита от дребезга контактов
}
Скетч 3. Программа для микроконтроллера ATtiny88 с функцией sleep CPU + BOD.
const byte ledPin = 13;
const byte buttonPin = 3;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(3, INPUT);
attachInterrupt(digitalPinToInterrupt(buttonPin), blink, FALLING);
SMCR = 0b00000101; // 1,327мА/0,224мА CPU Power-down Mode
ADCSRA &= ~(1 << ADEN); // 1,140мА/0,024мА sleep CPU + ADC switch off
}
void loop() {
__asm__ volatile ("sleep\n\t");
}
void blink() {
digitalWrite(ledPin, !digitalRead(ledPin));
delay(50); // Защита от дребезга контактов
}
Скетч 4. Программа для микроконтроллера ATtiny88 с функцией ssleep CPU + ADC switch off.
const byte ledPin = 13;
const byte buttonPin = 3;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(3, INPUT);
attachInterrupt(digitalPinToInterrupt(buttonPin), blink, FALLING);
SMCR = 0b00000101; // 1,327мА/0,224мА CPU Power-down Mode
ADCSRA &= ~(1 << ADEN); // ADC switch off
}
void loop() {
register byte temp = MCUCR | 1 << BODS; // Управление отключением BOD (детектор пониженного напряжения питания)
MCUCR |= 1 << BODSE; // Разрешение записи в BODS
MCUCR = temp; // Разрешение спящего режима BOD
__asm__ volatile ("sleep\n\t"); // 1,114мА/0,000мА sleep CPU + BOD + ADC switch off
}
void blink() {
digitalWrite(ledPin, !digitalRead(ledPin));
delay(50); // Защита от дребезга контактов
}
Скетч 5. Программа для микроконтроллера ATtiny88 с функцией ssleep CPU + BOD + ADC switch off.
Полученные результаты занесём в таблицу.
№ | Ток микроконтроллера | Δ | Режим | Описание |
---|---|---|---|---|
1 | 8,7 mA | No Sleep | Запрещён спящий режим | |
2 | 5,3 mA | 8,7−5,3=3,4 | Idle Mode | Режим ожидания |
3 | 4,47 mA | 8,7−4,47=4,23 | ADC Noise Reduction Mode | Режим шумоподавления АЦП |
4 | 0,22 mA | 8,7−0,22=8,48 | Power-down Mode | Режим пониженного энергопотребления |
5 | 0,213 mA | 0,22−0,213=0,007 | Power-down Mode CPU + Sleep BOD | Режим пониженного энергопотребления с отключением BOD |
6 | 0,024 mA | 0,22−0,024=0,196 | Power-down Mode CPU + ADC switch off | Режим пониженного энергопотребления с отключением ADC |
7 | 0,000 mA | Power-down Mode CPU + Sleep BOD + ADC switch off | Режим пониженного энергопотребления с отключением BOD и ADC |
Табл. 1.