Skip to content

Commit 2f89b00

Browse files
committed
upd
1 parent 4e6a009 commit 2f89b00

File tree

9 files changed

+249
-0
lines changed

9 files changed

+249
-0
lines changed

1releases/GyverWDT.zip

6.89 KB
Binary file not shown.

GyverWDT/GyverWDT.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#include <GyverWDT.h>
2+
3+
4+
/* указатель на функцию прерывания */
5+
void (*isr_wdt)();
6+
7+
/* непосредственно прерывание ватчдога */
8+
ISR(WDT_vect) {
9+
(*isr_wdt)();
10+
}
11+
12+
/* сброс счетчика watchdog в 0 */
13+
void watchdog_reset(void) {
14+
asm volatile("wdr"); // ассемблерная вставка "watchdog reset"
15+
}
16+
17+
/* Полное отключение watchdog'a */
18+
void watchdog_disable(void) {
19+
WDTCSR |= (1 << WDCE); // разрешение на вмешательство
20+
WDTCSR = 0; // обнуление регистра wdt
21+
}
22+
23+
24+
/* Вариант функции для работы ватчдога с прерываниями при таймауте */
25+
void watchdog_enable(uint8_t mode , uint8_t prescaler , void (*isr)()) {
26+
isr_wdt = *isr; //указатель на функцию
27+
switch (mode) {
28+
case 0: // interrupt
29+
if (prescaler > 7) { // если больше 7
30+
prescaler -= 8; // отняли старший бит
31+
WDTCSR |= (1 << WDCE) | (1 << WDE); // разрешили вмешательство
32+
WDTCSR = 0b01100000 | prescaler; // вкл режим int , установили старший бит и задвинули прескалер
33+
}
34+
else { // если меньше 7
35+
WDTCSR |= (1 << WDCE) | (1 << WDE); // разрешили вмешательство
36+
WDTCSR = 0b01000000 | prescaler; // вкл режим int , просто задвинули прескалер
37+
}
38+
break;
39+
case 1: // interrupt+reset
40+
if (prescaler > 7) { // если больше 7
41+
prescaler -= 8; // отняли старший бит
42+
WDTCSR |= (1 << WDCE) | (1 << WDE); // разрешили вмешательство
43+
WDTCSR = 0b01101000 | prescaler; // вкл режим int+rst , установили старший бит и задвинули прескалер
44+
}
45+
else { // если меньше 7
46+
WDTCSR |= (1 << WDCE) | (1 << WDE); // разрешили вмешательство
47+
WDTCSR = 0b01001000 | prescaler; // вкл режим int+rst , просто задвинули прескалер
48+
}
49+
break;
50+
}
51+
}
52+
53+
/* вариант для работы без прерываний (только сброс) */
54+
void watchdog_enable(uint8_t prescaler) {
55+
if (prescaler > 7) { // если больше 7
56+
prescaler -= 8; // отняли старший бит
57+
WDTCSR |= (1 << WDCE) | (1 << WDE); // разрешили вмешательство
58+
WDTCSR = 0b00101000 | prescaler; // вкл режим rst , установили старший бит и задвинули прескалер
59+
}
60+
else { // если меньше 7
61+
WDTCSR |= (1 << WDCE) | (1 << WDE); // разрешили вмешательство
62+
WDTCSR = 0b00001000 | prescaler; // вкл режим rst , просто задвинули прескалер
63+
}
64+
}

GyverWDT/GyverWDT.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#ifndef GyverWDT_h
2+
#define GyverWDT_h
3+
#include <Arduino.h>
4+
5+
/* библиотека для расширенной и удобной работы с watchdog.
6+
* created for AlexGyver by Egor 'Nich1con' Zaharov 10.08.2019
7+
* MCU supported : ATmega328/168 , ATmega32u4/16u4 , ATmega2560/1280 , ATtiny85/45 , ATtiny88/48 ...
8+
*/
9+
10+
/* О прескалерах и режимах работы watchdog таймера:
11+
* 1) Осцилятор сторжевого таймера не предполагает высокой точности и имеет отклонение при производстве около 10%
12+
* 2) Приблизительное соотношение делителей и таймаутов:
13+
* [/2 ~ 16ms /4 ~ 32ms /8 ~ 64ms /16 ~ 0.125s /32 ~ 0.25s /64 ~ 0.5s /128 ~ 1s /256 ~ 2s /512 ~ 4s /1024 ~ 8s ]
14+
* 3) Описание режимов работы сторжевого таймера:
15+
* - INTERRUPT_MODE => Таймаут инициирует вызов прерывания , работает на любом bootloader'e
16+
* - RESET_MODE => Таймаут инициирует сброс микроконтроллера , работает НЕ со всеми загрузчиками , для проверки воспользуйтесь примером "watchdog_support_test"
17+
* - INTERRUPT_RESET_MODE => Первый таймаут инициирует прерывание,и автоматически переводит watchdog в режим "RESET_MODE",
18+
* соотв. последующий таймаут иницирует сброс. Если в вызванном прерывании удалось побороть причину зависания,
19+
* вы можете перенастроить сторжевой таймер конструкцией [watchdog_disable() + watchdog_enable()],чтобы следующий таймаут не инициировал сброс.
20+
*/
21+
22+
/* варианты предделителей для watchdog'a */
23+
#define WDT_PRESCALER_2 0
24+
#define WDT_PRESCALER_4 1
25+
#define WDT_PRESCALER_8 2
26+
#define WDT_PRESCALER_16 3
27+
#define WDT_PRESCALER_32 4
28+
#define WDT_PRESCALER_64 5
29+
#define WDT_PRESCALER_128 6
30+
#define WDT_PRESCALER_256 7
31+
#define WDT_PRESCALER_512 8
32+
#define WDT_PRESCALER_1024 9
33+
34+
/* Режимы работы watchdog'a */
35+
#define INTERRUPT_MODE 0 // вызывает прерывание при таймауте
36+
#define INTERRUPT_RESET_MODE 1 // вызывает прерывание при таймауте, следующий таймаут инициирует сброс
37+
38+
/* указатель на функцию прерывания */
39+
extern void (*isr_wdt)();
40+
41+
/* Все функции библиотеки */
42+
void watchdog_reset(void); // сбросить watchdog
43+
void watchdog_disable(void); // полностью выключить watchdog
44+
void watchdog_enable(uint8_t mode , uint8_t prescaler, void (*isr)()); // Включить и настроить ватчдог (с прерыванием)
45+
void watchdog_enable(uint8_t prescaler); // Включить и настроить ватчдог (только reset)
46+
47+
#endif
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#include <GyverWDT.h>
2+
/* пример работы ватчдога как источника переодических прерываний */
3+
4+
volatile long oldTime;
5+
void setup() {
6+
Serial.begin(9600);
7+
Serial.println("hello!");
8+
watchdog_enable(INTERRUPT_MODE, WDT_PRESCALER_128, func); // подробнее о делителях и режимах в GyverWDT.h
9+
oldTime = millis();
10+
delay(10000); // работаем 10 секунд
11+
watchdog_disable(); // выключаем ватчдог
12+
//while(1) watchdog_reset(); // или можем сбрасывать его и не допускать таймаута и соотв. прерываний
13+
}
14+
15+
void func() {
16+
Serial.println(millis() - oldTime);
17+
oldTime = millis();
18+
}
19+
20+
void loop() {}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include <GyverWDT.h>
2+
/* пример работы ватчдога как автоматического reset при зависании */
3+
4+
void setup() {
5+
Serial.begin(9600);
6+
Serial.println("hello!"); // сигнализирует о старте программы
7+
/* в режиме reset фунция имеет только один аргумент */
8+
watchdog_enable(WDT_PRESCALER_512); // подробнее о режимах и прескалерах в файле GyverWDT.h
9+
Serial.println("watchdog enabled"); // сигнализирует о включении watchdog
10+
while (1); // источник зависания
11+
/* для подтверждения правильной работы программы, вызывайте watchdog_reset() не реже заданного таймаута */
12+
Serial.println("data:"); // это сообщение мы никогда не увидим , из-за зависания выше
13+
/* по достижению таймаута мы увидим , что программа перезапустилась */
14+
}
15+
16+
void loop() {
17+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include <GyverWDT.h>
2+
/* пример работы ватчдога в комбинированном режиме */
3+
4+
void setup() {
5+
Serial.begin(9600);
6+
Serial.println("hello!"); // сигнализирует о старте программы
7+
watchdog_enable(INTERRUPT_RESET_MODE, WDT_PRESCALER_512, alert); // подробнее о режимах и прескалерах в файле GyverWDT.h
8+
Serial.println("watchdog enabled"); // сигнализирует о включении watchdog
9+
while (1); // источник зависания
10+
Serial.println("data:"); // это сообщение мы никогда не увидим , из-за зависания выше
11+
/* первый таймаут сигнализирует предупреждением , последующий - инициирует сброс */
12+
}
13+
14+
void alert() {
15+
Serial.println("attention!");
16+
// в этом прерывании вы можете попытаться исправить причину зависания
17+
// если нет - следующий таймаут инициирует сброс
18+
}
19+
20+
void loop() {
21+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#include <GyverWDT.h>
2+
/* Скетч , тестирующий поддержку автоматического watchdog reset на вашем bootloader'е */
3+
4+
/* !!! Если после запуска скетча программа перезапускается каждые ~8с - ваш bootloader поддерживает watchdog reset !!!
5+
!!! Если после таймаута программа не перезагружается , а светодиод на плате начинает быстро мигать - watchdog reset не поддерживается !!!
6+
Если ваш bootloader не поддерживаем watchdog reset , вы можете использовать watchdog для генерации прерываний, см. GyverWDT.h
7+
*/
8+
9+
void setup() {
10+
Serial.begin(9600);
11+
Serial.println("wait 10 sec");
12+
delay(10000); // задержка , чтобы иметь возможность перепрошить контроллер в случае bootloop
13+
watchdog_enable(WDT_PRESCALER_1024); // таймаут ~ 8с
14+
Serial.println("watchdog enabled");
15+
while (1) { // бесконечный цикл, в котором нет watchdog_reset();
16+
if (!(millis() % 1000)) { // каждую секунду
17+
delay(10);
18+
Serial.println((int)((millis() / 1000) - 10)); // выводим прошедшее время в секундах
19+
}
20+
}
21+
}
22+
23+
void loop() {
24+
25+
}

GyverWDT/keywords.txt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#######################################
2+
# Syntax Coloring Map For GyverWDT
3+
#######################################
4+
5+
#######################################
6+
# Datatypes (KEYWORD1)
7+
#######################################
8+
9+
10+
#######################################
11+
# Methods and Functions (KEYWORD2)
12+
#######################################
13+
GyverWDT KEYWORD2
14+
watchdog_reset KEYWORD2
15+
watchdog_disable KEYWORD2
16+
watchdog_enable KEYWORD2
17+
#######################################
18+
# Constants (LITERAL1)
19+
#######################################
20+
WDT_PRESCALER_2 LITERAL1
21+
WDT_PRESCALER_4 LITERAL1
22+
WDT_PRESCALER_8 LITERAL1
23+
WDT_PRESCALER_16 LITERAL1
24+
WDT_PRESCALER_32 LITERAL1
25+
WDT_PRESCALER_64 LITERAL1
26+
WDT_PRESCALER_128 LITERAL1
27+
WDT_PRESCALER_256 LITERAL1
28+
WDT_PRESCALER_512 LITERAL1
29+
WDT_PRESCALER_1024 LITERAL1
30+
INTERRUPT_MODE LITERAL1
31+
INTERRUPT_RESET_MODE LITERAL1

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
* [directADC](#directADC)
1212
* [directTimers](#directTimers)
1313
* [GyverPWM](#GyverPWM)
14+
* [GyverWDT](#GyverWDT)
1415
* [ServoSmooth](#ServoSmooth)
1516
* [GyverFilters](#GyverFilters)
1617
* [GyverTimer](#GyverTimer)
@@ -452,6 +453,29 @@ void PWM_TMR1_10BIT(); // Установить таймер 1 (ШИМ на D9 и
452453

453454
---
454455

456+
<a id="GyverWDT"></a>
457+
### GyverWDT v1.0 [СКАЧАТЬ](https://github.com/AlexGyver/GyverLibs/releases/download/GyverWDT/GyverWDT.zip)
458+
Библиотека для расширенной и удобной работы с watchdog
459+
- Перезагрузка по прерыванию
460+
- Вызов обычных прерываний
461+
- Настройка периода работы
462+
#### Методы и функции библиотеки
463+
<details>
464+
<summary>РАЗВЕРНУТЬ</summary>
465+
<p>
466+
Смотри примеры в папке examples!
467+
468+
```C
469+
void watchdog_reset(void); // сбросить watchdog
470+
void watchdog_disable(void); // полностью выключить watchdog
471+
void watchdog_enable(uint8_t mode , uint8_t prescaler, void (*isr)()); // Включить и настроить ватчдог (с прерыванием)
472+
void watchdog_enable(uint8_t prescaler); // Включить и настроить ватчдог (только reset)
473+
```
474+
</p>
475+
</details>
476+
477+
---
478+
455479
<a id="ServoSmooth"></a>
456480
### ServoSmooth v1.3 [СКАЧАТЬ](https://github.com/AlexGyver/GyverLibs/releases/download/ServoSmooth/ServoSmooth.zip)
457481
Библиотека для плавного управления сервоприводами

0 commit comments

Comments
 (0)