├── .gitattributes
├── .github
└── workflows
│ └── tg-send.yml
├── LICENSE
├── README.md
├── README_EN.md
├── docs
└── timers.xlsx
├── examples
├── all_functions
│ └── all_functions.ino
├── double_interrupts
│ └── double_interrupts.ino
├── encoder_mode
│ └── encoder_mode.ino
├── meandr_2tact
│ └── meandr_2tact.ino
├── meandr_test
│ └── meandr_test.ino
├── simple
│ └── simple.ino
└── withoutInterrupts
│ └── withoutInterrupts.ino
├── keywords.txt
├── library.properties
└── src
├── GyverTimers.cpp
└── GyverTimers.h
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.github/workflows/tg-send.yml:
--------------------------------------------------------------------------------
1 |
2 | name: Telegram Message
3 | on:
4 | release:
5 | types: [published]
6 | jobs:
7 | build:
8 | name: Send Message
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: send telegram message on push
12 | uses: appleboy/telegram-action@master
13 | with:
14 | to: ${{ secrets.TELEGRAM_TO }}
15 | token: ${{ secrets.TELEGRAM_TOKEN }}
16 | disable_web_page_preview: true
17 | message: |
18 | ${{ github.event.repository.name }} v${{ github.event.release.tag_name }}
19 | ${{ github.event.release.body }}
20 | https://github.com/${{ github.repository }}
21 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 AlexGyver
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://github.com/GyverLibs/GyverTimers/releases/latest/download/GyverTimers.zip)
2 | [](https://registry.platformio.org/libraries/gyverlibs/GyverTimers)
3 | [](https://alexgyver.ru/)
4 | [](https://alexgyver.ru/support_alex/)
5 | [](https://github-com.translate.goog/GyverLibs/GyverTimers?_x_tr_sl=ru&_x_tr_tl=en)
6 |
7 | [](https://t.me/GyverLibs)
8 |
9 | # GyverTimers
10 | Настройка и контроль прерываний по аппаратным таймерам ATmega328p, ATmega2560
11 | - Поддерживаются все три таймера на ATmega328 и шесть таймеров на ATmega2560;
12 | - Настройка периода (мкс) и частоты (Гц) прерываний:
13 | - 8 бит таймеры: 61 Гц - 1 МГц (16 384 мкс.. 1 мкс);
14 | - 16 бит таймеры: 0.24 Гц - 1 МГц (4 200 000 мкс.. 1 мкс);
15 | - Автоматическая корректировка настройки периода от частоты тактирования (F_CPU);
16 | - Функция возвращает точный установившийся период/частоту для отладки (частота ограничена разрешением таймера);
17 | - Поддержка многоканального режима работы: один таймер вызывает 2 (ATmega328) или
18 | 3 (ATmega2560, таймеры 1, 3, 4, 5) прерывания с настраиваемым сдвигом по фазе 0-360 градусов;
19 | - Настраиваемое действие аппаратного вывода таймера по прерыванию: высокий сигнал, низкий сигнал, переключение.
20 | Позволяет генерировать меандр (одно- и двухтактный);
21 | - Контроль работы таймера: старт/стоп/пауза/продолжить/инициализация;
22 |
23 | ### Совместимость
24 | ATmega328p, ATmega2560
25 |
26 | ### Документация
27 | К библиотеке есть [расширенная документация](https://alexgyver.ru/GyverTimers/)
28 |
29 | ## Содержание
30 | - [Установка](#install)
31 | - [Инициализация](#init)
32 | - [Использование](#usage)
33 | - [Пример](#example)
34 | - [Версии](#versions)
35 | - [Баги и обратная связь](#feedback)
36 |
37 |
38 | ## Установка
39 | - Библиотеку можно найти по названию **GyverTimers** и установить через менеджер библиотек в:
40 | - Arduino IDE
41 | - Arduino IDE v2
42 | - PlatformIO
43 | - [Скачать библиотеку](https://github.com/GyverLibs/GyverTimers/archive/refs/heads/main.zip) .zip архивом для ручной установки:
44 | - Распаковать и положить в *C:\Program Files (x86)\Arduino\libraries* (Windows x64)
45 | - Распаковать и положить в *C:\Program Files\Arduino\libraries* (Windows x32)
46 | - Распаковать и положить в *Документы/Arduino/libraries/*
47 | - (Arduino IDE) автоматическая установка из .zip: *Скетч/Подключить библиотеку/Добавить .ZIP библиотеку…* и указать скачанный архив
48 | - Читай более подробную инструкцию по установке библиотек [здесь](https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA)
49 | ### Обновление
50 | - Рекомендую всегда обновлять библиотеку: в новых версиях исправляются ошибки и баги, а также проводится оптимизация и добавляются новые фичи
51 | - Через менеджер библиотек IDE: найти библиотеку как при установке и нажать "Обновить"
52 | - Вручную: **удалить папку со старой версией**, а затем положить на её место новую. "Замену" делать нельзя: иногда в новых версиях удаляются файлы, которые останутся при замене и могут привести к ошибкам!
53 |
54 |
55 |
56 | ## Инициализация
57 | Нет
58 |
59 |
60 | ## Использование
61 | ```cpp
62 | Методы для Timer0, Timer1, Timer2...
63 | uint32_t setPeriod(период); // установка периода в микросекундах и запуск таймера. Возвращает реальный период (точность ограничена разрешением таймера).
64 | uint32_t setFrequency(частота); // установка частоты в Герцах и запуск таймера. Возвращает реальную частоту (точность ограничена разрешением таймера).
65 | float setFrequencyFloat(частота float); // установка частоты в Герцах и запуск таймера, разрешены десятичные дроби. Возвращает реальную частоту (точность ограничена разрешением таймера).
66 | void enableISR(источник); // включить прерывания, канал прерываний CHANNEL_A или CHANNEL_B (+ CHANNEL_C у Mega2560)
67 | void disableISR(источник); // выключить прерывания, канал CHANNEL_A или CHANNEL_B. Счёт таймера не останавливается (без указания параметров будет выключен канал А).
68 | void pause(); // приостановить счёт таймера, не сбрасывая счётчик
69 | void resume(); // продолжить счёт после паузы
70 | void stop(); // остановить счёт и сбросить счётчик
71 | void restart(); // перезапустить таймер (сбросить счётчик)
72 | void setDefault(); // установить параметры таймера по умолчанию ("Ардуино-умолчания")
73 | void outputEnable(канал, режим); // канал: включить выход таймера CHANNEL_A или CHANNEL_B (+ CHANNEL_C у Mega2560). Режим: TOGGLE_PIN, CLEAR_PIN, SET_PIN (переключить/выключить/включить пин по прерыванию)
74 | void outputDisable(канал); // отключить выход таймера CHANNEL_A или CHANNEL_B (+ CHANNEL_C у Mega2560, см. такблицу таймеров)
75 | void outputState(канал, состояние); // сменить состояние канала: HIGH / LOW
76 | void phaseShift(источник, фаза); // сдвинуть фазу канала на 0-360 градусов (у 8 бит таймеров двигается только канал B)
77 | bool ready(uint8_t channel); // возвращает true, если произошло прерывание на указанном канале
78 | bool ready(); // возвращает true, если произошло прерывание на канале A
79 |
80 | /*
81 | Библиотека даёт прямой доступ к прерыванию без “Ардуиновских” attachInterrupt, что позволяет
82 | сократить время вызова функции-обработчика прерывания. Прерывание с настроенной частотой
83 | будет обрабатываться в блоке вида ISR(канал) {}, пример:
84 | */
85 | ISR(TIMER1_A) {
86 | // ваш код
87 | }
88 |
89 | ISR(TIMER1_B) {
90 | // ваш код
91 | }
92 |
93 | ISR(TIMER2_B) {
94 | // ваш код
95 | }
96 |
97 | ISR(TIMER0_A) {
98 | // ваш код
99 | }
100 |
101 | /*
102 | -------------------------------- Arduino NANO 16 МГц (ATmega328) ------------------------------------
103 | Таймер | Разрядность | Частоты | Периоды | Выходы | Пин Arduino | Пин МК|
104 | --------|---------------|-------------------|-------------------|-----------|---------------|-------|
105 | Timer0 | 8 бит | 61 Гц - 1 МГц | 16 384.. 1 мкс | CHANNEL_A | D6 | PD6 |
106 | | | | | CHANNEL_B | D5 | PD5 |
107 | --------|---------------|-------------------|-------------------|-----------|---------------|-------|
108 | Timer1 | 16 бит | 0.24 Гц - 1 МГц | 4 200 000.. 1 мкс | CHANNEL_A | D9 | PB1 |
109 | | | | | CHANNEL_B | D10 | PB2 |
110 | --------|---------------|-------------------|-------------------|-----------|---------------|-------|
111 | Timer2 | 8 бит | 61 Гц - 1 МГц | 16 384.. 1 мкс | CHANNEL_A | D11 | PB3 |
112 | | | | | CHANNEL_B | D3 | PD3 |
113 | ----------------------------------------------------------------------------------------------------
114 |
115 | ------------------------------ Arduino MEGA 16 МГц (ATmega2560) -------------------------------------
116 | Таймер | Разрядность | Частоты | Периоды | Выходы | Пин Arduino | Пин МК|
117 | --------|---------------|-------------------|-------------------|-----------|---------------|-------|
118 | Timer0 | 8 бит | 61 Гц - 1 МГц | 16 384.. 1 мкс | CHANNEL_A | 13 | PB7 |
119 | | | | | CHANNEL_B | 4 | PG5 |
120 | --------|---------------|-------------------|-------------------|-----------|---------------|-------|
121 | Timer1 | 16 бит | 0.24 Гц - 1 МГц | 4 200 000.. 1 мкс | CHANNEL_A | 11 | PB5 |
122 | | | | | CHANNEL_B | 12 | PB6 |
123 | | | | | CHANNEL_C | 13 | PB7 |
124 | --------|---------------|-------------------|-------------------|-----------|---------------|-------|
125 | Timer2 | 8 бит | 61 Гц - 1 МГц | 16 384.. 1 мкс | CHANNEL_A | 10 | PB4 |
126 | | | | | CHANNEL_B | 9 | PH6 |
127 | --------|---------------|-------------------|-------------------|-----------|---------------|-------|
128 | Timer3 | 16 бит | 0.24 Гц - 1 МГц | 4 200 000.. 1 мкс | CHANNEL_A | 5 | PE3 |
129 | | | | | CHANNEL_B | 2 | PE4 |
130 | | | | | CHANNEL_C | 3 | PE5 |
131 | --------|---------------|-------------------|-------------------|-----------|---------------|-------|
132 | Timer4 | 16 бит | 0.24 Гц - 1 МГц | 4 200 000.. 1 мкс | CHANNEL_A | 6 | PH3 |
133 | | | | | CHANNEL_B | 7 | PH4 |
134 | | | | | CHANNEL_C | 8 | PH5 |
135 | --------|---------------|-------------------|-------------------|-----------|---------------|-------|
136 | Timer5 | 16 бит | 0.24 Гц - 1 МГц | 4 200 000.. 1 мкс | CHANNEL_A | 46 | PL3 |
137 | | | | | CHANNEL_B | 45 | PL4 |
138 | | | | | CHANNEL_C | 44 | PL5 |
139 | ----------------------------------------------------------------------------------------------------
140 | */
141 | ```
142 |
143 |
144 | ## Пример
145 | Остальные примеры смотри в **examples**!
146 | ```cpp
147 | // Демонстрация всех функций библиотеки
148 |
149 | #include
150 |
151 | void setup() {
152 | // Перенастроить таймер и задать ему период или частоту
153 | // Все функции возвращают реальный период / частоту, которые могут отличаться от введенных
154 | Timer2.setPeriod(1000); // Задать конкретный период 1000 мкс (~ 1000 гц), вернет реальный период в мкс
155 | Timer0.setFrequency(250); // Задать частоту прерываний таймера в Гц, вернет реальную частоту в герцах
156 | Timer1.setFrequencyFloat(50.20); // Задать частоту более точно, в дробных числах, актуально для низких частот и таймера 1
157 | // С этого момента таймер уже перенастроен и гоняет с выьранной частотой / периодом
158 |
159 | // Подключить прерывание таймера, с этого момента прерывания начнут вызываться
160 | Timer0.enableISR(); // Подключить стандартное прерывание, канал А, без сдига фаз
161 | Timer2.enableISR(CHANNEL_B); // Подключить прерывание таймера 2, канал B
162 | Timer1.enableISR(CHANNEL_A); // Подключить прерывание канала А
163 | Timer1.enableISR(CHANNEL_B); // Подключить второе прерывание таймера 1
164 | // Прерывание уже начнет вызываться
165 |
166 | // Если вдруг прерывание нужно отключить, не останавливая таймер
167 | Timer1.disableISR(CHANNEL_B);
168 | // С этого момента прерывание B больше не будет вызываться
169 |
170 | // Если нужно приостановить таймер ПОЛНОСТЬЮ, аппаратно
171 | Timer2.pause();
172 | // С этого момента таймер стоит на месте, содержимое счетчика остается нетронутым
173 |
174 | // Теперь таймер можно вернуть в строй
175 | Timer2.resume();
176 | // Таймер продолжил считать с того же места
177 |
178 | // Если нужно полностью остановить таймер и сбросить содержимое счетчика
179 | Timer1.stop();
180 | // Таймер стоит, счетчик сброшен
181 |
182 | // Возвращаем таймер в строй
183 | Timer1.restart();
184 | // Таймер перезапущен, начал считать с начала
185 |
186 | // Если нужно вернуть стандартные Arduino - настройки таймера
187 | Timer0.setDefault();
188 | // Теперь таймер работает в станлартном режиме
189 | }
190 |
191 | // векторы прерываний
192 | ISR(TIMER1_A) {
193 | }
194 |
195 | ISR(TIMER1_B) {
196 | }
197 |
198 | ISR(TIMER2_B) {
199 | }
200 |
201 | ISR(TIMER0_A) {
202 | }
203 |
204 | void loop() {
205 |
206 | }
207 | ```
208 |
209 |
210 | ## Версии
211 | - v1.1 - исправлена ошибка в расчёте периодов
212 | - v1.2 - код разбит на h и cpp
213 | - v1.3 - поправлен незначительный баг
214 | - v1.4 - исправлена таблица частот и периодов
215 | - v1.5 - исправлен restart и resume
216 | - v1.6 - phase shift вынесен отдельным методом
217 | - v1.7 - поправлена документация
218 | - v1.8 - исправлен баг с макс периодом
219 | - v1.9 - исправлен баг с возвращаемым 2х периодом
220 | - v1.10 - добавлен флаг ready
221 |
222 |
223 | ## Баги и обратная связь
224 | При нахождении багов создавайте **Issue**, а лучше сразу пишите на почту [alex@alexgyver.ru](mailto:alex@alexgyver.ru)
225 | Библиотека открыта для доработки и ваших **Pull Request**'ов!
226 |
227 |
228 | При сообщении о багах или некорректной работе библиотеки нужно обязательно указывать:
229 | - Версия библиотеки
230 | - Какой используется МК
231 | - Версия SDK (для ESP)
232 | - Версия Arduino IDE
233 | - Корректно ли работают ли встроенные примеры, в которых используются функции и конструкции, приводящие к багу в вашем коде
234 | - Какой код загружался, какая работа от него ожидалась и как он работает в реальности
235 | - В идеале приложить минимальный код, в котором наблюдается баг. Не полотно из тысячи строк, а минимальный код
236 |
--------------------------------------------------------------------------------
/README_EN.md:
--------------------------------------------------------------------------------
1 | This is an automatic translation, may be incorrect in some places. See sources and examples!
2 |
3 | # Gyvertimers
4 | Setting up and controlling interruptions on the hardware timer ATMEGA328P, Atmega2560
5 | - all three timers on Atmega328 and six timers on Atmega2560 are supported;
6 | - Setting up the period (ISS) and frequency (Hz) interruptions:
7 | - 8 bit timers: 61 Hz - 1 MHz (16 384 μs .. 1 μs);
8 | - 16 bits of timers: 0.24 Hz - 1 MHz (4,200,000 μs .. 1 μs);
9 | - automatic adjustment of the settings of the period from the tactive frequency (F_CPU);
10 | - the function returns the exact established period/frequency for debugging (the frequency is limited by the timer resolution);
11 | - Support for the multichannel mode of operation: one timer calls 2 (atmega328) or
12 | 3 (ATMEGA2560, timers 1, 3, 4, 5) interruption with a custom-made shift in a phase of 0-360 degrees;
13 | - the customizable action of the hardware output of the timer for interruption: high signal, low signal, switching.
14 | Allows you to generate a meander (one- and two-stroke);
15 | - timer control: start/stop/pause/continue/initialization;
16 |
17 | ## compatibility
18 | Atmega328p, Atmega2560
19 |
20 | ### Documentation
21 | There is [extended documentation](https://alexgyver.ru/gyvertimers/) to the library
22 |
23 | ## Content
24 | - [Installation](#install)
25 | - [Initialization](#init)
26 | - [Usage](#usage)
27 | - [Example](#example)
28 | - [Versions](#versions)
29 | - [Bugs and feedback](#feedback)
30 |
31 |
32 | ## Installation
33 | - The library can be found by the name **gyvertimers** and installed through the library manager in:
34 | - Arduino ide
35 | - Arduino ide v2
36 | - Platformio
37 | - [download the library](https://github.com/gyverlibs/gyvertimers/archive/refs/heads/main.zip) .Zip archive for manual installation:
38 | - unpack and put in *C:\Program Files (X86)\Arduino\Libraries* (Windows X64)
39 | - unpack and put in *C:\Program Files\Arduino\Libraries* (Windows X32)
40 | - unpack and put in *documents/arduino/libraries/* (Mac)
41 | - (Arduino IDE) Automatic installation from ZIP: *Sketch > Include library > Add .ZIP library...* and specify downloaded archive
42 | - Read more detailed instructions for installing libraries [here](https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%BD%D0%BE%BE%BE%BED0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA)
43 | ### Update
44 | - I recommend always updating the library: errors and bugs are corrected in the new versions, as well as optimization and new features are added
45 | - through the IDE library manager: find the library how to install and click "update"
46 | - Manually: **remove the folder with the old version**, and then put a new one in its place. “Replacement” cannot be done: sometimes in new versions, files that remain when replacing are deleted and can lead to errors!
47 |
48 |
49 |
50 | ## Initialization
51 | No
52 |
53 |
54 | ## Usage
55 | ```CPP
56 | Methods for Timer0, Timer1, Timer2 ...
57 | uint32_t setperiod (period);// Installation of the period in microseconds and starting the timer.Returns the real period (accuracy is limited by the timer resolution).
58 | uint32_t setfrequency (frequency);// Frequency installation in Hertz and the timer launch.Returns the real frequency (accuracy is limited by the timer resolution).
59 | Float SetFrequencyFloat// Frequency installation in Hertsa and the timer launch, decimal fractions are allowed.Returns the riverfrequency (accuracy is limited by timer resolution).
60 | VOID Enableisr (source);// Turn on the interruptions, the channel of interruptions Channel_a or Channel_b (+ Channel_C by Mega2560)
61 | Void Disableisr (source);// Turn off the interruptions, channel Channel_a or Channel_b.The timer account does not stop (the channel A will be turned off without specifying the parameters).
62 | VOID PAUSE ();// suspend the timer account without dropping the counter
63 | VOID Resume ();// Continue the score after a pause
64 | VOID Stop ();// stop the score and drop the counter
65 | VOID RESTART ();// restart the timer (drop the counter)
66 | VOID Setdefault ();// Install the default timer parameters ("arduino-wilting")
67 | VOID outputenable (channel, mode);// Channel: Turn on the output of the Channel_a or Channel_b timer (+ channel_c in Mega2560).Mode: Toggle_pin, Clear_pin, Set_pin (switch/turn off/turn on the PIN on interruption)
68 | VOID outputdisable (channel);// Disconnect the output of the Channel_a or Channel_b timer (+ channel_c from Mega2560, see Thamere Taklitsa)
69 | VOID outputState (channel, condition);// Change the condition of the channel: High / Low
70 | VOID PHASSHIFT (source, phase);// shift the phase of the channel by 0-360 degrees (only channel b moves 8 bits of timers)
71 | Bool Ready (Uint8_T Channel);// returns True if an interruption on the specified channel occurs
72 | Bool Ready ();// returns True if there is an interruption on the channel A
73 |
74 | /*
75 | The library gives direct access to interruption without “arduinsky” Attachinterrapt, which allows
76 | Reduce the time of calling the interruption processor function.Interruption with configured frequency
77 | will be processed in the block of the type of ISR (channel) {}, example:
78 | */
79 | ISR (Timer1_a) {
80 | // Your code
81 | }
82 |
83 | ISR (Timer1_b) {
84 | // Your code
85 | }
86 |
87 | ISR (Timer2_b) {
88 | // Your code
89 | }
90 |
91 | ISR (Timer0_A) {
92 | // Your code
93 | }
94 |
95 | /*
96 | ------------------------------------------- ARDUINO Nano 16 MHz (atmega328) ------------------------------------
97 | Timer |Discharge |Frequencies |Periods |Exits |Pin Arduino |PIN MK |
98 | -------- | ------------------ | -------------------------------------------------------------- | ----------- | ------------------------------------------------------|
99 | Timer0 |8 bits |61 Hz - 1 MHz |16 384 .. 1 μs |Channel_a |D6 |PD6 |
100 | ||||Channel_b |D5 |PD5 |
101 | -------- | ------------------ | -------------------------------------------------------------- | ----------- | ------------------------------------------------------|
102 | Timer1 |16 bit |0.24 Hz - 1 MHz |4 200 000 .. 1 μs |Channel_a |D9 |PB1 |
103 | ||||Channel_b |D10 |PB2 |
104 | -------- | ------------------ | -------------------------------------------------------------- | ----------- | ------------------------------------------------------|
105 | Timer2 |8 bits |61 Hz - 1 MHz |16 384 .. 1 μs |Channel_a |D11 |PB3 |
106 | ||||Channel_b |D3 |PD3 |
107 | ------------------------------------------------------------------------------------------
108 |
109 | -------------------------------------------- MEGA 16 MHz (atmega2560) ---------------------------------------
110 | Timer |Discharge |Frequencies |Periods |Exits |Pin Arduino |PIN MK |
111 | -------- | ------------------ | -------------------------------------------------------------- | ----------- | ------------------------------------------------------|
112 | Timer0 |8 bits |61 Hz - 1 MHz |16 384 .. 1 μs |Channel_a |13 |PB7 |
113 | ||||Channel_b |4 |PG5 |
114 | -------- | ------------------ | -------------------------------------------------------------- | ----------- | ------------------------------------------------------|
115 | Timer1 |16 bit |0.24 Hz - 1 MHz |4 200 000 .. 1 μs |Channel_a |11 |PB5 |
116 | ||||Channel_b |12 |PB6 |
117 | ||||Channel_c |13 |PB7 |
118 | -------- | ------------------ | -------------------------------------------------------------- | ----------- | ------------------------------------------------------|
119 | Timer2 |8 bits |61 Hz - 1 MHz |16 384 .. 1 μs |Channel_a |10 |PB4 |
120 | ||||Channel_b |9 |PH6 |
121 | -------- | ------------------ | -------------------------------------------------------------- | ----------- | --------------- | ------ |
122 | Timer3 |16 bit |0.24 Hz - 1 MHz |4 200 000 .. 1 μs |Channel_a |5 |PE3 |
123 | ||||Channel_b |2 |PE4 |
124 | ||||Channel_c |3 |PE5 |
125 | -------- | ------------------ | -------------------------------------------------------------- | ----------- | ------------------------------------------------------|
126 | Timer4 |16 bit |0.24 Hz - 1 MHz |4 200 000 .. 1 μs |Channel_a |6 |PH3 |
127 | ||||Channel_b |7 |PH4 |
128 | ||||Channel_c |8 |PH5 |
129 | -------- | ------------------ | -------------------------------------------------------------- | ----------- | ------------------------------------------------------|
130 | Timer5 |16 bit |0.24 Hz - 1 MHz |4 200 000 .. 1 μs |Channel_a |46 |PL3 |
131 | ||||Channel_b |45 |PL4 |
132 | ||||Channel_c |44 |PL5 |
133 | ------------------------------------------------------------------------------------------
134 | */
135 | ```
136 |
137 |
138 | ## Example
139 | The rest of the examples look at ** Examples **!
140 | ```CPP
141 | // Demonstration of all functions of the library
142 |
143 | #include
144 |
145 | VOID setup () {
146 | // reconfigure the timer and set him a period or frequency
147 | // All functions return the real period / frequency that may differ from the introduced
148 | Timer2.Setperiod (1000);// set a specific period of 1000 μs (~ 1000 Hz), will return the real period to the ISS
149 | Timer0.setfrequency (250);// Set the frequency of the timer interruptions in Hz, will return the real frequency in Herza
150 | Timer1.setfrequencyFloat (50.20);// Set the frequency more accurately, in fractional numbers, it is relevant for low frequencies and timer 1
151 | // From that moment on, the timer is already reconfigured and drives with a fractured frequency / period
152 |
153 | // Connect the interruption of the timer, from this moment the interruption will begin to be called
154 | Timer0.enableisr ();// connect the standard interruption, channel A, without a phase retire
155 | Timer2.enableisr (Channel_b);// Connect the interruption of timer 2, channel b
156 | Timer1.enableisr (Channel_a);// Connect the interruption of the channel a
157 | Timer1.enableisr (Channel_b);// connect the second interruption of timer 1
158 | // interruption will already begin to be called
159 |
160 | // if suddenly the interruption needs to be turned off without stopping the timer
161 | Timer1.disableisr (Channel_b);
162 | // From this moment, interruption b will no longer be called
163 |
164 | // if you need to suspend the timer completely, hardware
165 | Timer2.pause ();
166 | // From that moment on the timer stands still, the contents of the counter remains untouched
167 |
168 | // Now the timer can be returned to duty
169 | Timer2.Resum ();
170 | // Timer continued to count from the same place
171 |
172 | // if you need to completely stop the timer and drop the contents of the counter
173 | Timer1.Stop ();
174 | // Timer stands, the counter is dropped
175 |
176 | // Return the timer to duty
177 | Timer1.Restart ();
178 | // The timer is restarted, began to count from the beginning
179 |
180 | // if you need to return the standard arduino - timer settings
181 | Timer0.Setdefault ();
182 | // Now the timer works in Stanland mode
183 | }
184 |
185 | // Vectors of interruptions
186 | ISR (Timer1_a) {
187 | }
188 |
189 | ISR (Timer1_b) {
190 | }
191 |
192 | ISR (Timer2_b) {
193 | }
194 |
195 | ISR (Timer0_A) {
196 | }
197 |
198 | VOID loop () {
199 |
200 | }
201 | ```
202 |
203 |
204 | ## Versions
205 | - V1.1 - Fixed error in the calculation of periods
206 | - V1.2 - The code is divided into h and CPP
207 | - v1.3 - a slight bug is corrected
208 | - V1.4 - Fixed frequency and periods are fixed
209 | - V1.5 - Restart and Resume fixed
210 | - V1.6 - Phase Shift is made in a separate method
211 | - v1.7 - documentation corrected
212 | - V1.8 - Fixed bug with max period
213 | - V1.9 - Fixed a bug with a return 2 -period
214 | - V1.10 - added flag of Ready
215 |
216 |
217 | ## Bugs and feedback
218 | Create an **issue** when you find bugs, and better immediately write to the mail [alex@alexgyver.ru](mailto:alex@alexgyver.ru)
219 | The library is open for refinement and your **pull requests**.
220 |
221 |
222 | When reporting about bugs or incorrect work of the library, it is necessary to indicate:
223 | - The version of the library
224 | - What is MK used
225 | - SDK version (for ESP)
226 | - Version of Arduino IDE
227 | - Whether the built-in examples work correctly, in which the functions and designs are used, leading to a bug in your code
228 | - What code is loaded, what was expected, and how it works in reality
229 | - Ideally, attach the minimum code in which the bug is observed. Not a thousand lines, but a minimum code.
230 |
--------------------------------------------------------------------------------
/docs/timers.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GyverLibs/GyverTimers/8d16082b9d7210e80fc342b0e17899b5107e47d1/docs/timers.xlsx
--------------------------------------------------------------------------------
/examples/all_functions/all_functions.ino:
--------------------------------------------------------------------------------
1 | // Демонстрация всех функций библиотеки
2 |
3 | #include
4 |
5 | void setup() {
6 | // Перенастроить таймер и задать ему период или частоту
7 | // Все функции возвращают реальный период / частоту, которые могут отличаться от введенных
8 | Timer2.setPeriod(1000); // Задать конкретный период 1000 мкс (~ 1000 гц), вернет реальный период в мкс
9 | Timer0.setFrequency(250); // Задать частоту прерываний таймера в Гц, вернет реальную частоту в герцах
10 | Timer1.setFrequencyFloat(50.20); // Задать частоту более точно, в дробных числах, актуально для низких частот и таймера 1
11 | // С этого момента таймер уже перенастроен и гоняет с выьранной частотой / периодом
12 |
13 | // Подключить прерывание таймера, с этого момента прерывания начнут вызываться
14 | Timer0.enableISR(); // Подключить стандартное прерывание, канал А, без сдига фаз
15 | Timer2.enableISR(CHANNEL_B); // Подключить прерывание таймера 2, канал B
16 | Timer1.enableISR(CHANNEL_A); // Подключить прерывание канала А
17 | Timer1.enableISR(CHANNEL_B); // Подключить второе прерывание таймера 1
18 | // Прерывание уже начнет вызываться
19 |
20 | // Если вдруг прерывание нужно отключить, не останавливая таймер
21 | Timer1.disableISR(CHANNEL_B);
22 | // С этого момента прерывание B больше не будет вызываться
23 |
24 | // Если нужно приостановить таймер ПОЛНОСТЬЮ, аппаратно
25 | Timer2.pause();
26 | // С этого момента таймер стоит на месте, содержимое счетчика остается нетронутым
27 |
28 | // Теперь таймер можно вернуть в строй
29 | Timer2.resume();
30 | // Таймер продолжил считать с того же места
31 |
32 | // Если нужно полностью остановить таймер и сбросить содержимое счетчика
33 | Timer1.stop();
34 | // Таймер стоит, счетчик сброшен
35 |
36 | // Возвращаем таймер в строй
37 | Timer1.restart();
38 | // Таймер перезапущен, начал считать с начала
39 |
40 | // Если нужно вернуть стандартные Arduino - настройки таймера
41 | Timer0.setDefault();
42 | // Теперь таймер работает в станлартном режиме
43 | }
44 |
45 | // векторы прерываний
46 | ISR(TIMER1_A) {
47 |
48 | }
49 |
50 | ISR(TIMER1_B) {
51 |
52 | }
53 |
54 | ISR(TIMER2_B) {
55 |
56 | }
57 |
58 | ISR(TIMER0_A) {
59 |
60 | }
61 |
62 | void loop() {
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/examples/double_interrupts/double_interrupts.ino:
--------------------------------------------------------------------------------
1 | // Пример генерации двухканальных прерываний на таймере с РАВНЫМ периодом, но сдвинутых по фазе
2 | // два потока прерываний с сдвигом 180 градусов (полная инверсия)
3 |
4 | #include
5 |
6 | void setup() {
7 | Serial.begin(9600);
8 |
9 | Serial.print("Real timer frequency is : "); // Выведем реальную частоту, реальная может отличаться от заданой (ограничено разрешением таймера)
10 | Serial.println(Timer1.setFrequencyFloat(2.50)); // Частота прерываний - 2.5 гц , используй .setFrequency(...) для целых чисел
11 | delay(1000);
12 | Timer1.enableISR(CHANNEL_A); // Первый канал - А
13 | Timer1.enableISR(CHANNEL_B); // Второй канал - B
14 | Timer1.phaseShift(CHANNEL_B, 180); // сдвинем фазу относительно первого
15 | }
16 |
17 | void loop() {}
18 |
19 | // два прерывания на одном таймере
20 | ISR(TIMER1_A) {
21 | Serial.println(" Channel A interrupt !"); // Прерывание А
22 | }
23 |
24 | ISR(TIMER1_B) {
25 | Serial.println(" Channel B interrupt !"); // Прерывание B
26 | }
27 |
--------------------------------------------------------------------------------
/examples/encoder_mode/encoder_mode.ino:
--------------------------------------------------------------------------------
1 | // Пример генерации двухтактного меандра на таймере 2 (пины D3 и D11)
2 | #include
3 |
4 | void setup() {
5 | pinMode(3, OUTPUT); // настроить пин как выход
6 | pinMode(11, OUTPUT); // настроить пин как выход
7 |
8 | // из-за особенности генерации меандра таймером
9 | // частоту нужно указывать в два раза больше нужной!
10 | Timer2.setFrequency(15000 * 2); // настроить частоту в Гц и запустить таймер. Меандр на 15 кГц
11 | Timer2.outputEnable(CHANNEL_A, TOGGLE_PIN); // в момент срабатывания таймера пин будет переключаться
12 | Timer2.outputEnable(CHANNEL_B, TOGGLE_PIN); // в момент срабатывания таймера пин будет переключаться
13 |
14 | // задаём фазовый сдвиг 0-360 (для всех каналов кроме A на 8 бит таймерах)
15 | Timer2.phaseShift(CHANNEL_B, 180);
16 | }
17 |
18 | void loop() {
19 | }
20 |
--------------------------------------------------------------------------------
/examples/meandr_2tact/meandr_2tact.ino:
--------------------------------------------------------------------------------
1 | // Пример генерации двухтактного меандра на таймере 2 (пины D3 и D11)
2 | #include
3 |
4 | void setup() {
5 | pinMode(3, OUTPUT); // настроить пин как выход
6 | pinMode(11, OUTPUT); // настроить пин как выход
7 |
8 | // из-за особенности генерации меандра таймером
9 | // частоту нужно указывать в два раза больше нужной!
10 | Timer2.setFrequency(15000 * 2); // настроить частоту в Гц и запустить таймер. Меандр на 15 кГц
11 | Timer2.outputEnable(CHANNEL_A, TOGGLE_PIN); // в момент срабатывания таймера пин будет переключаться
12 | Timer2.outputEnable(CHANNEL_B, TOGGLE_PIN); // в момент срабатывания таймера пин будет переключаться
13 | Timer2.outputState(CHANNEL_A, HIGH); // задаём начальное состояние пина 11
14 | Timer2.outputState(CHANNEL_B, LOW); // задаём начальное состояние пина 3
15 | }
16 |
17 | void loop() {
18 | }
--------------------------------------------------------------------------------
/examples/meandr_test/meandr_test.ino:
--------------------------------------------------------------------------------
1 | //Пример генерации меандра на таймере 2 , канале B (D3 на Arduino UNO)
2 | #include
3 |
4 | void setup() {
5 | pinMode(3, OUTPUT); // настроить пин как выход
6 |
7 | // из-за особенности генерации меандра таймером
8 | // частоту нужно указывать в два раза больше нужной!
9 | Timer2.setFrequency(500 * 2); // настроить частоту таймера в Гц
10 | Timer2.outputEnable(CHANNEL_B, TOGGLE_PIN); // в момент срабатывания таймера пин будет переключаться
11 | }
12 |
13 | void loop() {
14 | }
--------------------------------------------------------------------------------
/examples/simple/simple.ino:
--------------------------------------------------------------------------------
1 | // Пример простой генерации прерываний аппаратным таймером
2 | #include
3 |
4 | void setup() {
5 | Serial.begin(9600);
6 | Timer1.setFrequency(3); // Высокоточный таймер 1 для первого прерывания, частота - 3 Герца
7 | //Timer1.setPeriod(333333); // то же самое! Частота 3 Гц это период 333 333 микросекунд
8 | //Timer1.setFrequencyFloat(4.22); // Если нужна дробная частота в Гц
9 | Timer1.enableISR(); // Запускаем прерывание (по умолч. канал А)
10 |
11 | // запустим второй таймер
12 | Timer2.setPeriod(10000); // Устанавливаем период таймера 10000 мкс -> 100 гц
13 | Timer2.enableISR(CHANNEL_A); // Или просто .enableISR(), запускаем прерывание на канале А таймера 2
14 | pinMode(13, OUTPUT); // будем мигать
15 | }
16 |
17 | void loop() {}
18 |
19 | // Прерывание А таймера 1
20 | ISR(TIMER1_A) { // пишем в сериал
21 | Serial.println("timer1");
22 | }
23 |
24 | // Прерывание А таймера 2
25 | ISR(TIMER2_A) {
26 | // мигаем
27 | digitalWrite(13, !digitalRead(13));
28 | }
29 |
--------------------------------------------------------------------------------
/examples/withoutInterrupts/withoutInterrupts.ino:
--------------------------------------------------------------------------------
1 | // Используем аппаратный таймер вместо софтверного millis()/micros() БЕЗ прерываний
2 | // Подойдет для быстрых событий с высокой точностью!
3 |
4 | #include
5 |
6 | void setup() {
7 | Serial.begin(9600); // Для примера откроем порт
8 |
9 | Timer1.setFrequency(3); // Задать частоту в целых числах
10 | // С этого момента таймер уже перенастроен и гоняет с выбранной частотой / периодом
11 | }
12 |
13 | void loop() {
14 | static uint32_t timer = millis();
15 | if (millis() - timer >= 1000) {
16 | timer = millis();
17 | Serial.println("Software timer!");
18 | }
19 |
20 | if (Timer1.ready(CHANNEL_A)) { // Если прерывание канала А таймера 1 готово (но мы его не включили)
21 | Timer1.stop(); // Тормозим таймер (при желании)
22 | Serial.println("Hardware timer!");
23 | Timer1.restart(); // Перезапускаем таймер (раз затормозили)
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/keywords.txt:
--------------------------------------------------------------------------------
1 | #######################################
2 | # Syntax Coloring Map For GyverTimers
3 | #######################################
4 |
5 | #######################################
6 | # Datatypes (KEYWORD1)
7 | #######################################
8 | GyverTimers KEYWORD1
9 |
10 | Timer0 KEYWORD1
11 | Timer1 KEYWORD1
12 | Timer2 KEYWORD1
13 | Timer3 KEYWORD1
14 | Timer4 KEYWORD1
15 | Timer5 KEYWORD1
16 |
17 | #######################################
18 | # Methods and Functions (KEYWORD2)
19 | #######################################
20 | ISR KEYWORD2
21 |
22 | ready KEYWORD2
23 | setPeriod KEYWORD2
24 | setFrequency KEYWORD2
25 | setFrequencyFloat KEYWORD2
26 | enableISR KEYWORD2
27 | disableISR KEYWORD2
28 | pause KEYWORD2
29 | resume KEYWORD2
30 | stop KEYWORD2
31 | restart KEYWORD2
32 | setDefault KEYWORD2
33 | outputEnable KEYWORD2
34 | outputDisable KEYWORD2
35 | outputState KEYWORD2
36 | phaseShift KEYWORD2
37 |
38 | #######################################
39 | # Constants (LITERAL1)
40 | #######################################
41 | TIMER0_A LITERAL1
42 | TIMER0_B LITERAL1
43 | TIMER1_A LITERAL1
44 | TIMER1_B LITERAL1
45 | TIMER1_C LITERAL1
46 | TIMER2_A LITERAL1
47 | TIMER2_B LITERAL1
48 | TIMER3_A LITERAL1
49 | TIMER3_B LITERAL1
50 | TIMER3_C LITERAL1
51 | TIMER4_A LITERAL1
52 | TIMER4_B LITERAL1
53 | TIMER4_C LITERAL1
54 | TIMER5_A LITERAL1
55 | TIMER5_B LITERAL1
56 | TIMER5_C LITERAL1
57 |
58 | CHANNEL_A LITERAL1
59 | CHANNEL_B LITERAL1
60 | CHANNEL_C LITERAL1
61 |
62 | TOGGLE_PIN LITERAL1
63 | CLEAR_PIN LITERAL1
64 | SET_PIN LITERAL1
--------------------------------------------------------------------------------
/library.properties:
--------------------------------------------------------------------------------
1 | name=GyverTimers
2 | version=1.10
3 | author=AlexGyver
4 | maintainer=AlexGyver
5 | sentence=Library for control hardware timers on ATmega328p and ATmega2560
6 | paragraph=Library for control hardware timers on ATmega328p and ATmega2560
7 | category=Timing
8 | url=https://github.com/GyverLibs/GyverTimers
9 | architectures=avr
--------------------------------------------------------------------------------
/src/GyverTimers.cpp:
--------------------------------------------------------------------------------
1 | #include "GyverTimers.h"
2 |
3 | // ========================== READY ==========================
4 | bool Timer_0::ready(uint8_t channel) {
5 | bool flag = false;
6 | switch (channel) {
7 | case CHANNEL_A: flag = bitRead(TIFR0, OCF0A); if (flag)bitSet(TIFR0, OCF0A); break; // Return interrupt flag + clear flag
8 | case CHANNEL_B: flag = bitRead(TIFR0, OCF0B); if (flag)bitSet(TIFR0, OCF0B); break;
9 | }
10 | return flag;
11 | }
12 |
13 | bool Timer_1::ready(uint8_t channel) {
14 | bool flag = false;
15 | switch (channel) {
16 | case CHANNEL_A: flag = bitRead(TIFR1, OCF1A); if (flag)bitSet(TIFR1, OCF1A); break; // Return interrupt flag + clear flag
17 | case CHANNEL_B: flag = bitRead(TIFR1, OCF1B); if (flag)bitSet(TIFR1, OCF1B); break;
18 | #if defined(__AVR_ATmega2560__)
19 | case CHANNEL_C: flag = bitRead(TIFR1, OCF1C); if (flag)bitSet(TIFR1, OCF1C); break;
20 | #endif
21 | }
22 | return flag;
23 | }
24 |
25 | bool Timer_2::ready(uint8_t channel) {
26 | bool flag = false;
27 | switch (channel) {
28 | case CHANNEL_A: flag = bitRead(TIFR2, OCF2A); if (flag)bitSet(TIFR2, OCF2A); break; // Return interrupt flag + clear flag
29 | case CHANNEL_B: flag = bitRead(TIFR2, OCF2B); if (flag)bitSet(TIFR2, OCF2B); break;
30 | }
31 | return flag;
32 | }
33 |
34 | #if defined(__AVR_ATmega2560__)
35 | bool Timer_3::ready(uint8_t channel) {
36 | bool flag = false;
37 | switch (channel) {
38 | case CHANNEL_A: flag = bitRead(TIFR3, OCF3A); if (flag)bitSet(TIFR3, OCF3A); break; // Return interrupt flag + clear flag
39 | case CHANNEL_B: flag = bitRead(TIFR3, OCF3B); if (flag)bitSet(TIFR3, OCF3B); break;
40 | case CHANNEL_C: flag = bitRead(TIFR3, OCF3C); if (flag)bitSet(TIFR3, OCF3C); break;
41 | }
42 | return flag;
43 | }
44 |
45 | bool Timer_4::ready(uint8_t channel) {
46 | bool flag = false;
47 | switch (channel) {
48 | case CHANNEL_A: flag = bitRead(TIFR4, OCF4A); if (flag)bitSet(TIFR4, OCF4A); break; // Return interrupt flag + clear flag
49 | case CHANNEL_B: flag = bitRead(TIFR4, OCF4B); if (flag)bitSet(TIFR4, OCF4B); break;
50 | case CHANNEL_C: flag = bitRead(TIFR4, OCF4C); if (flag)bitSet(TIFR4, OCF4C); break;
51 | }
52 | return flag;
53 | }
54 |
55 | bool Timer_5::ready(uint8_t channel) {
56 | bool flag = false;
57 | switch (channel) {
58 | case CHANNEL_A: flag = bitRead(TIFR5, OCF5A); if (flag)bitSet(TIFR5, OCF5A); break; // Return interrupt flag + clear flag
59 | case CHANNEL_B: flag = bitRead(TIFR5, OCF5B); if (flag)bitSet(TIFR5, OCF5B); break;
60 | case CHANNEL_C: flag = bitRead(TIFR5, OCF5C); if (flag)bitSet(TIFR5, OCF5C); break;
61 | }
62 | return flag;
63 | }
64 | #endif
65 |
66 | // ========================== OUTPUT STATE ==========================
67 | void Timer_0::outputState(uint8_t channel, bool state) {
68 | switch (channel) {
69 | case CHANNEL_A: TCCR0B = (TCCR0B & 0x7F) | (state << FOC0A); break;
70 | case CHANNEL_B: TCCR0B = (TCCR0B & 0xBF) | (state << FOC0B); break;
71 | }
72 | }
73 |
74 | void Timer_1::outputState(uint8_t channel, bool state) {
75 | switch (channel) {
76 | case CHANNEL_A: TCCR1C = (TCCR1C & 0x7F) | (state << FOC1A); break;
77 | case CHANNEL_B: TCCR1C = (TCCR1C & 0xBF) | (state << FOC1B); break;
78 | #if defined(__AVR_ATmega2560__)
79 | case CHANNEL_C: TCCR1C = (TCCR1C & 0xDF) | (state << FOC1C); break;
80 | #endif
81 | }
82 | }
83 |
84 | void Timer_2::outputState(uint8_t channel, bool state) {
85 | switch (channel) {
86 | case CHANNEL_A: TCCR2B = (TCCR2B & 0x7F) | (state << FOC2A); break;
87 | case CHANNEL_B: TCCR2B = (TCCR2B & 0xBF) | (state << FOC2B); break;
88 | }
89 | }
90 |
91 | #if defined(__AVR_ATmega2560__)
92 | void Timer_3::outputState(uint8_t channel, bool state) {
93 | switch (channel) {
94 | case CHANNEL_A: TCCR3C = (TCCR3C & 0x7F) | (state << FOC3A); break;
95 | case CHANNEL_B: TCCR3C = (TCCR3C & 0xBF) | (state << FOC3B); break;
96 | case CHANNEL_C: TCCR3C = (TCCR3C & 0xDF) | (state << FOC3C); break;
97 | }
98 | }
99 |
100 | void Timer_4::outputState(uint8_t channel, bool state) {
101 | switch (channel) {
102 | case CHANNEL_A: TCCR4C = (TCCR4C & 0x7F) | (state << FOC4A); break;
103 | case CHANNEL_B: TCCR4C = (TCCR4C & 0xBF) | (state << FOC4B); break;
104 | case CHANNEL_C: TCCR4C = (TCCR4C & 0xDF) | (state << FOC4C); break;
105 | }
106 | }
107 |
108 | void Timer_5::outputState(uint8_t channel, bool state) {
109 | switch (channel) {
110 | case CHANNEL_A: TCCR5C = (TCCR5C & 0x7F) | (state << FOC5A); break;
111 | case CHANNEL_B: TCCR5C = (TCCR5C & 0xBF) | (state << FOC5B); break;
112 | case CHANNEL_C: TCCR5C = (TCCR5C & 0xDF) | (state << FOC5C); break;
113 | }
114 | }
115 | #endif
116 |
117 |
118 | // ========================== PAUSE ==========================
119 | void Timer_0::pause(void) {
120 | TCCR0B = (TCCR0B & 0xF8); // Clear timer clock bits
121 | }
122 |
123 | void Timer_1::pause(void) {
124 | TCCR1B = (TCCR1B & 0xF8);
125 | }
126 |
127 | void Timer_2::pause(void) {
128 | TCCR2B = (TCCR2B & 0xF8);
129 | }
130 |
131 | #if defined(__AVR_ATmega2560__)
132 |
133 | void Timer_3::pause(void) {
134 | TCCR3B = (TCCR3B & 0xF8);
135 | }
136 |
137 | void Timer_4::pause(void) {
138 | TCCR4B = (TCCR4B & 0xF8);
139 | }
140 |
141 | void Timer_5::pause(void) {
142 | TCCR5B = (TCCR5B & 0xF8);
143 | }
144 |
145 | #endif
146 |
147 | // ========================== RESUME ==========================
148 | void Timer_0::resume(void) {
149 | TCCR0B = ((TCCR0B & 0xF8) | _timer0_clock); // Return clock timer settings
150 | }
151 |
152 | void Timer_1::resume(void) {
153 | TCCR1B = ((TCCR1B & 0xF8) | _timer1_clock);
154 | }
155 |
156 | void Timer_2::resume(void) {
157 | TCCR2B = ((TCCR2B & 0xF8) | _timer2_clock);
158 | }
159 |
160 | #if defined(__AVR_ATmega2560__)
161 | void Timer_3::resume(void) {
162 | TCCR3B = ((TCCR3B & 0xF8) | _timer3_clock);
163 | }
164 |
165 | void Timer_4::resume(void) {
166 | TCCR4B = ((TCCR4B & 0xF8) | _timer4_clock);
167 | }
168 |
169 | void Timer_5::resume(void) {
170 | TCCR5B = ((TCCR5B & 0xF8) | _timer5_clock);
171 | }
172 | #endif
173 |
174 |
175 | // ========================== STOP ==========================
176 | void Timer_0::stop(void) {
177 | Timer_0::pause();
178 | TCNT0 = 0x00; // Clear timer counter
179 | }
180 |
181 | void Timer_1::stop(void) {
182 | Timer_1::pause();
183 | TCNT1 = 0x00;
184 | }
185 |
186 | void Timer_2::stop(void) {
187 | Timer_2::pause();
188 | TCNT2 = 0x00;
189 | }
190 |
191 | #if defined(__AVR_ATmega2560__)
192 | void Timer_3::stop(void) {
193 | Timer_3::pause();
194 | TCNT3 = 0x00;
195 | }
196 |
197 | void Timer_4::stop(void) {
198 | Timer_4::pause();
199 | TCNT4 = 0x00;
200 | }
201 |
202 | void Timer_5::stop(void) {
203 | Timer_5::pause();
204 | TCNT5 = 0x00;
205 | }
206 | #endif
207 |
208 |
209 | // ========================== RESTART ==========================
210 | void Timer_0::restart(void) {
211 | Timer_0::resume();
212 | TCNT0 = 0x00;
213 | }
214 |
215 | void Timer_1::restart(void) {
216 | Timer_1::resume();
217 | TCNT1 = 0x00;
218 | }
219 |
220 | void Timer_2::restart(void) {
221 | Timer_2::resume();
222 | TCNT2 = 0x00;
223 | }
224 |
225 | #if defined(__AVR_ATmega2560__)
226 | void Timer_3::restart(void) {
227 | Timer_3::resume();
228 | TCNT3 = 0x00;
229 | }
230 |
231 | void Timer_4::restart(void) {
232 | Timer_4::resume();
233 | TCNT4 = 0x00;
234 | }
235 |
236 | void Timer_5::restart(void) {
237 | Timer_5::resume();
238 | TCNT5 = 0x00;
239 | }
240 | #endif
241 |
242 |
243 | // ========================== DISABLE ISR ==========================
244 | void Timer_0::disableISR(uint8_t source) {
245 | TIMSK0 &= ~ (source ? (1 << OCIE0B) : (1 << OCIE0A));
246 | }
247 |
248 | void Timer_1::disableISR(uint8_t source) {
249 | switch (source) {
250 | case CHANNEL_A: TIMSK1 &= ~ (1 << OCIE1A); break;
251 | case CHANNEL_B: TIMSK1 &= ~ (1 << OCIE1B); break;
252 | #if defined(__AVR_ATmega2560__)
253 | case CHANNEL_C: TIMSK1 &= ~ (1 << OCIE1C); break;
254 | #endif
255 | }
256 | }
257 |
258 | void Timer_2::disableISR(uint8_t source) {
259 | TIMSK2 &= ~ (source ? (1 << OCIE2B) : (1 << OCIE2A));
260 | }
261 |
262 | #if defined(__AVR_ATmega2560__)
263 | void Timer_3::disableISR(uint8_t source) {
264 | switch (source) {
265 | case CHANNEL_A: TIMSK3 &= ~ (1 << OCIE3A); break;
266 | case CHANNEL_B: TIMSK3 &= ~ (1 << OCIE3B); break;
267 | case CHANNEL_C: TIMSK3 &= ~ (1 << OCIE3C); break;
268 | }
269 | }
270 |
271 | void Timer_4::disableISR(uint8_t source) {
272 | switch (source) {
273 | case CHANNEL_A: TIMSK4 &= ~ (1 << OCIE4A); break;
274 | case CHANNEL_B: TIMSK4 &= ~ (1 << OCIE4B); break;
275 | case CHANNEL_C: TIMSK4 &= ~ (1 << OCIE4C); break;
276 | }
277 | }
278 |
279 | void Timer_5::disableISR(uint8_t source) {
280 | switch (source) {
281 | case CHANNEL_A: TIMSK5 &= ~ (1 << OCIE5A); break;
282 | case CHANNEL_B: TIMSK5 &= ~ (1 << OCIE5B); break;
283 | case CHANNEL_C: TIMSK5 &= ~ (1 << OCIE5C); break;
284 | }
285 | }
286 | #endif
287 |
288 | // ========================== DEFAULT ==========================
289 | void Timer_0::setDefault(void) {
290 | TCCR0A = 0x03; // Fast PWM , 8 bit
291 | TCCR0B = 0x03; // Prescaler /64
292 | OCR0B = 0x00; // Clear COMPA
293 | OCR0A = 0x00; // Clear COMPB
294 | TCNT0 = 0x00; // Clear counter
295 | }
296 |
297 | void Timer_1::setDefault(void) {
298 | TCCR1A = 0x01; // Phasecorrect PWM , 8 bit
299 | TCCR1B = 0x0B; // Prescaler /64
300 | OCR1B = 0x00; // Clear COMPA
301 | OCR1A = 0x00; // Clear COMPB
302 | TCNT1 = 0x00; // Clear counter
303 | }
304 |
305 | void Timer_2::setDefault(void) {
306 | TCCR2A = 0x01; // Phasecorrect PWM , 8 bit
307 | TCCR2B = 0x04; // Prescaler /64
308 | OCR2B = 0x00; // Clear COMPA
309 | OCR2A = 0x00; // Clear COMPB
310 | TCNT2 = 0x00; // Clear counter
311 | }
312 |
313 |
314 | #if defined(__AVR_ATmega2560__)
315 | void Timer_3::setDefault(void) {
316 | TCCR3A = 0x01; // Phasecorrect PWM , 8 bit
317 | TCCR3B = 0x0B; // Prescaler /64
318 | OCR3B = 0x00; // Clear COMPA
319 | OCR3A = 0x00; // Clear COMPB
320 | TCNT3 = 0x00; // Clear counter
321 | }
322 |
323 | void Timer_4::setDefault(void) {
324 | TCCR4A = 0x01; // Phasecorrect PWM , 8 bit
325 | TCCR4B = 0x0B; // Prescaler /64
326 | OCR4B = 0x00; // Clear COMPA
327 | OCR4A = 0x00; // Clear COMPB
328 | TCNT4 = 0x00; // Clear counter
329 | }
330 |
331 | void Timer_5::setDefault(void) {
332 | TCCR5A = 0x01; // Phasecorrect PWM , 8 bit
333 | TCCR5B = 0x0B; // Prescaler /64
334 | OCR5B = 0x00; // Clear COMPA
335 | OCR5A = 0x00; // Clear COMPB
336 | TCNT5 = 0x00; // Clear counter
337 | }
338 | #endif
339 |
340 | // ========================== PHASE SHIFT ==========================
341 | void Timer_0::phaseShift(uint8_t source, uint16_t phase) {
342 | if (source) OCR0B = map(phase, 0, 360, 0, OCR0A);
343 | }
344 |
345 | void Timer_1::phaseShift(uint8_t source, uint16_t phase) {
346 | switch (source) {
347 | case CHANNEL_A: OCR1A = map(phase, 0, 360, 0, ICR1); break;
348 | case CHANNEL_B: OCR1B = map(phase, 0, 360, 0, ICR1); break;
349 | #if defined(__AVR_ATmega2560__)
350 | case CHANNEL_C: OCR1C = map(phase, 0, 360, 0, ICR1); break;
351 | #endif
352 | }
353 | }
354 |
355 | void Timer_2::phaseShift(uint8_t source, uint16_t phase) {
356 | if (source) OCR2B = map(phase, 0, 360, 0, OCR2A);
357 | }
358 |
359 | #if defined(__AVR_ATmega2560__)
360 |
361 | void Timer_3::phaseShift(uint8_t source, uint16_t phase) {
362 | switch (source) {
363 | case CHANNEL_A: OCR3A = map(phase, 0, 360, 0, ICR3); break;
364 | case CHANNEL_B: OCR3B = map(phase, 0, 360, 0, ICR3); break;
365 | case CHANNEL_C: OCR3C = map(phase, 0, 360, 0, ICR3); break;
366 | }
367 | }
368 |
369 | void Timer_4::phaseShift(uint8_t source, uint16_t phase) {
370 | switch (source) {
371 | case CHANNEL_A: OCR4A = map(phase, 0, 360, 0, ICR4); break;
372 | case CHANNEL_B: OCR4B = map(phase, 0, 360, 0, ICR4); break;
373 | case CHANNEL_C: OCR4C = map(phase, 0, 360, 0, ICR4); break;
374 | }
375 | }
376 |
377 | void Timer_5::phaseShift(uint8_t source, uint16_t phase) {
378 | switch (source) {
379 | case CHANNEL_A: OCR5A = map(phase, 0, 360, 0, ICR5); break;
380 | case CHANNEL_B: OCR5B = map(phase, 0, 360, 0, ICR5); break;
381 | case CHANNEL_C: OCR5C = map(phase, 0, 360, 0, ICR5); break;
382 | }
383 | }
384 | #endif
385 |
386 |
387 | // ========================== ENABLE ISR ==========================
388 | void Timer_0::enableISR(uint8_t source) {
389 | if (!source) TIMSK0 |= (1 << OCIE0A);
390 | else TIMSK0 |= (1 << OCIE0B);
391 | }
392 |
393 | void Timer_1::enableISR(uint8_t source) {
394 | switch (source) {
395 | case CHANNEL_A: TIMSK1 |= (1 << OCIE1A); break;
396 | case CHANNEL_B: TIMSK1 |= (1 << OCIE1B); break;
397 | #if defined(__AVR_ATmega2560__)
398 | case CHANNEL_C: TIMSK1 |= (1 << OCIE1C); break;
399 | #endif
400 | }
401 | }
402 |
403 | void Timer_2::enableISR(uint8_t source) {
404 | if (!source) TIMSK2 |= (1 << OCIE2A);
405 | else TIMSK2 |= (1 << OCIE2B);
406 | }
407 |
408 | #if defined(__AVR_ATmega2560__)
409 |
410 | void Timer_3::enableISR(uint8_t source) {
411 | switch (source) {
412 | case CHANNEL_A: TIMSK3 |= (1 << OCIE3A); break;
413 | case CHANNEL_B: TIMSK3 |= (1 << OCIE3B); break;
414 | case CHANNEL_C: TIMSK3 |= (1 << OCIE3C); break;
415 | }
416 | }
417 |
418 | void Timer_4::enableISR(uint8_t source) {
419 | switch (source) {
420 | case CHANNEL_A: TIMSK4 |= (1 << OCIE4A); break;
421 | case CHANNEL_B: TIMSK4 |= (1 << OCIE4B); break;
422 | case CHANNEL_C: TIMSK4 |= (1 << OCIE4C); break;
423 | }
424 | }
425 |
426 | void Timer_5::enableISR(uint8_t source) {
427 | switch (source) {
428 | case CHANNEL_A: TIMSK5 |= (1 << OCIE5A); break;
429 | case CHANNEL_B: TIMSK5 |= (1 << OCIE5B); break;
430 | case CHANNEL_C: TIMSK5 |= (1 << OCIE5C); break;
431 | }
432 | }
433 | #endif
434 |
435 | // ========================== SET FREQUENCY ==========================
436 | uint32_t Timer_0::setFrequency(uint32_t _timer0_frequency) {
437 | return 1000000UL / (Timer_0::setPeriod(1000000UL / _timer0_frequency));
438 | }
439 |
440 | uint32_t Timer_1::setFrequency(uint32_t _timer1_frequency) {
441 | return 1000000UL / (Timer_1::setPeriod(1000000UL / _timer1_frequency));
442 | }
443 |
444 | uint32_t Timer_2::setFrequency(uint32_t _timer2_frequency) {
445 | return 1000000UL / (Timer_2::setPeriod(1000000UL / _timer2_frequency));
446 | }
447 |
448 | #if defined(__AVR_ATmega2560__)
449 |
450 | uint32_t Timer_3::setFrequency(uint32_t _timer3_frequency) {
451 | return 1000000UL / (Timer_3::setPeriod(1000000UL / _timer3_frequency));
452 | }
453 |
454 | uint32_t Timer_4::setFrequency(uint32_t _timer4_frequency) {
455 | return 1000000UL / (Timer_4::setPeriod(1000000UL / _timer4_frequency));
456 | }
457 |
458 | uint32_t Timer_5::setFrequency(uint32_t _timer5_frequency) {
459 | return 1000000UL / (Timer_5::setPeriod(1000000UL / _timer5_frequency));
460 | }
461 |
462 | #endif
463 |
464 |
465 | // ========================== SET FREQUENCY FLOAT ==========================
466 | float Timer_0::setFrequencyFloat(float _timer0_frequency) {
467 | return 1000000.0F / (Timer_0::setPeriod(1000000.0F / _timer0_frequency));
468 | }
469 |
470 | float Timer_1::setFrequencyFloat(float _timer1_frequency) {
471 | return 1000000.0F / (Timer_1::setPeriod(1000000.0F / _timer1_frequency));
472 | }
473 |
474 | float Timer_2::setFrequencyFloat(float _timer2_frequency) {
475 | return 1000000.0F / (Timer_2::setPeriod(1000000.0F / _timer2_frequency));
476 | }
477 |
478 | #if defined(__AVR_ATmega2560__)
479 |
480 | float Timer_3::setFrequencyFloat(float _timer3_frequency) {
481 | return 1000000.0F / (Timer_3::setPeriod(1000000.0F / _timer3_frequency));
482 | }
483 |
484 | float Timer_4::setFrequencyFloat(float _timer4_frequency) {
485 | return 1000000.0F / (Timer_4::setPeriod(1000000.0F / _timer4_frequency));
486 | }
487 |
488 | float Timer_5::setFrequencyFloat(float _timer5_frequency) {
489 | return 1000000.0F / (Timer_5::setPeriod(1000000.0F / _timer5_frequency));
490 | }
491 |
492 | #endif
493 |
494 | // ========================== OUTPUT ENABLE ==========================
495 | void Timer_0::outputEnable(uint8_t channel, uint8_t mode) {
496 | switch (channel) {
497 | case CHANNEL_A: TCCR0A = (TCCR0A & 0x3F) | (mode << 6); break;
498 | case CHANNEL_B: TCCR0A = (TCCR0A & 0xCF) | (mode << 4); break;
499 | }
500 | }
501 |
502 | void Timer_1::outputEnable(uint8_t channel, uint8_t mode) {
503 | switch (channel) {
504 | case CHANNEL_A: TCCR1A = (TCCR1A & 0x3F) | (mode << 6); break;
505 | case CHANNEL_B: TCCR1A = (TCCR1A & 0xCF) | (mode << 4); break;
506 | #if defined(__AVR_ATmega2560__)
507 | case CHANNEL_C: TCCR1A = (TCCR1A & 0xF3) | (mode << 2); break;
508 | #endif
509 | }
510 | }
511 |
512 | void Timer_2::outputEnable(uint8_t channel, uint8_t mode) {
513 | switch (channel) {
514 | case CHANNEL_A: TCCR2A = (TCCR2A & 0x3F) | (mode << 6); break;
515 | case CHANNEL_B: TCCR2A = (TCCR2A & 0xCF) | (mode << 4); break;
516 | }
517 | }
518 |
519 | #if defined(__AVR_ATmega2560__)
520 | void Timer_3::outputEnable(uint8_t channel, uint8_t mode) {
521 | switch (channel) {
522 | case CHANNEL_A: TCCR3A = (TCCR3A & 0x3F) | (mode << 6); break;
523 | case CHANNEL_B: TCCR3A = (TCCR3A & 0xCF) | (mode << 4); break;
524 | case CHANNEL_C: TCCR3A = (TCCR3A & 0xF3) | (mode << 2); break;
525 | }
526 | }
527 |
528 | void Timer_4::outputEnable(uint8_t channel, uint8_t mode) {
529 | switch (channel) {
530 | case CHANNEL_A: TCCR4A = (TCCR4A & 0x3F) | (mode << 6); break;
531 | case CHANNEL_B: TCCR4A = (TCCR4A & 0xCF) | (mode << 4); break;
532 | case CHANNEL_C: TCCR4A = (TCCR4A & 0xF3) | (mode << 2); break;
533 | }
534 | }
535 |
536 | void Timer_5::outputEnable(uint8_t channel, uint8_t mode) {
537 | switch (channel) {
538 | case CHANNEL_A: TCCR5A = (TCCR5A & 0x3F) | (mode << 6); break;
539 | case CHANNEL_B: TCCR5A = (TCCR5A & 0xCF) | (mode << 4); break;
540 | case CHANNEL_C: TCCR5A = (TCCR5A & 0xF3) | (mode << 2); break;
541 | }
542 | }
543 | #endif
544 |
545 |
546 | // ========================== OUTPUT DISABLE ==========================
547 | void Timer_0::outputDisable(uint8_t channel) {
548 | switch (channel) {
549 | case CHANNEL_A: TCCR0A = (TCCR0A & 0x3F); break;
550 | case CHANNEL_B: TCCR0A = (TCCR0A & 0xCF); break;
551 | }
552 | }
553 |
554 | void Timer_1::outputDisable(uint8_t channel) {
555 | switch (channel) {
556 | case CHANNEL_A: TCCR1A = (TCCR1A & 0x3F); break;
557 | case CHANNEL_B: TCCR1A = (TCCR1A & 0xCF); break;
558 | #if defined(__AVR_ATmega2560__)
559 | case CHANNEL_C: TCCR1A = (TCCR1A & 0xF3); break;
560 | #endif
561 | }
562 | }
563 |
564 | void Timer_2::outputDisable(uint8_t channel) {
565 | switch (channel) {
566 | case CHANNEL_A: TCCR2A = (TCCR2A & 0x3F); break;
567 | case CHANNEL_B: TCCR2A = (TCCR2A & 0xCF); break;
568 | }
569 | }
570 |
571 | #if defined(__AVR_ATmega2560__)
572 | void Timer_3::outputDisable(uint8_t channel) {
573 | switch (channel) {
574 | case CHANNEL_A: TCCR3A = (TCCR3A & 0x3F); break;
575 | case CHANNEL_B: TCCR3A = (TCCR3A & 0xCF); break;
576 | case CHANNEL_C: TCCR3A = (TCCR3A & 0xF3); break;
577 | }
578 | }
579 |
580 | void Timer_4::outputDisable(uint8_t channel) {
581 | switch (channel) {
582 | case CHANNEL_A: TCCR4A = (TCCR4A & 0x3F); break;
583 | case CHANNEL_B: TCCR4A = (TCCR4A & 0xCF); break;
584 | case CHANNEL_C: TCCR4A = (TCCR4A & 0xF3); break;
585 | }
586 | }
587 |
588 | void Timer_5::outputDisable(uint8_t channel) {
589 | switch (channel) {
590 | case CHANNEL_A: TCCR5A = (TCCR5A & 0x3F); break;
591 | case CHANNEL_B: TCCR5A = (TCCR5A & 0xCF); break;
592 | case CHANNEL_C: TCCR5A = (TCCR5A & 0xF3); break;
593 | }
594 | }
595 | #endif
596 |
597 |
598 |
599 | // ========================== SET PERIOD ==========================
600 | uint32_t Timer_0::setPeriod(uint32_t _timer0_period) {
601 | _timer0_period = constrain(_timer0_period, 1, MAX_PERIOD_8);
602 |
603 | uint32_t _timer0_cycles = F_CPU / 1000000 * _timer0_period; // Calculation of the number of timer cycles per period
604 | uint8_t _timer0_prescaler = 0x00;
605 | uint16_t _timer0_divider = 0x00;
606 |
607 | if (_timer0_cycles < 256UL) { // Сhoose optimal divider for the timer
608 | _timer0_prescaler = 0x01;
609 | _timer0_divider = 1UL;
610 | } else if (_timer0_cycles < 256UL * 8) {
611 | _timer0_prescaler = 0x02;
612 | _timer0_divider = 8UL;
613 | } else if (_timer0_cycles < 256UL * 64) {
614 | _timer0_prescaler = 0x03;
615 | _timer0_divider = 64UL;
616 | } else if (_timer0_cycles < 256UL * 256) {
617 | _timer0_prescaler = 0x04;
618 | _timer0_divider = 256UL;
619 | } else {
620 | _timer0_prescaler = 0x05;
621 | _timer0_divider = 1024UL;
622 | }
623 |
624 | uint8_t _timer0_top = (_timer0_cycles < 256UL * 1024 ? (_timer0_cycles / _timer0_divider) : 256UL) ;
625 |
626 | TCCR0A = (TCCR0A & 0xF0) | (1 << WGM21); // CTC - mode
627 | TCCR0B = _timer0_prescaler; // Set timer prescaler
628 | OCR0A = _timer0_top - 1; // Set timer top
629 | _timer0_clock = (TCCR0B & 0x07); // Save timer clock settings
630 |
631 | return (1000000UL / ((F_CPU / _timer0_divider) / _timer0_top)); // Return real timer period
632 | }
633 |
634 | uint32_t Timer_1::setPeriod(uint32_t _timer1_period) {
635 | _timer1_period = constrain(_timer1_period, 1, MAX_PERIOD_16);
636 |
637 | uint32_t _timer1_cycles = F_CPU / 1000000 * _timer1_period; // Calculation of the number of timer cycles per period
638 | uint8_t _timer1_prescaler = 0x00;
639 | uint16_t _timer1_divider = 0x00;
640 |
641 | if (_timer1_cycles < 65536UL) { // Сhoose optimal divider for the timer
642 | _timer1_prescaler = 0x01;
643 | _timer1_divider = 1UL;
644 | } else if (_timer1_cycles < 65536UL * 8) {
645 | _timer1_prescaler = 0x02;
646 | _timer1_divider = 8UL;
647 | } else if (_timer1_cycles < 65536UL * 64) {
648 | _timer1_prescaler = 0x03;
649 | _timer1_divider = 64UL;
650 | } else if (_timer1_cycles < 65536UL * 256) {
651 | _timer1_prescaler = 0x04;
652 | _timer1_divider = 256UL;
653 | } else {
654 | _timer1_prescaler = 0x05;
655 | _timer1_divider = 1024UL;
656 | }
657 |
658 | uint16_t _timer1_top = (_timer1_cycles < 65536UL * 1024 ? (_timer1_cycles / _timer1_divider) : 65536UL) ;
659 | #if defined(__AVR_ATmega2560__)
660 | TCCR1A = (TCCR1A & 0xFC);
661 | #else
662 | TCCR1A = (TCCR1A & 0xF0);
663 | #endif
664 | TCCR1B = ((1 << WGM13) | (1 << WGM12) | _timer1_prescaler); // CTC mode + set prescaler
665 | ICR1 = _timer1_top - 1; // Set timer top
666 | _timer1_clock = (TCCR1B & 0x07); // Save timer clock settings
667 | return (1000000UL / ((F_CPU / _timer1_divider) / _timer1_top)); // Return real timer period
668 | }
669 |
670 | uint32_t Timer_2::setPeriod(uint32_t _timer2_period) {
671 | _timer2_period = constrain(_timer2_period, 1, MAX_PERIOD_8);
672 |
673 | uint32_t _timer2_cycles = F_CPU / 1000000 * _timer2_period; // Calculation of the number of timer cycles per period
674 | uint8_t _timer2_prescaler = 0x00;
675 | uint16_t _timer2_divider = 0x00;
676 |
677 | if (_timer2_cycles < 256UL) { // Сhoose optimal divider for the timer
678 | _timer2_prescaler = 0x01;
679 | _timer2_divider = 1UL;
680 | } else if (_timer2_cycles < 256UL * 8) {
681 | _timer2_prescaler = 0x02;
682 | _timer2_divider = 8UL;
683 | } else if (_timer2_cycles < 256UL * 32) {
684 | _timer2_prescaler = 0x03;
685 | _timer2_divider = 32UL;
686 | } else if (_timer2_cycles < 256UL * 64) {
687 | _timer2_prescaler = 0x04;
688 | _timer2_divider = 64UL;
689 | } else if (_timer2_cycles < 256UL * 128) {
690 | _timer2_prescaler = 0x05;
691 | _timer2_divider = 128UL;
692 | } else if (_timer2_cycles < 256UL * 256) {
693 | _timer2_prescaler = 0x06;
694 | _timer2_divider = 256UL;
695 | } else {
696 | _timer2_prescaler = 0x07;
697 | _timer2_divider = 1024UL;
698 | }
699 |
700 | uint8_t _timer2_top = (_timer2_cycles < 256UL * 1024 ? (_timer2_cycles / _timer2_divider) : 256UL);
701 |
702 | TCCR2A = (TCCR2A & 0xF0) | (1 << WGM21); // CTC - mode
703 | TCCR2B = _timer2_prescaler; // Set timer prescaler
704 | OCR2A = _timer2_top - 1; // Set timer top
705 | _timer2_clock = (TCCR2B & 0x07); // Save timer clock settings
706 |
707 | return (1000000UL / ((F_CPU / _timer2_divider) / _timer2_top)); // Return real timer period
708 | }
709 |
710 | #if defined(__AVR_ATmega2560__)
711 |
712 | uint32_t Timer_3::setPeriod(uint32_t _timer3_period) {
713 | _timer3_period = constrain(_timer3_period, 1, MAX_PERIOD_16);
714 |
715 | uint32_t _timer3_cycles = F_CPU / 1000000 * _timer3_period; // Calculation of the number of timer cycles per period
716 | uint8_t _timer3_prescaler = 0x00;
717 | uint16_t _timer3_divider = 0x00;
718 |
719 | if (_timer3_cycles < 65536UL) { // Сhoose optimal divider for the timer
720 | _timer3_prescaler = 0x01;
721 | _timer3_divider = 1UL;
722 | } else if (_timer3_cycles < 65536UL * 8) {
723 | _timer3_prescaler = 0x02;
724 | _timer3_divider = 8UL;
725 | } else if (_timer3_cycles < 65536UL * 64) {
726 | _timer3_prescaler = 0x03;
727 | _timer3_divider = 64UL;
728 | } else if (_timer3_cycles < 65536UL * 256) {
729 | _timer3_prescaler = 0x04;
730 | _timer3_divider = 256UL;
731 | } else {
732 | _timer3_prescaler = 0x05;
733 | _timer3_divider = 1024UL;
734 | }
735 |
736 | uint16_t _timer3_top = (_timer3_cycles < 65536UL * 1024 ? (_timer3_cycles / _timer3_divider) : 65536UL) ;
737 |
738 | TCCR3A = (TCCR3A & 0xFC);
739 | TCCR3B = ((1 << WGM33) | (1 << WGM32) | _timer3_prescaler); // CTC mode + set prescaler
740 | ICR3 = _timer3_top - 1; // Set timer top
741 | _timer3_clock = (TCCR3B & 0x07); // Save timer clock settings
742 |
743 | return (1000000UL / ((F_CPU / _timer3_divider) / _timer3_top)); // Return real timer period
744 | }
745 |
746 | uint32_t Timer_4::setPeriod(uint32_t _timer4_period) {
747 | _timer4_period = constrain(_timer4_period, 1, MAX_PERIOD_16);
748 |
749 | uint32_t _timer4_cycles = F_CPU / 1000000 * _timer4_period; // Calculation of the number of timer cycles per period
750 | uint8_t _timer4_prescaler = 0x00;
751 | uint16_t _timer4_divider = 0x00;
752 |
753 | if (_timer4_cycles < 65536UL) { // Сhoose optimal divider for the timer
754 | _timer4_prescaler = 0x01;
755 | _timer4_divider = 1UL;
756 | } else if (_timer4_cycles < 65536UL * 8) {
757 | _timer4_prescaler = 0x02;
758 | _timer4_divider = 8UL;
759 | } else if (_timer4_cycles < 65536UL * 64) {
760 | _timer4_prescaler = 0x03;
761 | _timer4_divider = 64UL;
762 | } else if (_timer4_cycles < 65536UL * 256) {
763 | _timer4_prescaler = 0x04;
764 | _timer4_divider = 256UL;
765 | } else {
766 | _timer4_prescaler = 0x05;
767 | _timer4_divider = 1024UL;
768 | }
769 |
770 | uint16_t _timer4_top = (_timer4_cycles < 65536UL * 1024 ? (_timer4_cycles / _timer4_divider) : 65536UL) ;
771 |
772 | TCCR4A = (TCCR4A & 0xFC);
773 | TCCR4B = ((1 << WGM43) | (1 << WGM42) | _timer4_prescaler); // CTC mode + set prescaler
774 | ICR4 = _timer4_top - 1; // Set timer top
775 | _timer4_clock = (TCCR4B & 0x07); // Save timer clock settings
776 |
777 | return (1000000UL / ((F_CPU / _timer4_divider) / _timer4_top)); // Return real timer period
778 | }
779 |
780 | uint32_t Timer_5::setPeriod(uint32_t _timer5_period) {
781 | _timer5_period = constrain(_timer5_period, 1, MAX_PERIOD_16);
782 |
783 | uint32_t _timer5_cycles = F_CPU / 1000000 * _timer5_period; // Calculation of the number of timer cycles per period
784 | uint8_t _timer5_prescaler = 0x00;
785 | uint16_t _timer5_divider = 0x00;
786 |
787 | if (_timer5_cycles < 65536UL) { // Сhoose optimal divider for the timer
788 | _timer5_prescaler = 0x01;
789 | _timer5_divider = 1UL;
790 | } else if (_timer5_cycles < 65536UL * 8) {
791 | _timer5_prescaler = 0x02;
792 | _timer5_divider = 8UL;
793 | } else if (_timer5_cycles < 65536UL * 64) {
794 | _timer5_prescaler = 0x03;
795 | _timer5_divider = 64UL;
796 | } else if (_timer5_cycles < 65536UL * 256) {
797 | _timer5_prescaler = 0x04;
798 | _timer5_divider = 256UL;
799 | } else {
800 | _timer5_prescaler = 0x05;
801 | _timer5_divider = 1024UL;
802 | }
803 |
804 | uint16_t _timer5_top = (_timer5_cycles < 65536UL * 1024 ? (_timer5_cycles / _timer5_divider) : 65536UL) ;
805 |
806 | TCCR5A = (TCCR5A & 0xFC);
807 | TCCR5B = ((1 << WGM53) | (1 << WGM52) | _timer5_prescaler); // CTC mode + set prescaler
808 | ICR5 = _timer5_top - 1; // Set timer top
809 | _timer5_clock = (TCCR5B & 0x07); // Save timer clock settings
810 |
811 | return (1000000UL / ((F_CPU / _timer5_divider) / _timer5_top)); // Return real timer period
812 | }
813 |
814 | #endif
815 |
816 |
817 | Timer_0 Timer0 = Timer_0();
818 | Timer_1 Timer1 = Timer_1();
819 | Timer_2 Timer2 = Timer_2();
820 |
821 | #if defined(__AVR_ATmega2560__)
822 | Timer_3 Timer3 = Timer_3();
823 | Timer_4 Timer4 = Timer_4();
824 | Timer_5 Timer5 = Timer_5();
825 | #endif
--------------------------------------------------------------------------------
/src/GyverTimers.h:
--------------------------------------------------------------------------------
1 | /*
2 | Настройка и контроль прерываний по аппаратным таймерам ATmega328p, ATmega2560
3 | Документация: https://alexgyver.ru/gyvertimers/
4 | GitHub: https://github.com/GyverLibs/GyverTimers
5 | Возможности:
6 | - Поддерживаются все три таймера на ATmega328 и шесть таймеров на ATmega2560;
7 | - Настройка периода (мкс) и частоты (Гц) прерываний:
8 | - 8 бит таймеры: 61 Гц - 1 МГц (16 384 мкс.. 1 мкс);
9 | - 16 бит таймеры: 0.24 Гц - 1 МГц (4 200 000 мкс.. 1 мкс);
10 | - Автоматическая корректировка настройки периода от частоты тактирования (F_CPU);
11 | - Функция возвращает точный установившийся период/частоту для отладки (частота ограничена разрешением таймера);
12 | - Поддержка многоканального режима работы: один таймер вызывает 2 (ATmega328) или
13 | 3 (ATmega2560, таймеры 1, 3, 4, 5) прерывания с настраиваемым сдвигом по фазе 0-360 градусов;
14 | - Настраиваемое действие аппаратного вывода таймера по прерыванию: высокий сигнал, низкий сигнал, переключение.
15 | Позволяет генерировать меандр (одно- и двухтактный);
16 | - Контроль работы таймера: старт/стоп/пауза/продолжить/инициализация;
17 |
18 | Egor 'Nich1con' Zaharov for AlexGyver, alex@alexgyver.ru
19 | https://alexgyver.ru/
20 | MIT License
21 |
22 | Версии:
23 | v1.1 - исправлена ошибка в расчёте периодов
24 | v1.2 - код разбит на h и cpp
25 | v1.3 - поправлен незначительный баг
26 | v1.4 - исправлена таблица частот и периодов
27 | v1.5 - исправлен restart и resume
28 | v1.6 - phase shift вынесен отдельным методом
29 | v1.7 - поправлена документация
30 | v1.8 - исправлен баг с макс периодом
31 | v1.9 - исправлен баг с возвращаемым 2х периодом
32 | v1.10 - добавлен флаг ready
33 | */
34 |
35 | /*
36 | -------------------------------- Arduino NANO 16 МГц (ATmega328) ------------------------------------
37 | Таймер | Разрядность | Частоты | Периоды | Выходы | Пин Arduino | Пин МК|
38 | --------|---------------|-------------------|-------------------|-----------|---------------|-------|
39 | Timer0 | 8 бит | 61 Гц - 1 МГц | 16 384.. 1 мкс | CHANNEL_A | D6 | PD6 |
40 | | | | | CHANNEL_B | D5 | PD5 |
41 | --------|---------------|-------------------|-------------------|-----------|---------------|-------|
42 | Timer1 | 16 бит | 0.24 Гц - 1 МГц | 4 200 000.. 1 мкс | CHANNEL_A | D9 | PB1 |
43 | | | | | CHANNEL_B | D10 | PB2 |
44 | --------|---------------|-------------------|-------------------|-----------|---------------|-------|
45 | Timer2 | 8 бит | 61 Гц - 1 МГц | 16 384.. 1 мкс | CHANNEL_A | D11 | PB3 |
46 | | | | | CHANNEL_B | D3 | PD3 |
47 | ----------------------------------------------------------------------------------------------------
48 |
49 | ------------------------------ Arduino MEGA 16 МГц (ATmega2560) -------------------------------------
50 | Таймер | Разрядность | Частоты | Периоды | Выходы | Пин Arduino | Пин МК|
51 | --------|---------------|-------------------|-------------------|-----------|---------------|-------|
52 | Timer0 | 8 бит | 61 Гц - 1 МГц | 16 384.. 1 мкс | CHANNEL_A | 13 | PB7 |
53 | | | | | CHANNEL_B | 4 | PG5 |
54 | --------|---------------|-------------------|-------------------|-----------|---------------|-------|
55 | Timer1 | 16 бит | 0.24 Гц - 1 МГц | 4 200 000.. 1 мкс | CHANNEL_A | 11 | PB5 |
56 | | | | | CHANNEL_B | 12 | PB6 |
57 | | | | | CHANNEL_C | 13 | PB7 |
58 | --------|---------------|-------------------|-------------------|-----------|---------------|-------|
59 | Timer2 | 8 бит | 61 Гц - 1 МГц | 16 384.. 1 мкс | CHANNEL_A | 10 | PB4 |
60 | | | | | CHANNEL_B | 9 | PH6 |
61 | --------|---------------|-------------------|-------------------|-----------|---------------|-------|
62 | Timer3 | 16 бит | 0.24 Гц - 1 МГц | 4 200 000.. 1 мкс | CHANNEL_A | 5 | PE3 |
63 | | | | | CHANNEL_B | 2 | PE4 |
64 | | | | | CHANNEL_C | 3 | PE5 |
65 | --------|---------------|-------------------|-------------------|-----------|---------------|-------|
66 | Timer4 | 16 бит | 0.24 Гц - 1 МГц | 4 200 000.. 1 мкс | CHANNEL_A | 6 | PH3 |
67 | | | | | CHANNEL_B | 7 | PH4 |
68 | | | | | CHANNEL_C | 8 | PH5 |
69 | --------|---------------|-------------------|-------------------|-----------|---------------|-------|
70 | Timer5 | 16 бит | 0.24 Гц - 1 МГц | 4 200 000.. 1 мкс | CHANNEL_A | 46 | PL3 |
71 | | | | | CHANNEL_B | 45 | PL4 |
72 | | | | | CHANNEL_C | 44 | PL5 |
73 | ----------------------------------------------------------------------------------------------------
74 | */
75 |
76 | /*
77 | setPeriod(период) - установка периода в микросекундах и запуск таймера. Возвращает реальный период (точность ограничена разрешением таймера).
78 | setFrequency(частота) - установка частоты в Герцах и запуск таймера. Возвращает реальную частоту (точность ограничена разрешением таймера).
79 | setFrequencyFloat(частота float) - установка частоты в Герцах и запуск таймера, разрешены десятичные дроби. Возвращает реальную частоту (точность ограничена разрешением таймера).
80 | enableISR(источник) - включить прерывания, канал прерываний CHANNEL_A или CHANNEL_B (+ CHANNEL_C у Mega2560)
81 | disableISR(источник) - выключить прерывания, канал CHANNEL_A или CHANNEL_B. Счёт таймера не останавливается (без указания параметров будет выключен канал А).
82 | pause() - приостановить счёт таймера, не сбрасывая счётчик
83 | resume() - продолжить счёт после паузы
84 | stop() - остановить счёт и сбросить счётчик
85 | restart() - перезапустить таймер (сбросить счётчик)
86 | setDefault() - установить параметры таймера по умолчанию ("Ардуино-умолчания")
87 | outputEnable(канал, режим) - канал: включить выход таймера CHANNEL_A или CHANNEL_B (+ CHANNEL_C у Mega2560). Режим: TOGGLE_PIN, CLEAR_PIN, SET_PIN (переключить/выключить/включить пин по прерыванию)
88 | outputDisable(канал) - отключить выход таймера CHANNEL_A или CHANNEL_B (+ CHANNEL_C у Mega2560, см. такблицу таймеров)
89 | outputState(канал, состояние) - сменить состояние канала: HIGH / LOW
90 | phaseShift(источник, фаза) - сдвинуть фазу канала на 0-360 градусов (у 8 бит таймеров двигается только канал B)
91 | */
92 |
93 | #define MAX_PERIOD_8 (1000000UL * 1024UL / F_CPU * 256UL) // 16384 (61 Гц) на 16 МГц
94 | #define MAX_PERIOD_16 (1000000UL * 1024UL / F_CPU * 65536UL) // 4194304 (0.24 Гц) на 16 МГц
95 |
96 | #ifndef GyverTimers_h
97 | #define GyverTimers_h
98 | #include
99 |
100 | /* ========== Константы ========== */
101 | #define CHANNEL_A 0x00
102 | #define CHANNEL_B 0x01
103 | #define CHANNEL_C 0x02
104 |
105 | #define TOGGLE_PIN 0x01
106 | #define CLEAR_PIN 0x02
107 | #define SET_PIN 0x03
108 |
109 | #define TIMER0_A TIMER0_COMPA_vect
110 | #define TIMER0_B TIMER0_COMPB_vect
111 | #define TIMER1_A TIMER1_COMPA_vect
112 | #define TIMER1_B TIMER1_COMPB_vect
113 | #define TIMER2_A TIMER2_COMPA_vect
114 | #define TIMER2_B TIMER2_COMPB_vect
115 |
116 | #if defined(__AVR_ATmega2560__)
117 | #define TIMER1_C TIMER1_COMPC_vect
118 | #define TIMER3_A TIMER3_COMPA_vect
119 | #define TIMER3_B TIMER3_COMPB_vect
120 | #define TIMER3_C TIMER3_COMPC_vect
121 | #define TIMER4_A TIMER4_COMPA_vect
122 | #define TIMER4_B TIMER4_COMPB_vect
123 | #define TIMER4_C TIMER4_COMPC_vect
124 | #define TIMER5_A TIMER5_COMPA_vect
125 | #define TIMER5_B TIMER5_COMPB_vect
126 | #define TIMER5_C TIMER5_COMPC_vect
127 | #endif
128 |
129 | #define GYVERTIMERS_INLINE
130 | /*inline __attribute__((always_inline))*/
131 |
132 | /* ================ Сlasses of timers ================ */
133 | class Timer_0 { // Timer 0
134 | public:
135 | uint32_t setPeriod(uint32_t _timer0_period); // Set timer period [us]
136 | uint32_t setFrequency(uint32_t _timer0_frequency); // Set timer frequency [Hz]
137 | float setFrequencyFloat(float _timer0_frequency); // Set timer float frequency [Hz]
138 |
139 | GYVERTIMERS_INLINE
140 | bool ready(uint8_t channel = CHANNEL_A); // Return true, is interrupt is ready, but not enabled
141 |
142 | GYVERTIMERS_INLINE
143 | void enableISR(uint8_t source = CHANNEL_A); // Enable timer interrupt , channel A or B
144 |
145 | GYVERTIMERS_INLINE
146 | void disableISR(uint8_t source = CHANNEL_A); // Disable timer interrupt , channel A or B
147 |
148 | GYVERTIMERS_INLINE
149 | void pause(void); // Disable timer clock , not cleaning the counter
150 |
151 | GYVERTIMERS_INLINE
152 | void resume(void); // Return clock timer settings
153 |
154 | GYVERTIMERS_INLINE
155 | void stop(void); // Disable timer clock , and cleaning the counter
156 |
157 | GYVERTIMERS_INLINE
158 | void restart(void); // Return clock timer settings & reset counter
159 |
160 | GYVERTIMERS_INLINE
161 | void setDefault(void); // Set default timer settings
162 |
163 | GYVERTIMERS_INLINE
164 | void outputEnable(uint8_t channel, uint8_t mode); // Enable and configurate timer hardware output
165 |
166 | GYVERTIMERS_INLINE
167 | void outputDisable(uint8_t channel); // Disable timer hardware output
168 |
169 | GYVERTIMERS_INLINE
170 | void outputState(uint8_t channel,bool state); // Set High / Low on the timer output
171 |
172 | GYVERTIMERS_INLINE
173 | void phaseShift(uint8_t source, uint16_t phase);
174 |
175 | private:
176 | uint8_t _timer0_clock = 0x00; // Variable to store timer clock settings
177 | };
178 |
179 | class Timer_1 { // Timer 1
180 | public:
181 | uint32_t setPeriod(uint32_t _timer1_period); // Set timer period [Hz]
182 | uint32_t setFrequency(uint32_t _timer1_frequency); // Set timer frequency [Hz]
183 | float setFrequencyFloat(float _timer1_frequency); // Set timer float frequency [Hz]
184 |
185 | GYVERTIMERS_INLINE
186 | bool ready(uint8_t channel = CHANNEL_A); // Return true, is interrupt is ready, but not enabled
187 |
188 | GYVERTIMERS_INLINE
189 | void enableISR(uint8_t source = CHANNEL_A); // Enable timer interrupt , channel A or B
190 |
191 | GYVERTIMERS_INLINE
192 | void disableISR(uint8_t source = CHANNEL_A); // Disable timer interrupt , channel A or B
193 |
194 | GYVERTIMERS_INLINE
195 | void pause(void); // Disable timer clock , not cleaning the counter
196 |
197 | GYVERTIMERS_INLINE
198 | void resume(void); // Return clock timer settings
199 |
200 | GYVERTIMERS_INLINE
201 | void stop(void); // Disable timer clock , and cleaning the counter
202 |
203 | GYVERTIMERS_INLINE
204 | void restart(void); // Return clock timer settings & reset counter
205 |
206 | GYVERTIMERS_INLINE
207 | void setDefault(void); // Set default timer settings
208 |
209 | GYVERTIMERS_INLINE
210 | void outputEnable(uint8_t channel, uint8_t mode); // Enable and configurate timer hardware output
211 |
212 | GYVERTIMERS_INLINE
213 | void outputDisable(uint8_t channel); // Disable timer hardware output
214 |
215 | GYVERTIMERS_INLINE
216 | void outputState(uint8_t channel,bool state); // Set High / Low on the timer output
217 |
218 | GYVERTIMERS_INLINE
219 | void phaseShift(uint8_t source, uint16_t phase);
220 |
221 | private:
222 | uint8_t _timer1_clock = 0x00; // Variable to store timer clock settings
223 | };
224 |
225 | class Timer_2 { // Timer 2
226 | public:
227 | uint32_t setPeriod(uint32_t _timer2_period); // Set timer period [Hz]
228 | uint32_t setFrequency(uint32_t _timer2_frequency); // Set timer frequency [Hz]
229 | float setFrequencyFloat(float _timer2_frequency); // Set timer float frequency [Hz]
230 |
231 | GYVERTIMERS_INLINE
232 | bool ready(uint8_t channel = CHANNEL_A); // Return true, is interrupt is ready, but not enabled
233 |
234 | GYVERTIMERS_INLINE
235 | void enableISR(uint8_t source = CHANNEL_A); // Enable timer interrupt , channel A or B
236 |
237 | GYVERTIMERS_INLINE
238 | void disableISR(uint8_t source = CHANNEL_A); // Disable timer interrupt , channel A or B
239 |
240 | GYVERTIMERS_INLINE
241 | void pause(void); // Disable timer clock , not cleaning the counter
242 |
243 | GYVERTIMERS_INLINE
244 | void resume(void); // Return clock timer settings
245 |
246 | GYVERTIMERS_INLINE
247 | void stop(void); // Disable timer clock , and cleaning the counter
248 |
249 | GYVERTIMERS_INLINE
250 | void restart(void); // Return clock timer settings & reset counter
251 |
252 | GYVERTIMERS_INLINE
253 | void setDefault(void); // Set default timer settings
254 |
255 | GYVERTIMERS_INLINE
256 | void outputEnable(uint8_t channel, uint8_t mode); // Enable and configurate timer hardware output
257 |
258 | GYVERTIMERS_INLINE
259 | void outputDisable(uint8_t channel); // Disable timer hardware output
260 |
261 | GYVERTIMERS_INLINE
262 | void outputState(uint8_t channel,bool state); // Set High / Low on the timer output
263 |
264 | GYVERTIMERS_INLINE
265 | void phaseShift(uint8_t source, uint16_t phase);
266 |
267 | private:
268 | uint8_t _timer2_clock = 0x00; // Variable to store timer clock settings
269 | };
270 |
271 | #if defined(__AVR_ATmega2560__)
272 | class Timer_3 { // Timer 3
273 | public:
274 | uint32_t setPeriod(uint32_t _timer3_period); // Set timer period [Hz]
275 | uint32_t setFrequency(uint32_t _timer3_frequency); // Set timer frequency [Hz]
276 | float setFrequencyFloat(float _timer3_frequency); // Set timer float frequency [Hz]
277 |
278 | GYVERTIMERS_INLINE
279 | bool ready(uint8_t channel = CHANNEL_A); // Return true, is interrupt is ready, but not enabled
280 |
281 | GYVERTIMERS_INLINE
282 | void enableISR(uint8_t source = CHANNEL_A); // Enable timer interrupt , channel A or B
283 |
284 | GYVERTIMERS_INLINE
285 | void disableISR(uint8_t source = CHANNEL_A); // Disable timer interrupt , channel A or B
286 |
287 | GYVERTIMERS_INLINE
288 | void pause(void); // Disable timer clock , not cleaning the counter
289 |
290 | GYVERTIMERS_INLINE
291 | void resume(void); // Return clock timer settings
292 |
293 | GYVERTIMERS_INLINE
294 | void stop(void); // Disable timer clock , and cleaning the counter
295 |
296 | GYVERTIMERS_INLINE
297 | void restart(void); // Return clock timer settings & reset counter
298 |
299 | GYVERTIMERS_INLINE
300 | void setDefault(void); // Set default timer settings
301 |
302 | GYVERTIMERS_INLINE
303 | void outputEnable(uint8_t channel, uint8_t mode); // Enable and configurate timer hardware output
304 |
305 | GYVERTIMERS_INLINE
306 | void outputDisable(uint8_t channel); // Disable timer hardware output
307 |
308 | GYVERTIMERS_INLINE
309 | void outputState(uint8_t channel,bool state); // Set High / Low on the timer output
310 |
311 | GYVERTIMERS_INLINE
312 | void phaseShift(uint8_t source, uint16_t phase);
313 |
314 | private:
315 | uint8_t _timer3_clock = 0x00; // Variable to store timer clock settings
316 | };
317 |
318 | class Timer_4 { // Timer 4
319 | public:
320 | uint32_t setPeriod(uint32_t _timer4_period); // Set timer period [Hz]
321 | uint32_t setFrequency(uint32_t _timer4_frequency); // Set timer frequency [Hz]
322 | float setFrequencyFloat(float _timer4_frequency); // Set timer float frequency [Hz]
323 |
324 | GYVERTIMERS_INLINE
325 | bool ready(uint8_t channel = CHANNEL_A); // Return true, is interrupt is ready, but not enabled
326 |
327 | GYVERTIMERS_INLINE
328 | void enableISR(uint8_t source = CHANNEL_A); // Enable timer interrupt , channel A or B
329 |
330 | GYVERTIMERS_INLINE
331 | void disableISR(uint8_t source = CHANNEL_A); // Disable timer interrupt , channel A or B
332 |
333 | GYVERTIMERS_INLINE
334 | void pause(void); // Disable timer clock , not cleaning the counter
335 |
336 | GYVERTIMERS_INLINE
337 | void resume(void); // Return clock timer settings
338 |
339 | GYVERTIMERS_INLINE
340 | void stop(void); // Disable timer clock , and cleaning the counter
341 |
342 | GYVERTIMERS_INLINE
343 | void restart(void); // Return clock timer settings & reset counter
344 |
345 | GYVERTIMERS_INLINE
346 | void setDefault(void); // Set default timer settings
347 |
348 | GYVERTIMERS_INLINE
349 | void outputEnable(uint8_t channel, uint8_t mode); // Enable and configurate timer hardware output
350 |
351 | GYVERTIMERS_INLINE
352 | void outputDisable(uint8_t channel); // Disable timer hardware output
353 |
354 | GYVERTIMERS_INLINE
355 | void outputState(uint8_t channel,bool state); // Set High / Low on the timer output
356 |
357 | GYVERTIMERS_INLINE
358 | void phaseShift(uint8_t source, uint16_t phase);
359 |
360 | private:
361 | uint8_t _timer4_clock = 0x00; // Variable to store timer clock settings
362 | };
363 |
364 | class Timer_5 { // Timer 5
365 | public:
366 | uint32_t setPeriod(uint32_t _timer5_period); // Set timer period [Hz]
367 | uint32_t setFrequency(uint32_t _timer5_frequency); // Set timer frequency [Hz]
368 | float setFrequencyFloat(float _timer5_frequency); // Set timer float frequency [Hz]
369 |
370 | GYVERTIMERS_INLINE
371 | bool ready(uint8_t channel = CHANNEL_A); // Return true, is interrupt is ready, but not enabled
372 |
373 | GYVERTIMERS_INLINE
374 | void enableISR(uint8_t source = CHANNEL_A); // Enable timer interrupt , channel A or B
375 |
376 | GYVERTIMERS_INLINE
377 | void disableISR(uint8_t source = CHANNEL_A); // Disable timer interrupt , channel A or B
378 |
379 | GYVERTIMERS_INLINE
380 | void pause(void); // Disable timer clock , not cleaning the counter
381 |
382 | GYVERTIMERS_INLINE
383 | void resume(void); // Return clock timer settings
384 |
385 | GYVERTIMERS_INLINE
386 | void stop(void); // Disable timer clock , and cleaning the counter
387 |
388 | GYVERTIMERS_INLINE
389 | void restart(void); // Return clock timer settings & reset counter
390 |
391 | GYVERTIMERS_INLINE
392 | void setDefault(void); // Set default timer settings
393 |
394 | GYVERTIMERS_INLINE
395 | void outputEnable(uint8_t channel, uint8_t mode); // Enable and configurate timer hardware output
396 |
397 | GYVERTIMERS_INLINE
398 | void outputDisable(uint8_t channel); // Disable timer hardware output
399 |
400 | GYVERTIMERS_INLINE
401 | void outputState(uint8_t channel,bool state); // Set High / Low on the timer output
402 |
403 | GYVERTIMERS_INLINE
404 | void phaseShift(uint8_t source, uint16_t phase);
405 |
406 | private:
407 | uint8_t _timer5_clock = 0x00; // Variable to store timer clock settings
408 | };
409 |
410 | #endif
411 |
412 | extern Timer_0 Timer0;
413 | extern Timer_1 Timer1;
414 | extern Timer_2 Timer2;
415 |
416 | #if defined(__AVR_ATmega2560__)
417 | extern Timer_3 Timer3;
418 | extern Timer_4 Timer4;
419 | extern Timer_5 Timer5;
420 | #endif
421 |
422 | #endif
--------------------------------------------------------------------------------