attiny85 сбрасывает себя вместо процедуры пробуждения
У меня есть digispark attiny85, и я использование SLEEP_MODE_PWR_DOWN для перехода в спящий режим и пробуждения с помощью внешнего прерывания на выводе 2. Я пытаюсь подсчитать количество полученных прерываний с помощью приведенного ниже кода.
Проблема заключается в том, что при каждом низком сигнале на выводе 2 attiny85 сам сбрасывает (перезагружает) вместо пробуждения процессора и продолжает работу с того места, где остановился. Я могу определить это, увидев, как светодиод мигает 3 раза (как в setup()) при каждом низком сигнале.
Есть ли ограничения на это оборудование? Как я могу только просыпаться из сна и не перезагружаться? Буду признателен, если вы приведёте мне пример.
#include <avr/interrupt.h>
#include <avr/sleep.h>
//изменено с http://playground.arduino.cc/Learning/arduinoSleepCode
int ledPin = 0; // светодиод подключен к цифровому выводу 0
int interruptPin = 1; // Светодиод, показывающий действие прерывания
int wakePin = 2; // активный НИЗКИЙ, кратковременно заземлите этот контакт, чтобы проснуться
unsigned int counter = 0;
void setup(){
pinMode(ledPin, OUTPUT); // устанавливаем цифровой вывод как выход
pinMode(interruptPin, OUTPUT); // устанавливаем цифровой вывод как выход
pinMode(wakePin, INPUT_PULLUP); // устанавливаем цифровой вывод в качестве входа
digitalWrite(wakePin, HIGH);
counter = 0;
//моргаем несколько раз, чтобы мы могли определить загрузку & петля
digitalWrite (interruptPin, HIGH); // устанавливаем цифровой вывод как выход
delay(250);
digitalWrite (interruptPin, LOW); // устанавливаем цифровой вывод как выход
delay(250);
digitalWrite (interruptPin, HIGH); // устанавливаем цифровой вывод как выход
delay(250);
digitalWrite (interruptPin, LOW); // устанавливаем цифровой вывод как выход
delay(250);
digitalWrite (interruptPin, HIGH); // устанавливаем цифровой вывод как выход
delay(250);
digitalWrite (interruptPin, LOW); // устанавливаем цифровой вывод как выход
delay(250);
}
void sleepNow(){
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // здесь устанавливается спящий режим
sleep_enable(); // включает бит сна в регистре mcucr, поэтому сон возможен
attachInterrupt(0, wakeUpNow, LOW); // используем прерывание 0 (контакт 2) и запускаем функцию WakeUpNow, когда контакт 2 становится НИЗКИМ
digitalWrite(interruptPin, LOW);
sleep_mode(); // здесь устройство фактически переведено в спящий режим!!
sleep_disable(); // первое, что делаем после пробуждения: отключаем сон...
detachInterrupt(0); // отключает вывод прерывания 3, поэтому код WakeUpNow не будет выполняться в обычное время работы.
delay(250); // ждем 2 секунды. чтобы люди могли заметить светодиод прерывания, показывающий, что прерывание обработано
digitalWrite (interruptPin, HIGH); // выключаем светодиод прерывания
}
void wakeUpNow(){ // здесь прерывание обрабатывается после пробуждения
//выполняем код после пробуждения перед возвратом к функции цикла()
// таймеры и код, использующий таймеры (serial.print и т. д.), здесь работать не будут.
digitalWrite(interruptPin, HIGH);
}
void loop(){
digitalWrite(interruptPin, HIGH);
//digitalWrite(ledPin, ВЫСОКИЙ); // включаем светодиод
counter++;
delay(5000); // ждем секунду
sleepNow(); // здесь вызывается функция сна
}
@ozkolonur, 👍2
Обсуждение1 ответ
Лучший ответ:
Я нашел это и могу подтвердить, что оно работает. на digispark attiny85.
void sleepTillChg() { // Сток 0,02 мА во время сна здесь
GIMSK |= _BV(PCIE); // Включить прерывания по смене контактов
PCMSK |= _BV(PCINT0); // Используем PB0 (был PB3) в качестве контакта прерывания
// Отключаем ненужную периферию
ADCSRA &= ~_BV(ADEN); // АЦП выключен
ACSR |= _BV(ACD); // Отключаем аналоговый компаратор
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // заменяет приведенный выше оператор
sleep_enable(); // Устанавливает бит включения режима сна в регистре MCUCR (SE BIT)
sei(); // Разрешаем прерывания
sleep_cpu(); // спать... Зззз
cli(); // Запретить прерывания
PCMSK &= ~_BV(PCINT0); // Выключаем PB0 (был PB3) как вывод прерывания
sleep_disable(); // Очистить бит SE
sei(); // Разрешаем прерывания
}
ISR(PCINT0_vect) {
// Это вызывается, когда происходит прерывание, но нам не нужно ничего в нем делать
}
кредиты должны идти https://www.instructables.com/id/3-Minute-Game-Timer/
- ATtiny85 со сном и последовательным портом
- Связь последовательного порта Digispark
- Как сгенерировать аппаратное прерывание в mpu6050 для пробуждения Arduino из режима SLEEP_MODE_PWR_DOWN?
- Библиотеки I2C для ATTiny85?
- Digispark ATtiny 85 - не распознается как HID устройство
- Клавиатура Digispark ATtiny85
- Как использовать attachInterrupt() в ATtiny85 с Arduino IDE?
- Digispark Atinny85 не распознан (проблема с загрузчиком)
Просто мысль: разве логика
detachInterrupt
не должна быть в методеwakeUpNow
?, @Filip FranikЯ так не думаю, Филипп, в большинстве примеров в Интернете, как вы можете видеть, WakeUpNow() использовать необязательно. большинство людей используют эту пустую функцию., @ozkolonur