ATtiny85 не выходит из сна
Мой ATtiny 85 не просыпается!
Назначение устройства состоит в том, чтобы контролировать геркон и выдавать выходной импульс 20 мс при каждом попеременном положительном переходе входа геркона. Устройство должно перейти в спящий режим после 30 секунд бездействия. Он должен просыпаться при срабатывании геркона (подъеме или падении края).
/*
ATMEL ATTINY 85
+-\/-+
PB5 1| |8 Vcc
PB3 2| |7 PB2 (INT0) reed switch input (1 MΩ ext. pull-up)
PB4 3| |6 PB1 output
GND 4| |5 PB0
+----+
*/
#include <avr/sleep.h>
#include <avr/power.h>
#include <elapsedMillis.h>
const int hallPin = 2; // Геркон в данном случае.
const int magnetPin = 1; // Вывод.
const long debouncing_time = 15; // Время снятия в миллисекундах.
volatile int hallState = 0; // переменная для хранения счетчика холла
volatile bool hallMem = 0; // Одноразовая память.
volatile unsigned long last_micros;
elapsedMillis timer;
void setup(){
pinMode(magnetPin, OUTPUT);
pinMode(hallPin, INPUT);
// Присоединить прерывание к вектору ISR. НУЖНО ЛИ МНЕ ЭТО?
// attachInterrupt(0, pin_ISR, RISING); //по умолчанию вывод interupt всегда равен 0 на ATtiny85 (физический вывод 7).
timer = 0; //Сброс таймера
}
void loop(){
if(digitalRead(hallPin) && !hallMem){
hallMem = true; // Одноразовая память.
hallState++;
delay(debouncing_time); // Keep it simple.
timer = 0;
}
if(!digitalRead(hallPin)){
hallMem = false; // Разрешить повторный триггер.
}
if(hallState > 1) {
digitalWrite(magnetPin, HIGH); // Отправить импульс 20 мс на катушку активации датчика.
delay(20);
digitalWrite(magnetPin, LOW);
hallState = 0; // Сброс триггера.
}
if(timer >= 30000) { // Нет активности.
system_sleep();
}
}
// От http://interface.khm.de/index.php/lab/experiments/sleep_watchdog_battery/
void system_sleep() {
GIMSK |= _BV(PCIE); // Включить прерывания смены выводов
PCMSK |= _BV(INT0); // Использовать INT0 (PB2) в качестве вывода прерывания
ADCSRA &= ~_BV(ADEN); // ADC off
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // заменяет вышеприведенный оператор
sleep_enable(); // Устанавливает бит включения сна в регистре MCUCR (БИТ SE).
sei(); // Включить прерывания
sleep_cpu(); // сон
cli(); // Отключить прерывания
// PCMSK &= ~_BV (INT0); // Отключить INT0 (PB2) как вывод прерывания
sleep_disable(); // Clear SE bit
ADCSRA |= _BV(ADEN); // ADC on
sei(); // Включить прерывания
timer = 0; // Сброс таймера сна при пробуждении.
}
ISR(PCINT0_vect) {
}
Может ли кто-нибудь заметить мою ошибку, которая мешает пробуждению?
Что делает инструкция включения АЦП? Нужно ли мне это?
Большое спасибо.
@Transistor, 👍2
Обсуждение1 ответ
Лучший ответ:
Я считаю, что ваша проблема заключается вот в чем:
PCMSK |= _BV(INT0); // Использовать INT0 (PB2) в качестве вывода прерывания
Похоже, вы перепутали два вида прерываний:
INT0 (внешнее прерывание), которое работает только на выводе INT0 (т. Е. PB2) и может воспринимать низкоуровневый, восходящий край, падающий край или любые изменения.
PCINT0 (прерывание смены pin), которое работает на любом выводе ввода-вывода, но может воспринимать только “любое изменение”.
Поскольку вы спите в режиме PWR_DOWN, прерывание смены pin является подходящим выбором. Вся ваша программа согласуется с этим выбором, но для строки выше.
Макрос INT0
имеет значение 6. Он представляет собой бит 6 GIMSK
, который
используется для включения прерывания INT0. Не то, что ты хочешь. Бит 6
PCMSK
зарезервирован, поэтому вы не должны прикасаться к нему. Если вы хотите
, чтобы прерывание смены pin воспринимало изменения в pin PB2 (он же PCINT2), вам
необходимо:
PCMSK |= _BV(PCINT2); // изменения смысла в PCINT2 = PB2
Спасибо за ясное объяснение. Теперь это работает. Могу ли я опустить строки "ADCSRA", поскольку я не использую никаких аналоговых функций?, @Transistor
@Transistor: Действительно, можете., @Edgar Bonet
- attiny85 сбрасывает себя вместо процедуры пробуждения
- Attiny85 простая проблема с аналоговым и цифровым выходом
- ATtiny85 со сном и последовательным портом
- ATtiny85 дает многократное пробуждение от простоя, если INT0 удерживается на низком уровне
- Связь последовательного порта Digispark
- Как сгенерировать аппаратное прерывание в mpu6050 для пробуждения Arduino из режима SLEEP_MODE_PWR_DOWN?
- Как перевести ATtiny/ATmega в режим глубокого сна (чтобы годами работать от батарей), но при этом обнаруживать нажатие кнопки?
- Библиотеки I2C для ATTiny85?
Попробуйте заменить PCMSK |= _BV(INT0); на PCMSK |= _BV(PCINT2).;, @gbg
@gbg, это, кажется, что-то делает, спасибо. Я собираюсь добавить "Пробужденный", чтобы я мог контролировать состояние сна. В Ирландии пора спать., @Transistor