-
Notifications
You must be signed in to change notification settings - Fork 0
/
main-sleep.c
64 lines (52 loc) · 3.88 KB
/
main-sleep.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/**
* Пример для Arduino Nano.
*
* Микроконтроллер после включения перейдет в спящий режим для экономия энергии.
* При нажатии кнопки (соединении INT0/PD2/D2 с GNG) микроконтроллер выйдет из спящего режима и помигает светодиодом.
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <util/delay.h>
#define LED_PIN PB5 // PB5(D13)
#define INTERRUPT_PIN PD2 // INT0/PD2(D2)
int main(void) {
DDRB |= (1<<LED_PIN); // Настройка PB5 на выход
// Настройка PD2 на вход не требуется (значение по умолчанию), регистр DDRD
PORTD |= (1<<INTERRUPT_PIN); // Подтягиваем PD2 к high
// EICRA - External Interrupt Control Register A
// Прерывание на INT0/PD2 будет сгенерировано при низком уровне (low)
// ISC01=0, ISC00=0
// EIMSK - External Interrupt Mask Register
EIMSK |= (1<<INT0); // Включить внешнее прерывание на INT0
// BOD - это аббревиатура от Brown-Out Detection.
// Это функция, которая защищает микроконтроллер от повреждения из-за пониженного напряжения питания.
// Если напряжение питания упадет ниже определенного порогового значения, BOD сработает и перезагрузит микроконтроллер.
// Включен или выключен по умолчанию BOD зависит от установленных фьюзов в микроконтроллере.
sleep_bod_disable();
while (1)
{
sei(); // Разрешить глобальные прерывания
// Режим Power-down Mode - это самый экономичный режим работы микроконтроллера ATmega328P.
// В этом режиме все внутренние блоки микроконтроллера, за исключением таймера реального времени (RTC), отключаются.
// В результате потребление энергии микроконтроллера составляет менее 1 мкА.
// Микроконтроллер выйдет из режима Power-down Mode, когда произойдет событие, которое сгенерирует прерывание RTC.
// Например, это может быть срабатывание таймера RTC, приход внешнего сигнала на вход INT0 или INT1,
// изменение состояния шины SPI или I2C и т. д.
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_mode();
// Функция sleep_mode() аналогична вызову нескольких функций:
// - sleep_enable(); // разрешает перевод микроконтроллера в режим сна
// - sleep_cpu(); // переводит микроконтроллер в режим сна
// - sleep_disable(); // запрещает перевод микроконтроллера в режим сна
// Попадем в это место при возникновении прерывания на INT0/PD2
cli(); // Запретить глобальные прерывания
for (int i = 0; i < 3; i++)
{
PORTB |= (1<<LED_PIN); // Включить светодиод на PB5
_delay_ms(1000);
PORTB &= ~(1<<LED_PIN); // Выключить светодиод на PB5
_delay_ms(1000);
}
}
}