├── .gitattributes ├── .github └── workflows │ └── tg-send.yml ├── LICENSE ├── README.md ├── README_EN.md ├── docs ├── customPWM.xlsx ├── defaultPWM.xlsx ├── Погрешность меандра до 1 кГц.jpg ├── Погрешность меандра до 10 кГц.jpg ├── Погрешность меандра до 100 кГц.jpg ├── Погрешность меандра до 1000 кГц.jpg └── Погрешность меандра.xlsx ├── examples ├── PWMdefFrequency │ └── PWMdefFrequency.ino ├── PWMfrequency │ └── PWMfrequency.ino ├── PWMresolution │ └── PWMresolution.ino ├── PWMtest │ └── PWMtest.ino └── squareTest │ └── squareTest.ino ├── keywords.txt ├── library.properties └── src ├── GyverPWM.cpp └── GyverPWM.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 | [![latest](https://img.shields.io/github/v/release/GyverLibs/GyverPWM.svg?color=brightgreen)](https://github.com/GyverLibs/GyverPWM/releases/latest/download/GyverPWM.zip) 2 | [![PIO](https://badges.registry.platformio.org/packages/gyverlibs/library/GyverPWM.svg)](https://registry.platformio.org/libraries/gyverlibs/GyverPWM) 3 | [![Foo](https://img.shields.io/badge/Website-AlexGyver.ru-blue.svg?style=flat-square)](https://alexgyver.ru/) 4 | [![Foo](https://img.shields.io/badge/%E2%82%BD%24%E2%82%AC%20%D0%9F%D0%BE%D0%B4%D0%B4%D0%B5%D1%80%D0%B6%D0%B0%D1%82%D1%8C-%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B0-orange.svg?style=flat-square)](https://alexgyver.ru/support_alex/) 5 | [![Foo](https://img.shields.io/badge/README-ENGLISH-blueviolet.svg?style=flat-square)](https://github-com.translate.goog/GyverLibs/GyverPWM?_x_tr_sl=ru&_x_tr_tl=en) 6 | 7 | [![Foo](https://img.shields.io/badge/ПОДПИСАТЬСЯ-НА%20ОБНОВЛЕНИЯ-brightgreen.svg?style=social&logo=telegram&color=blue)](https://t.me/GyverLibs) 8 | 9 | # GyverPWM 10 | Библиотека для расширенной генерации ШИМ на ATmega328 (Arduino UNO/Nano/Pro Mini...) 11 | - Аппаратная генерация ШИМ настраиваемой частоты и разрядности 12 | 13 | ### Совместимость 14 | Arduino UNO/Nano/Pro Mini 15 | 16 | ### Документация 17 | К библиотеке есть [расширенная документация](https://alexgyver.ru/GyverPWM/) 18 | 19 | ## Содержание 20 | - [Установка](#install) 21 | - [Инициализация](#init) 22 | - [Использование](#usage) 23 | - [Пример](#example) 24 | - [Версии](#versions) 25 | - [Баги и обратная связь](#feedback) 26 | 27 | 28 | ## Установка 29 | - Библиотеку можно найти по названию **GyverPWM** и установить через менеджер библиотек в: 30 | - Arduino IDE 31 | - Arduino IDE v2 32 | - PlatformIO 33 | - [Скачать библиотеку](https://github.com/GyverLibs/GyverPWM/archive/refs/heads/main.zip) .zip архивом для ручной установки: 34 | - Распаковать и положить в *C:\Program Files (x86)\Arduino\libraries* (Windows x64) 35 | - Распаковать и положить в *C:\Program Files\Arduino\libraries* (Windows x32) 36 | - Распаковать и положить в *Документы/Arduino/libraries/* 37 | - (Arduino IDE) автоматическая установка из .zip: *Скетч/Подключить библиотеку/Добавить .ZIP библиотеку…* и указать скачанный архив 38 | - Читай более подробную инструкцию по установке библиотек [здесь](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) 39 | ### Обновление 40 | - Рекомендую всегда обновлять библиотеку: в новых версиях исправляются ошибки и баги, а также проводится оптимизация и добавляются новые фичи 41 | - Через менеджер библиотек IDE: найти библиотеку как при установке и нажать "Обновить" 42 | - Вручную: **удалить папку со старой версией**, а затем положить на её место новую. "Замену" делать нельзя: иногда в новых версиях удаляются файлы, которые останутся при замене и могут привести к ошибкам! 43 | 44 | 45 | 46 | ## Инициализация 47 | Нет 48 | 49 | 50 | ## Использование 51 | ```cpp 52 | // ============== Функции для расширенной генерации ШИМ сигнала ============== 53 | // Данные функции убирают один ШИМ выход у 8-ми битных таймеров, оставляя нам ШИМ пины D3, D5, D9 и D10 на ATmega328 54 | void PWM_frequency(byte pin, long freq, modes correct); 55 | /* PWM_freqency(пин, частота, режим) - запустить ШИМ с выбранной частотой 56 | - Пины: D3 (таймер 2), D5 (таймер 0 - сломает millis/delay), D9 и D10 (таймер 1) 57 | - Режим: 0 (FAST_PWM), 1 (CORRECT_PWM) 58 | - Частота: 250-200'000 Гц для всех таймеров 59 | - Для изменения заполнения используй PWM_set 60 | - Разрядность в этом режиме приведена к 8 битам, на деле шаги изменения разные! 61 | */ 62 | void PWM_resolution(byte pin, byte res, modes correct); 63 | /* PWM_resolution(пин, разрядность, режим) - запустить ШИМ с выбранной разрядностью 64 | - Пины: D3 (таймер 2), D5 (таймер 0 - сломает millis/delay), D9 и D10 (таймер 1) 65 | - Режим: 0 (FAST_PWM), 1 (CORRECT_PWM) 66 | - Разрешение: D3 (4-8 бит), D5 (4-8 бит), D9 и D10 (4-16 бит) 67 | - Частота в этом режиме выбирается автоматически максимальная согласно возможностям таймера (см. таблицу) 68 | - Для изменения заполнения используй PWM_set 69 | - Пределы заполнения для разной разрядности указаны в таблице 70 | */ 71 | void PWM_set(byte pin, unsigned int duty); 72 | /* PWM_set(пин, заполнение) - изменить заполнение на выбранном пине 73 | - Пин: D3, D5, D6, D9, D10, D11 74 | - Заполнение: зависит от разрешения и режима (см. таблицу) 75 | - При использовании PWM_frequency разрядность составляет 8 бит (0-255) 76 | - При использовании PWM_resolution макс. значение заполнения равно (2^разрядность - 1), также смотри таблицу 77 | */ 78 | void PWM_detach(byte pin); // отключает ШИМ на выбранном пине (позволяет использовать digital Read/Write) 79 | void PWM_attach(byte pin); // подключает ШИМ на выбранном пине (с последними настройками) 80 | void PWM_default(byte pin); // сброс настроек соответствующего пину таймера на "стандартные" для Arduino 81 | void PWM_16KHZ_D3(byte duty); 82 | /* Запуск ШИМ с частотой 16 кГц на пине D3 83 | - Отменяет настройки PWM_frequency/PWM_resolution 84 | - Разрядность приведена к 8 битам (заполнение 0-255) 85 | - Заполнение меняет сама (не нужно вызывать PWM_set) */ 86 | void PWM_20KHZ_D3(byte duty); 87 | /* Запуск ШИМ с частотой 20 кГц на пине D3 88 | - Отменяет настройки PWM_frequency/PWM_resolution 89 | - Разрядность приведена к 8 битам (заполнение 0-255) 90 | - Заполнение меняет сама (не нужно вызывать PWM_set) */ 91 | void PWM_16KHZ_D5(byte duty); 92 | /* Запуск ШИМ с частотой 16 кГц на пине D5 93 | - Отменяет настройки PWM_frequency/PWM_resolution 94 | - Разрядность приведена к 8 битам (заполнение 0-255) 95 | - Заполнение меняет сама (не нужно вызывать PWM_set) */ 96 | void PWM_20KHZ_D5(byte duty); 97 | /* Запуск ШИМ с частотой 20 кГц на пине D5 98 | - Отменяет настройки PWM_frequency/PWM_resolution 99 | - Разрядность приведена к 8 битам (заполнение 0-255) 100 | - Заполнение меняет сама (не нужно вызывать PWM_set) */ 101 | void PWM_16KHZ_D9(int duty); 102 | /* Запуск ШИМ с частотой 16 кГц (15.6 кГц) на пине D9 103 | - Отменяет настройки PWM_frequency/PWM_resolution 104 | - Разрядность ровно 10 бит (заполнение 0-1023) 105 | - Заполнение меняет сама (не нужно вызывать PWM_set) */ 106 | void PWM_20KHZ_D9(int duty); 107 | /* Запуск ШИМ с частотой 20 кГц на пине D9 108 | - Отменяет настройки PWM_frequency/PWM_resolution 109 | - Разрядность приведена к 10 битам (заполнение 0-1023) 110 | - Заполнение меняет сама (не нужно вызывать PWM_set) */ 111 | void PWM_16KHZ_D10(int duty); 112 | /* Запуск ШИМ с частотой 16 кГц (15.6 кГц) на пине D10 113 | - Отменяет настройки PWM_frequency/PWM_resolution 114 | - Разрядность ровно 10 бит (заполнение 0-1023) 115 | - Заполнение меняет сама (не нужно вызывать PWM_set) */ 116 | void PWM_20KHZ_D10(int duty); 117 | /* Запуск ШИМ с частотой 20 кГц на пине D10 118 | - Отменяет настройки PWM_frequency/PWM_resolution 119 | - Разрядность приведена к 10 битам (заполнение 0-1023) 120 | - Заполнение меняет сама (не нужно вызывать PWM_set) */ 121 | 122 | float PWM_square_D9(float frequency); 123 | /* Генератор меандра (квадратная волна) на пине D9 124 | Частота от 2 Гц до 8 Мгц, шаг частоты зависит от частоты 125 | (начиная с 0.01 Гц и заканчивая десятками кГц!!!) 126 | Отключить можно вызвав PWM_detach(9); 127 | Для сброса таймера в режим по-умолчанию - PWM_default(9); 128 | Возвращает установленную частоту в герцах! 129 | 130 | Частота Погрешность 131 | 300 Гц 0.01 Гц 132 | 700 Гц 0.05 Гц 133 | 900 ГЦ 0.1 Гц 134 | 2 кГц 0.5 Гц 135 | 3 кГц 1 Гц 136 | 4 кГц 2 Гц 137 | 9 кГц 10 Гц 138 | 20 кГц 50 Гц 139 | 30 кГц 110 Гц 140 | 63 кГц 500 Гц 141 | 90 кГц 1000 Гц 142 | */ 143 | /* 144 | ============= Таблица №1 частот для расширенной генерации ШИМ (PWM_resolution) ============= 145 | _________________________________________________________________________________________________________________________ 146 | |Разрядность, бит |4 |5 |6 |7 |8 |9 |10 |11 |12 |13 |14 |15 |16 | 147 | |___________________|_______|_______|_______|_______|______|________|________|_______|_______|_______|______|______|______| 148 | |Макс. значение duty|15 |31 |63 |127 |255 |511 |1023 |2047 |4095 |8191 |16383 |32767 |65535 | 149 | |___________________|_______|_______|_______|_______|______|________|________|_______|_______|_______|______|______|______| 150 | |Fast | Пины 3, 5 |1 МГц |516 кГц|254 кГц|126 кГц|63 кГц|- |- |- |- |- |- |- |- | 151 | |PWM | 9, 10 |1 МГц |516 кГц|254 кГц|126 кГц|63 кГц|31.2 кГц|15.6 кГц|7.8 кГц|3.9 кГц|1.9 кГц|980 Гц|488 Гц|244 Гц| 152 | |_______|___________|_______|_______|_______|_______|______|________|________|_______|_______|_______|______|______|______| 153 | |Correct| Пины 3, 5 |571 кГц|266 кГц|129 кГц|63 кГц |32 кГц|- |- |- |- |- |- |- |- | 154 | |PWM | 9, 10 |571 кГц|266 кГц|129 кГц|63 кГц |32 кГц|15.7 кГц|7.8 кГц |3.9 кГц|1.9 кГц|976 Гц |488 Гц|244 Гц|122 Гц| 155 | |_______|___________|_______|_______|_______|_______|______|________|________|_______|_______|_______|______|______|______| 156 | */ 157 | // ============ Функции для настройки стандартной генерации ШИМ сигнала (analogWrite) ============ 158 | // Данные функции НЕ убирают один ШИМ выход у 8-ми битных таймеров, можно использовать все 6 ШИМ пинов с настроенной частотой! См. таблицу. 159 | void PWM_prescaler(byte pin, byte mode); 160 | /* PWM_prescaler(пин, режим) - установить предделитель таймера (меняет частоту ШИМ) 161 | - Пин: D3, D5, D6, D9, D10, D11 162 | - Режим: 1-7, см. таблицу частот 163 | */ 164 | void PWM_mode(byte pin, modes mode); 165 | /* PWM_mode(пин, режим) - установить режим генерации ШИМ 166 | - Пин: D3, D5, D6, D9, D10, D11 167 | - Режим: 0 - FastPWM, 1 - Phase-correct, см. таблицу частот 168 | */ 169 | void PWM_TMR1_8BIT(); // Установить таймер 1 (ШИМ на D9 и D10) в режим 8 бит. См. таблицу частот 170 | void PWM_TMR1_10BIT(); // Установить таймер 1 (ШИМ на D9 и D10) в режим 10 бит. См. таблицу частот 171 | /* 172 | ========== Таблица №2 частот для стандартной генерации ШИМ (PWM_prescaler) ========== 173 | 174 | Timer 0 по умолчанию работает в режиме Fast PWM 175 | Timer 1 и 2 по умолчанию работают в режиме Phase-correct 176 | _______________________________________________________________________________________________ 177 | | | Timer0 (пины 5 и 6) 8 bit | Timer 1 (пины 9 и 10) 10 bit | Timer2 (пины 3 и 11) 8 bit| 178 | | | Timer1 (пины 9 и 10) 8 bit| | | 179 | | |___________________________|_______________________________|___________________________| 180 | |mode | Phase-correct | Fast PWM | Phase-correct | Fast PWM | Phase-correct | Fast PWM | 181 | |_______|_______________|___________|___________________|___________|_______________|___________| 182 | |1 | 31.4 kHz | 62.5 kHz | 7.8 kHz | 15.6 kHz | 31.4 kHz | 62.5 kHz | 183 | |2 | 4 kHz | 7.8 kHz | 977 Hz | 2 kHz | 4 kHz | 8 kHz | 184 | |3 | 490 Hz | 976 Hz | 122 Hz | 244 Hz | 980 Hz | 2 kHz | 185 | |4 | 122 Hz | 244 Hz | 30 Hz | 61 Hz | 490 Hz | 980 Hz | 186 | |5 | 30 Hz | 61 Hz | 7.6 Hz | 15 Hz | 245 Hz | 490 Hz | 187 | |6 | - | - | - | - | 122 Hz | 244 Hz | 188 | |7 | - | - | - | - | 30 Hz | 60 Hz | 189 | |_______|_______________|___________|___________________|___________|_______________|___________| 190 | */ 191 | ``` 192 | 193 | 194 | ## Пример 195 | Остальные примеры смотри в **examples**! 196 | ```cpp 197 | #include 198 | 199 | void setup() { 200 | pinMode(3, OUTPUT); 201 | pinMode(5, OUTPUT); 202 | pinMode(9, OUTPUT); 203 | pinMode(10, OUTPUT); 204 | 205 | // Данные функции убирают один ШИМ выход у 8-ми битных таймеров, оставляя нам ШИМ пины D3, D5, D9 и D10 на ATmega328 206 | 207 | PWM_16KHZ_D3(30); // ШИМ 16 кГц на пине D3, заполнение 30 из 255 208 | PWM_20KHZ_D5(50); // ШИМ 20 кГц на пине D5, заполнение 50 из 255. Сломает millis() и delay()! 209 | PWM_16KHZ_D9(760); // ШИМ 16 кГц на пине D9, заполнение 760 из 1023 210 | PWM_16KHZ_D10(800); // ШИМ 16 кГц на пине D10, заполнение 800 из 1023 211 | // пины 9 и 10 работают на одной частоте, запустить на разных не получится 212 | } 213 | 214 | void loop() { 215 | } 216 | ``` 217 | 218 | 219 | ## Версии 220 | - v1.4 221 | - v1.5 - мелкие исправления и оптимизация 222 | - v1.6 - поддержка ATmega168 223 | 224 | 225 | ## Баги и обратная связь 226 | При нахождении багов создавайте **Issue**, а лучше сразу пишите на почту [alex@alexgyver.ru](mailto:alex@alexgyver.ru) 227 | Библиотека открыта для доработки и ваших **Pull Request**'ов! 228 | 229 | 230 | При сообщении о багах или некорректной работе библиотеки нужно обязательно указывать: 231 | - Версия библиотеки 232 | - Какой используется МК 233 | - Версия SDK (для ESP) 234 | - Версия Arduino IDE 235 | - Корректно ли работают ли встроенные примеры, в которых используются функции и конструкции, приводящие к багу в вашем коде 236 | - Какой код загружался, какая работа от него ожидалась и как он работает в реальности 237 | - В идеале приложить минимальный код, в котором наблюдается баг. Не полотно из тысячи строк, а минимальный код 238 | -------------------------------------------------------------------------------- /README_EN.md: -------------------------------------------------------------------------------- 1 | This is an automatic translation, may be incorrect in some places. See sources and examples! 2 | 3 | # Gyverpwm 4 | Library for expanded generation of PWM on Atmega328 (Arduino Uno/Nano/Pro mini ...) 5 | - hardware generation of PWM of customized frequency and discharge 6 | 7 | ## compatibility 8 | Arduino UNO/Nano/Pro mini 9 | 10 | ### Documentation 11 | There is [extended documentation] to the library (https://alexgyver.ru/gyverpwm/) 12 | 13 | ## Content 14 | - [installation] (# Install) 15 | - [initialization] (#init) 16 | - [use] (#usage) 17 | - [Example] (# Example) 18 | - [versions] (#varsions) 19 | - [bugs and feedback] (#fedback) 20 | 21 | 22 | ## Installation 23 | - The library can be found by the name ** gyverpwm ** and installed through the library manager in: 24 | - Arduino ide 25 | - Arduino ide v2 26 | - Platformio 27 | - [download the library] (https://github.com/gyverlibs/gyverpwm/archive/refs/heads/main.zip). Zip archive for manual installation: 28 | - unpack and put in * C: \ Program Files (X86) \ Arduino \ Libraries * (Windows X64) 29 | - unpack and put in * C: \ Program Files \ Arduino \ Libraries * (Windows X32) 30 | - unpack and put in *documents/arduino/libraries/ * 31 | - (Arduino id) Automatic installation from. Zip: * sketch/connect the library/add .Zip library ... * and specify downloaded archive 32 | - 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) 33 | ### Update 34 | - I recommend always updating the library: errors and bugs are corrected in the new versions, as well as optimization and new features are added 35 | - through the IDE library manager: find the library how to install and click "update" 36 | - 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! 37 | 38 | 39 | 40 | ## initialization 41 | No 42 | 43 | 44 | ## Usage 45 | `` `CPP 46 | // =====ward 47 | // these functions remove one PWM output from 8 bit timers, leaving us shim pins D3, D5, D9 and D10 on Atmega328 48 | VOID PWM_FREQUENCY (Byte PIN, LONG FreQ, Modes Correct); 49 | /* Pwm_freqency (pin, frequency, mode) - start the shim with the selected frequency 50 | - Pins: D3 (timer 2), d5 (timer 0 - will break millis/delay), D9 and D10 (timer 1) 51 | - mode: 0 (fast_pwm), 1 (Correct_PWM) 52 | - Frequency: 250-200'000 Hz for all timers 53 | - To change the filling, use pwm_se 54 | - The bit in this mode is given to 8 bits, in fact, the steps of the change are different! 55 | */ 56 | VOID PWM_RESOLUTION (Byte PIN, Byte Res, Modes Correct); 57 | /* Pwm_resolution (pin, discharge, mode) - start the PWM with the selected bit 58 | - Pins: D3 (timer 2), d5 (timer 0 - will break millis/delay), D9 and D10 (timer 1) 59 | - mode: 0 (fast_pwm), 1 (Correct_PWM) 60 | -Resolution: D3 (4-8 bits), D5 (4-8 bits), D9 and D10 (4-16 bits) 61 | - the frequency in this mode is automatically maximum according to the capabilities of the timer (see table) 62 | - To change the filling, use pwm_se 63 | - the limits of filling for different discharge are indicated in the table 64 | */ 65 | VOID PWM_SET (Byte PIN, UNSIGNED inti); 66 | /* Pwm_seet (pin, filling) - change the filling on the selected pin 67 | - PIN: D3, D5, D6,D9, D10, D11 68 | - Filling: depends on the permission and the regime (see table) 69 | - when using pwm_frequency, the discharge is 8 bits (0-255) 70 | - When using PWM_Resolution Max.The value of the filling is equal (2^discharge - 1), also look at the table 71 | */ 72 | VOID pwm_detach (byte pin);// Disaches the PWM on the selected pin (allows you to use digital read/WRITE) 73 | VOID pwm_attach (byte pin);// connects Shim on the selected pin (with the last settings) 74 | VOID pwm_default (byte pin);// Reset settings corresponding to Pin Tiemer on "Standard" for Arduino 75 | VOID PWM_16KHZ_D3 (Byte Duty); 76 | /* Launch PWM with a frequency of 16 kHz on pin D3 77 | - cancels PWM_FREQUENCY/PWM_RESOLATION settings 78 | - discharge is given to 8 bits (filling 0-255) 79 | - Filling changes itself (you do not need to call pwm_seet) */ 80 | VOID PWM_20KHZ_D3 (Byte Duty); 81 | /* Launch of PWM with a frequency of 20 kHz on pin D3 82 | - cancels PWM_FREQUENCY/PWM_RESOLATION settings 83 | - discharge is given to 8 bits (filling 0-255) 84 | - Filling changes itself (you do not need to call pwm_seet) */ 85 | VOID PWM_16KHZ_D5 (Byte Duty); 86 | /* Launch PWM with a frequency of 16 kHz on pin D5 87 | - cancels PWM_FREQUENCY/PWM_RESOLATION settings 88 | - discharge is given to 8 bits (filling 0-255) 89 | - Filling changes itself (you do not need to call pwm_seet) */ 90 | VOID PWM_20KHZ_D5 (Byte Duty); 91 | /* Launch PWM with a frequency of 20 kHz on pin D5 92 | - cancels PWM_FREQUENCY/PWM_RESOLATION settings 93 | - discharge is given to 8 bits (filling 0-255) 94 | - Filling changes itself (you do not need to call pwm_seet) */ 95 | VOID PWM_16KHZ_D9 (inti); 96 | /* Launch of PWM with a frequency of 16 kHz (15.6 kHz) on pin D9 97 | - cancels PWM_FREQUENCY/PWM_RESOLATION settings 98 | - Disgusting of exactly 10 bits (filling 0-1023) 99 | - Filling changes itself (you do not need to call pwm_seet) */ 100 | VOID PWM_20KHZ_D9 (inti); 101 | /* Launch PWM with a frequency of 20 kHz on pin D9 102 | - cancels PWM_FREQUENCY/PWM_RESOLATION settings 103 | - discharge is given to 10 bits (filling 0-1023) 104 | - Filling changes itself (you do not need to call pwm_seet) */ 105 | VOID PWM_16KHZ_D10 (inti); 106 | /* Launch of PWM with a frequency of 16 kHz (15.6 kHz) on pin D10 107 | - cancels PWM_FREQUENCY/PWM_RESOLATION settings 108 | - Disgusting of exactly 10 bits (filling 0-1023) 109 | - Filling changes itself (you do not need to call pwm_seet) */ 110 | VOID PWM_20KHZ_D10 (inti); 111 | /* Launch PWM with a frequency of 20 kHz on pin D10 112 | - cancels PWM_FREQUENCY/PWM_RESOLATION settings 113 | - discharge is given to 10 bits (filling 0-1023) 114 | - Filling changes itself (you do not need to call pwm_seet) */ 115 | 116 | Float PWM_SQUARE_D9 (Float Frequency); 117 | /* Meander generator (square wave) on pin D9 118 | Frequency from 2 Hz to 8 MHz, the frequency step depends on the frequency 119 | (Starting from 0.01 Hz and ending with dozens of kHz !!!) 120 | You can turn off by calling pwm_detach (9); 121 | To reset the timer into a default mode - pwm_default (9); 122 | Returns the established frequency in Herza! 123 | 124 | Frequency error 125 | 300 Hz 0.01 Hz 126 | 700 Hz 0.05 Hz 127 | 900 Hz 0.1 Hz 128 | 2 kHz 0.5 Hz 129 | 3 kHz 1 Hz 130 | 4 kHz 2 Hz 131 | 9 kHz 10 Hz 132 | 20 kHz 50 Hz 133 | 30 kHz 110 Hz 134 | 63 kHz 500 Hz 135 | 90 kHz 1000 Hz 136 | */ 137 | /* 138 | ==========ward 139 | _____________________________________________________________________________________________________________ 140 | | Disgusting, bit | 4 | 5 | 6 | 7 | 8 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 141 | | ___________________ | _______ | _______ | _______ | _______ | ______ | ________ | ________ | _______ | _______ | _______ | ______ | ______ | ______ | 142 | | Max.Duty value | 15 | 31 | 63 | 127 | 255 | 511 | 1023 | 2047 | 4095 | 8191 | 16383 | 32767 | 65535 | 143 | | ___________________ | _______ | _______ | _______ | _______ | ______ | ________ | ________ | _______ | _______ | _______ | ______ | ______ | ______ | 144 | | Fast |Pins 3, 5 | 1 MHz | 516 kHz | 254 kHz | 126 kHz | 63 kHz |- |- |- |- |- |- |- |- | 145 | | Pwm |9, 10 | 1 MHz | 516 kHz | 254 kHz | 126 kHz | 63 kHz | 31.2 kHz | 15.6 kHz | 7.8 kHz | 3.9 kHz | 1.9 kHz | 980 Hz | 488 Hz |244 Hz | 146 | | _______ | ___________ | _______ | _______ | _______ | _______ | ______ | ________ | ________ | _______ | _______ | _______ | ______ | ______ | ______ | 147 | | Correct |Pines 3, 5 | 571 kHz | 266 kHz | 129 kHz | 63 kHz | 32 kHz |- |- |- |- |- |- |- |- | 148 | | Pwm |9, 10 | 571 kHz | 266 kHz | 129 kHz | 63 kHz | 32 kHz | 15.7 kHz | 7.8 kHz | 3.9 kHz | 1.9 kHz | 976 Hz | 488 Hz | 244 Hz | 122 Hz | 149 | | _______ | ___________ | _______ | _______ | _______ | _______ | ______ | ________ | ________ | _______ | _______ | _______ | ______ | ______ | ______ | 150 | */ 151 | // ==ward 152 | // These functions do not remove one PWM output from 8 bit timers, you can use all 6 PIM Pinov with a configured frequency!See table. 153 | VOID PWM_PRESCALER (Byte PIN, Byte Mode); 154 | /* PWM_PRESCALER (PIN, mode) - set the Tiemer Premier (changes the frequency of PWM) 155 | - PIN: D3, D5, D6, D9, D10, D11 156 | - mode: 1-7, see the frequency table 157 | */ 158 | VOID pwm_mode (byte pin, modes mode); 159 | /* Pwm_mode (pin, mode) - set the generation mode of the PWM 160 | - PIN: D3, D5, D6, D9, D10, D11 161 | - mode: 0 - Fastpwm, 1 - Phase -Correct, see the frequency table 162 | */ 163 | VOID PWM_TMR1_8BIT ();// Install the timer 1 (PWM on D9 and D10) in mode 8 bits.See the frequency table 164 | VOID PWM_TMR1_10BIT ();// Install the timer 1 (Shim on D9 and D10) in mode 10 bits.See the frequency table 165 | /* 166 | =======ward 167 | 168 | Timer 0 by default operates in FAST PWM mode 169 | Timer 1 and 2 by default work in Phase-Correct mode 170 | _______________________________________________________________________________________ 171 | ||Timer0 (Pines 5 and 6) 8 Bit |Timer 1 (Pines 9 and 10) 10 Bit |Timer2 (Pins 3 and 11) 8 Bit | 172 | ||Timer1 (Pins 9 and 10) 8 Bit ||| 173 | || ________________ ( 174 | | Mode |Phase-Correct |FAST PWM |Phase-Correct |FAST PWM |Phase-Correct |FAST PWM | 175 | | _______ | _______________ | ___________ | _____________________ | _____________ | _________________ | ___________ | 176 | | 1 |31.4 khz |62.5 KHZ |7.8 khz |15.6 khz |31.4 khz |62.5 KHZ | 177 | | 2 |4 khz |7.8 khz |977 Hz |2 khz |4 khz |8 khz | 178 | | 3 |490 Hz |976 Hz |122 Hz |244 Hz |980 Hz |2 khz | 179 | | 4 |122 Hz |244 Hz |30 Hz |61 Hz |490 Hz |980 Hz | 180 | | 5 |30 Hz |61 Hz |7.6 Hz |15 Hz |245 Hz |490 Hz | 181 | | 6 |- |- |- |- |122 Hz |244 Hz | 182 | | 7 |- |- |- |- |30 Hz |60 Hz | 183 | | _______ | _______________ | ___________ | _____________________ | _____________ | _________________ | ___________ | 184 | */ 185 | `` ` 186 | 187 | 188 | ## Example 189 | The rest of the examples look at ** Examples **! 190 | `` `CPP 191 | #include 192 | 193 | VOID setup () { 194 | Pinmode (3, output); 195 | Pinmode (5, output); 196 | Pinmode (9, output); 197 | Pinmode (10, output); 198 | 199 | // these functions remove one PWM output from 8 bit timers, leaving us shim pins D3, D5, D9 and D10 on Atmega328 200 | 201 | PWM_16KHZ_D3 (30);// SHIM 16 kHz on pin D3, filling 30 out of 255 202 | PWM_20KHZ_D5 (50);// PWM 20 kHz on pin D5, filling 50 out of 255. Millis () and delay () will break! 203 | PWM_16KHZ_D9 (760);// SHIM 16 kHz on pin D9, filling 760 out of 1023 204 | PWM_16KHZ_D10 (800);// SHIM 16 kHz on pin D10, filling 800 out of 1023 205 | // Pins 9 and 10 work at the same frequency, starting on different ones will not work 206 | } 207 | 208 | VOID loop () { 209 | } 210 | `` ` 211 | 212 | 213 | ## versions 214 | - V1.4 215 | - V1.5 - Small corrections and optimization 216 | - V1.6 - support atmega168 217 | 218 | 219 | ## bugs and feedback 220 | Create ** Issue ** when you find the bugs, and better immediately write to the mail [alex@alexgyver.ru] (mailto: alex@alexgyver.ru) 221 | The library is open for refinement and your ** pull Request ** 'ow! 222 | 223 | 224 | Under the messageCranberries about bugs or incorrect work of the library must be indicated: 225 | - The version of the library 226 | - What is MK used 227 | - SDK version (for ESP) 228 | - version of Arduino ide 229 | - whether the built -in examples work correctly, in which the functions and designs are used, leading to a bug in your code 230 | - what code has been loaded, what work was expected from it and how it works in reality 231 | - Ideally, attach the minimum code in which the bug is observed.Not a canvas of a thousand lines, but a minimum code -------------------------------------------------------------------------------- /docs/customPWM.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GyverLibs/GyverPWM/06de6ab268e60af2bb97876bf8413c29c6824ca3/docs/customPWM.xlsx -------------------------------------------------------------------------------- /docs/defaultPWM.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GyverLibs/GyverPWM/06de6ab268e60af2bb97876bf8413c29c6824ca3/docs/defaultPWM.xlsx -------------------------------------------------------------------------------- /docs/Погрешность меандра до 1 кГц.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GyverLibs/GyverPWM/06de6ab268e60af2bb97876bf8413c29c6824ca3/docs/Погрешность меандра до 1 кГц.jpg -------------------------------------------------------------------------------- /docs/Погрешность меандра до 10 кГц.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GyverLibs/GyverPWM/06de6ab268e60af2bb97876bf8413c29c6824ca3/docs/Погрешность меандра до 10 кГц.jpg -------------------------------------------------------------------------------- /docs/Погрешность меандра до 100 кГц.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GyverLibs/GyverPWM/06de6ab268e60af2bb97876bf8413c29c6824ca3/docs/Погрешность меандра до 100 кГц.jpg -------------------------------------------------------------------------------- /docs/Погрешность меандра до 1000 кГц.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GyverLibs/GyverPWM/06de6ab268e60af2bb97876bf8413c29c6824ca3/docs/Погрешность меандра до 1000 кГц.jpg -------------------------------------------------------------------------------- /docs/Погрешность меандра.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GyverLibs/GyverPWM/06de6ab268e60af2bb97876bf8413c29c6824ca3/docs/Погрешность меандра.xlsx -------------------------------------------------------------------------------- /examples/PWMdefFrequency/PWMdefFrequency.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void setup() { 4 | pinMode(3, OUTPUT); 5 | pinMode(5, OUTPUT); 6 | pinMode(9, OUTPUT); 7 | pinMode(10, OUTPUT); 8 | 9 | // Данные функции НЕ УБИРАЮТ один ШИМ выход у 8-ми битных таймеров, оставляя нам ШИМ пины D3, D5, D9 и D10 на ATmega328 10 | 11 | PWM_prescaler(3, 1); // установить частоту ШИМ на пине D3 равной 31.4 кГц (см. таблицу №2 в GyverPWM.h) 12 | // частота автоматически будет установлена для пина D11! 13 | 14 | PWM_prescaler(6, 2); // установить частоту ШИМ на пине D6 равной 7.8 кГц (см. таблицу №2 в GyverPWM.h) 15 | // частота автоматически будет установлена для пина D5! Также это сломает millis() и delay() 16 | 17 | PWM_prescaler(9, 1); // установить частоту ШИМ на пине D9 равной 7.8 кГц (см. таблицу №2 в GyverPWM.h) 18 | // частота автоматически будет установлена для пина D10! 19 | 20 | PWM_mode(9, 1); // установить режим работы таймера 1 в Fast PWM. Частота будет 15.6 кГц (см. таблицу №2 в GyverPWM.h) 21 | // режим автоматически будет установлен для пина D10! 22 | } 23 | 24 | void loop() { 25 | // можем пользоваться ШИМом на всех 6-ти пинах! 26 | analogWrite(3, 123); 27 | analogWrite(5, 241); 28 | analogWrite(6, 26); 29 | analogWrite(9, 98); 30 | analogWrite(10, 165); 31 | analogWrite(11, 152); 32 | } 33 | -------------------------------------------------------------------------------- /examples/PWMfrequency/PWMfrequency.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void setup() { 4 | pinMode(3, OUTPUT); 5 | pinMode(5, OUTPUT); 6 | pinMode(9, OUTPUT); 7 | pinMode(10, OUTPUT); 8 | 9 | // Данные функции убирают один ШИМ выход у 8-ми битных таймеров, оставляя нам ШИМ пины D3, D5, D9 и D10 на ATmega328 10 | 11 | // запустить ШИМ на D3 с частотой 66.666 Гц, режим FAST_PWM 12 | PWM_frequency(3, 66666, FAST_PWM); 13 | 14 | // запустить ШИМ на D5 с частотой 25'000 Гц, режим CORRECT_PWM. Сломает millis()! 15 | PWM_frequency(5, 25000, CORRECT_PWM); 16 | 17 | // запустить ШИМ на D9 с частотой 150'000 Гц, режим FAST_PWM 18 | PWM_frequency(9, 150000, FAST_PWM); 19 | 20 | // запустить ШИМ на D10 с частотой 150'000 Гц, режим FAST_PWM 21 | PWM_frequency(10, 150000, FAST_PWM); 22 | // пины 9 и 10 работают на одной частоте, запустить на разных не получится! 23 | } 24 | 25 | void loop() { 26 | PWM_set(3, analogRead(0) / 4); // заполнение регулируем потенциометром на А0 (8 бит) 27 | PWM_set(5, analogRead(0) / 4); // заполнение регулируем потенциометром на А0 (8 бит) 28 | 29 | PWM_set(9, analogRead(0) / 4); // заполнение регулируем потенциометром на А0 (8 бит) 30 | PWM_set(10, 255 - analogRead(0) / 4); // заполнение регулируем потенциометром на А0 (8 бит) 31 | } 32 | -------------------------------------------------------------------------------- /examples/PWMresolution/PWMresolution.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void setup() { 4 | pinMode(3, OUTPUT); 5 | pinMode(5, OUTPUT); 6 | pinMode(9, OUTPUT); 7 | pinMode(10, OUTPUT); 8 | 9 | // Данные функции убирают один ШИМ выход у 8-ми битных таймеров, оставляя нам ШИМ пины D3, D5, D9 и D10 на ATmega328 10 | 11 | // запустить ШИМ на D3, разрядность 4 бита (0-15), частота 1 МГц (см. таблицу №1 в GyverPWM.h), режим FAST_PWM 12 | PWM_resolution(3, 4, FAST_PWM); 13 | 14 | // запустить ШИМ на D5, разрядность 6 бит (0-63), частота 254 кГц (см. таблицу №1 в GyverPWM.h), режим FAST_PWM. Сломает millis()! 15 | PWM_resolution(5, 6, FAST_PWM); 16 | 17 | // запустить ШИМ на D9, разрядность 12 бит (0-4095), частота 3.9 кГц (см. таблицу №1 в GyverPWM.h), режим FAST_PWM 18 | PWM_resolution(9, 12, FAST_PWM); 19 | 20 | // запустить ШИМ на D10, разрядность 12 бит (0-4095), частота 3.9 кГц (см. таблицу №1 в GyverPWM.h), режим FAST_PWM 21 | PWM_resolution(10, 12, FAST_PWM); 22 | // пины 9 и 10 работают на одной разрядности, запустить на разных не получится! 23 | } 24 | 25 | void loop() { 26 | PWM_set(3, 3); // установить заполнение ШИМ на D3, равное 3 из 15, частота 1 МГц (см. таблицу №1 в GyverPWM.h) 27 | PWM_set(5, 40); // установить заполнение ШИМ на D5, равное 40 из 63, частота 254 кГц (см. таблицу №1 в GyverPWM.h) 28 | PWM_set(9, 2842); // установить заполнение ШИМ на D9, равное 2842 из 4095, частота 3.9 кГц (см. таблицу №1 в GyverPWM.h) 29 | PWM_set(10, 1248); // установить заполнение ШИМ на D10, равное 1248 из 4095, частота 3.9 кГц (см. таблицу №1 в GyverPWM.h) 30 | } 31 | -------------------------------------------------------------------------------- /examples/PWMtest/PWMtest.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void setup() { 4 | pinMode(3, OUTPUT); 5 | pinMode(5, OUTPUT); 6 | pinMode(9, OUTPUT); 7 | pinMode(10, OUTPUT); 8 | 9 | // Данные функции убирают один ШИМ выход у 8-ми битных таймеров, оставляя нам ШИМ пины D3, D5, D9 и D10 на ATmega328 10 | 11 | PWM_16KHZ_D3(30); // ШИМ 16 кГц на пине D3, заполнение 30 из 255 12 | PWM_20KHZ_D5(50); // ШИМ 20 кГц на пине D5, заполнение 50 из 255. Сломает millis() и delay()! 13 | PWM_16KHZ_D9(760); // ШИМ 16 кГц на пине D9, заполнение 760 из 1023 14 | PWM_16KHZ_D10(800); // ШИМ 16 кГц на пине D10, заполнение 800 из 1023 15 | // пины 9 и 10 работают на одной частоте, запустить на разных не получится 16 | } 17 | 18 | void loop() { 19 | } 20 | -------------------------------------------------------------------------------- /examples/squareTest/squareTest.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void setup() { 4 | pinMode(9, OUTPUT); 5 | PWM_square_D9(78.65); 6 | } 7 | 8 | void loop() { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For GyverPWM 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | GyverPWM KEYWORD1 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | 15 | PWM_default KEYWORD2 16 | PWM_frequency KEYWORD2 17 | PWM_resolution KEYWORD2 18 | PWM_set KEYWORD2 19 | PWM_detach KEYWORD2 20 | PWM_attach KEYWORD2 21 | 22 | PWM_16KHZ_D3 KEYWORD2 23 | PWM_20KHZ_D3 KEYWORD2 24 | PWM_16KHZ_D5 KEYWORD2 25 | PWM_20KHZ_D5 KEYWORD2 26 | PWM_16KHZ_D9 KEYWORD2 27 | PWM_20KHZ_D9 KEYWORD2 28 | PWM_16KHZ_D10 KEYWORD2 29 | PWM_20KHZ_D10 KEYWORD2 30 | 31 | PWM_square_D9 KEYWORD2 32 | 33 | PWM_prescaler KEYWORD2 34 | PWM_mode KEYWORD2 35 | PWM_TMR1_8BIT KEYWORD2 36 | PWM_TMR1_10BIT KEYWORD2 37 | 38 | 39 | ####################################### 40 | # Constants (LITERAL1) 41 | ####################################### 42 | 43 | CORRECT_PWM LITERAL1 44 | FAST_PWM LITERAL1 -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=GyverPWM 2 | version=1.6 3 | author=AlexGyver 4 | maintainer=AlexGyver 5 | sentence=Library for advanced PWM settings of AVR 6 | paragraph=Library for advanced PWM settings of AVR 7 | category=Signal Input/Output 8 | url=https://github.com/GyverLibs/GyverPWM 9 | architectures=avr -------------------------------------------------------------------------------- /src/GyverPWM.cpp: -------------------------------------------------------------------------------- 1 | #include "GyverPWM.h" 2 | 3 | static bool isDefault[3] = {true, true, true}; // Массив default - флагов 4 | static bool isMapping[3] = {false, false, false}; // Массив map - флагов 5 | 6 | /* Функция быстрой установки состояния пина */ 7 | void PIN_set(uint8_t pin, uint8_t x) { 8 | if (pin < 8) bitWrite(PORTD, pin, x); 9 | else if (pin < 14) bitWrite(PORTB, (pin - 8), x); 10 | else if (pin < 20) bitWrite(PORTC, (pin - 14), x); 11 | } 12 | 13 | /* Установка параметров таймера по умолчанию */ 14 | void PWM_default(uint8_t pin) { 15 | PWM_detach(pin); 16 | PIN_set(pin, LOW); 17 | switch (pin) { 18 | case 6: // Timer0 - A 19 | case 5: // Timer0 - B 20 | isDefault[0] = true; 21 | isMapping[0] = false; 22 | TCCR0A = TCCR0B = 0b11; 23 | break; 24 | 25 | case 9: // Timer1 - A 26 | case 10: // Timer1 - B 27 | isMapping[1] = false; 28 | TCCR1A = 0b01; 29 | TCCR1B = 0b11; 30 | break; 31 | 32 | case 11: // Timer2 - A 33 | case 3: // Timer2 - B 34 | isDefault[2] = true; 35 | isMapping[2] = false; 36 | TCCR2A = TCCR2B = 0b11; 37 | break; 38 | } 39 | } 40 | 41 | /* Установка частоты ШИМ сигнала на указанном пине (настраивает таймер) */ 42 | void PWM_frequency(uint8_t pin, uint32_t frequency, uint8_t correct) { 43 | frequency = constrain(frequency, 250, 200000); // Ограничиваем частоты 44 | PWM_detach(pin); // Детачим таймер 45 | PIN_set(pin, LOW); // Переводим пин в LOW 46 | 47 | switch (pin) { 48 | case 3: // Timer2 - B 49 | isDefault[2] = false; // Ставим флаги 50 | isMapping[2] = true; 51 | if (correct) { 52 | TCCR2A = 1 << WGM20; // Phase correct режим 53 | if (frequency > MIN_PWMFREQ_CORRECT(1)) { // Выбираем предделитель 54 | TCCR2B = (1 << WGM22) | 0b001; OCR2A = (F_CPU / 2UL) / (frequency * 1UL); // Настраиваем делитель + считаем TOP 55 | } else if (frequency > MIN_PWMFREQ_CORRECT(8)) { 56 | TCCR2B = (1 << WGM22) | 0b010; OCR2A = (F_CPU / 2UL) / (frequency * 8UL); 57 | } else if (frequency > MIN_PWMFREQ_CORRECT(32)) { 58 | TCCR2B = (1 << WGM22) | 0b011; OCR2A = (F_CPU / 2UL) / (frequency * 32UL); 59 | } else if (frequency > MIN_PWMFREQ_CORRECT(64)) { 60 | TCCR2B = (1 << WGM22) | 0b100; OCR2A = (F_CPU / 2UL) / (frequency * 64UL); 61 | } else if (frequency > MIN_PWMFREQ_CORRECT(128)) { 62 | TCCR2B = (1 << WGM22) | 0b101; OCR2A = (F_CPU / 2UL) / (frequency * 128UL); 63 | } else if (frequency > MIN_PWMFREQ_CORRECT(256)) { 64 | TCCR2B = (1 << WGM22) | 0b110; OCR2A = (F_CPU / 2UL) / (frequency * 256UL); 65 | } 66 | } else { 67 | TCCR2A = 1 << WGM20 | 1 << WGM21; // Fast PWM режим 68 | if (frequency > MIN_PWMFREQ_FAST(1)) { // Выбираем предделитель 69 | TCCR2B = (1 << WGM22) | 0b001; OCR2A = (F_CPU / (frequency * 1UL)) - 1; // Настраиваем делитель + считаем TOP 70 | } else if (frequency > MIN_PWMFREQ_FAST(8)) { 71 | TCCR2B = (1 << WGM22) | 0b010; OCR2A = (F_CPU / (frequency * 8UL)) - 1; 72 | } else if (frequency > MIN_PWMFREQ_FAST(32)) { 73 | TCCR2B = (1 << WGM22) | 0b011; OCR2A = (F_CPU / (frequency * 32UL)) - 1; 74 | } else if (frequency > MIN_PWMFREQ_FAST(64)) { 75 | TCCR2B = (1 << WGM22) | 0b100; OCR2A = (F_CPU / (frequency * 64UL)) - 1; 76 | } else if (frequency > MIN_PWMFREQ_FAST(128)) { 77 | TCCR2B = (1 << WGM22) | 0b101; OCR2A = (F_CPU / (frequency * 128UL)) - 1; 78 | } else if (frequency > MIN_PWMFREQ_FAST(256)) { 79 | TCCR2B = (1 << WGM22) | 0b110; OCR2A = (F_CPU / (frequency * 256UL)) - 1; 80 | } 81 | } break; 82 | 83 | case 5: // Timer0 - B 84 | isDefault[0] = false; 85 | isMapping[0] = true; 86 | if (correct) { 87 | TCCR0A = 1 << WGM00; 88 | if (frequency > MIN_PWMFREQ_CORRECT(1)) { 89 | TCCR0B = (1 << WGM02) | 0b001; OCR0A = (F_CPU / 2UL) / (frequency * 1UL); 90 | } else if (frequency > MIN_PWMFREQ_CORRECT(8)) { 91 | TCCR0B = (1 << WGM02) | 0b010; OCR0A = (F_CPU / 2UL) / (frequency * 8UL); 92 | } else if (frequency > MIN_PWMFREQ_CORRECT(64)) { 93 | TCCR0B = (1 << WGM02) | 0b011; OCR0A = (F_CPU / 2UL) / (frequency * 64UL); 94 | } else if (frequency > MIN_PWMFREQ_CORRECT(256)) { 95 | TCCR0B = (1 << WGM02) | 0b100; OCR0A = (F_CPU / 2UL) / (frequency * 256UL); 96 | } 97 | } else { 98 | TCCR0A = 1 << WGM00 | 1 << WGM01; 99 | if (frequency > MIN_PWMFREQ_FAST(1)) { 100 | TCCR0B = (1 << WGM02) | 0b001; OCR0A = (F_CPU / (frequency * 1UL)) - 1; 101 | } else if (frequency > MIN_PWMFREQ_FAST(8)) { 102 | TCCR0B = (1 << WGM02) | 0b010; OCR0A = (F_CPU / (frequency * 8UL)) - 1; 103 | } else if (frequency > MIN_PWMFREQ_FAST(64)) { 104 | TCCR0B = (1 << WGM02) | 0b011; OCR0A = (F_CPU / (frequency * 64UL)) - 1; 105 | } else if (frequency > MIN_PWMFREQ_FAST(256)) { 106 | TCCR0B = (1 << WGM02) | 0b100; OCR0A = (F_CPU / (frequency * 256UL)) - 1; 107 | } 108 | } break; 109 | 110 | case 9: // Timer1 - A 111 | case 10: // Timer1 - B 112 | isMapping[1] = true; 113 | if (correct) { 114 | TCCR1A = 1 << WGM11; // Phase correct режим 115 | TCCR1B = 1 << WGM13 | 0b001; // Для таймера 1 делитель всегда 1 116 | ICR1 = F_CPU / (frequency * 2UL); // Считаем 117 | } else { 118 | TCCR1A = 1 << WGM11; // Fast PWM режим 119 | TCCR1B = 1 << WGM13 | 1 << WGM12 | 0b001; 120 | ICR1 = (F_CPU / frequency) - 1; // Считаем 121 | } break; 122 | } 123 | } 124 | 125 | /* Установка разрешения ШИМ сигнала на указанном пине (настраивает таймер) */ 126 | void PWM_resolution(uint8_t pin, uint8_t resolution, uint8_t correct) { 127 | PWM_detach(pin); // Детачим таймер 128 | PIN_set(pin, LOW); // Переводим пин в LOW 129 | 130 | switch (pin) { 131 | case 3: // Timer2 - B 132 | isDefault[2] = isMapping[2] = false; // Ставим флаги 133 | TCCR2A = correct ? (1 << WGM20) : (1 << WGM20 | 1 << WGM21); // Выбираем Fast PWM или Phase correct 134 | TCCR2B = 1 << WGM22 | 1 << CS20; 135 | OCR2A = (1 << constrain(resolution, 4, 8)) - 1; // Устанавливаем top с ограничением 136 | break; 137 | 138 | case 5: // Timer0 - B 139 | isDefault[0] = isMapping[0] = false; 140 | TCCR0A = correct ? (1 << WGM00) : (1 << WGM00 | 1 << WGM01); 141 | TCCR0B = 1 << WGM02 | 1 << CS00; 142 | OCR0A = (1 << constrain(resolution, 4, 8)) - 1; 143 | break; 144 | 145 | case 9: // Timer1 - A 146 | case 10: // Timer1 - B 147 | isMapping[1] = false; 148 | TCCR1A = 1 << WGM11; 149 | TCCR1B = (correct ? (1 << WGM13) : (1 << WGM13 | 1 << WGM12)) | 1 << CS10; 150 | ICR1 = (1 << constrain(resolution, 4, 16)) - 1; 151 | break; 152 | } 153 | } 154 | 155 | /* Установка заполнения ШИМ сигнала на указанном пине */ 156 | void PWM_set(uint8_t pin, uint16_t duty) { 157 | if (!duty) { // Если заполнение 0 - детачим пин и в LOW 158 | PWM_detach(pin); 159 | PIN_set(pin, LOW); 160 | return; 161 | } 162 | 163 | switch (pin) { 164 | case 3: // Timer2 - B 165 | if (isMapping[2]) duty = constrain(map(duty, 0, 255, 0, OCR2A), 0, OCR2A); // Масштабируем если нужно 166 | if (duty == OCR2A){ PWM_detach(pin); PIN_set(pin, HIGH);} // Если макс. значение - детачим и в HIGH 167 | else {PWM_attach(pin); OCR2B = duty;} // Иначе аттачим и выводим заполнение 168 | break; 169 | 170 | case 5: // Timer0 - B 171 | if (isMapping[0]) duty = constrain(map(duty, 0, 255, 0, OCR0A), 0, OCR0A); 172 | if (duty == OCR0A){ PWM_detach(pin); PIN_set(pin, HIGH);} 173 | else {PWM_attach(pin); OCR0B = duty;} 174 | break; 175 | 176 | case 6: // Timer0 - A 177 | if (isDefault[0]) { 178 | if (duty == 255){ PWM_detach(pin); PIN_set(pin, HIGH);} 179 | else {PWM_attach(pin); OCR0A = duty;} 180 | } break; 181 | 182 | case 9: // Timer1 - A 183 | if (isMapping[1]) duty = constrain(map(duty, 0, 255, 0, ICR1), 0, ICR1); 184 | if (duty == ICR1){ PWM_detach(pin); PIN_set(pin, HIGH);} 185 | else {PWM_attach(pin); OCR1A = duty;} 186 | break; 187 | 188 | case 10: // Timer1 - B 189 | if (isMapping[1]) duty = constrain(map(duty, 0, 255, 0, ICR1), 0, ICR1); 190 | if (duty == ICR1){ PWM_detach(pin); PIN_set(pin, HIGH);} 191 | else {PWM_attach(pin); OCR1B = duty;} 192 | break; 193 | 194 | case 11: // Timer2 - A 195 | if (isDefault[2]) { 196 | if (duty == 255){ PWM_detach(pin); PIN_set(pin, HIGH);} 197 | else {PWM_attach(pin); OCR2A = duty;} 198 | } break; 199 | } 200 | } 201 | 202 | /* Отключение пина от таймера */ 203 | void PWM_detach(uint8_t pin) { 204 | switch (pin) { // Выбираем пин 205 | case 3: bitClear(TCCR2A, COM2B1); break; // Сбрасываем нужный бит таймера 206 | case 5: bitClear(TCCR0A, COM0B1); break; 207 | case 6: bitClear(TCCR0A, COM0A1); break; 208 | case 9: bitClear(TCCR1A, COM1A1); break; 209 | case 10: bitClear(TCCR1A, COM1B1); break; 210 | case 11: bitClear(TCCR2A, COM2A1); break; 211 | } 212 | } 213 | 214 | /* Подключение пина к таймеру */ 215 | void PWM_attach(uint8_t pin) { 216 | switch (pin) { // Выбираем пин 217 | case 3: bitSet(TCCR2A, COM2B1); break; // Ставим нужный бит таймера 218 | case 5: bitSet(TCCR0A, COM0B1); break; 219 | case 6: bitSet(TCCR0A, COM0A1); break; 220 | case 9: bitSet(TCCR1A, COM1A1); break; 221 | case 10: bitSet(TCCR1A, COM1B1); break; 222 | case 11: bitSet(TCCR2A, COM2A1); break; 223 | } 224 | } 225 | 226 | /* Установка делителя таймера */ 227 | void PWM_prescaler(uint8_t pin, uint8_t prescaler) { // 228 | switch (pin) { 229 | case 5: 230 | case 6: TCCR0B = TCCR0B & 0xF8 | prescaler; break; 231 | case 9: 232 | case 10: TCCR1B = TCCR1B & 0xF8 | prescaler; break; 233 | case 3: 234 | case 11: TCCR2B = TCCR2B & 0xF8 | prescaler; break; 235 | } 236 | } 237 | 238 | /* Установка режима таймера */ 239 | void PWM_mode(uint8_t pin, uint8_t mode) { 240 | switch (pin) { 241 | case 5: 242 | case 6: TCCR0A = TCCR0A & 0xFC | (mode ? 0b01 : 0b11); break; 243 | case 9 : 244 | case 10 : TCCR1B = TCCR1B & 0xF7 | (mode ? 0 : 1 << WGM12); break; 245 | case 3 : 246 | case 11 : TCCR2A = TCCR2A & 0xFC | (mode ? 0b01 : 0b11); break; 247 | } 248 | } 249 | 250 | /* Установка режима 8 бит таймеру 1 */ 251 | void PWM_TMR1_8BIT() { 252 | TCCR1A = TCCR1A & 0xE0 | (1 << WGM10); 253 | } 254 | 255 | /* Установка режима 10 бит таймеру 1 */ 256 | void PWM_TMR1_10BIT() { 257 | TCCR1A = TCCR1A & 0xE0 | (1 << WGM10 | 1 << WGM11); 258 | } 259 | 260 | /* ШИМ 16 кГц "8 Бит" на пине 3 */ 261 | void PWM_16KHZ_D3(uint8_t duty) { 262 | TCCR2A = 1 << COM2B1 | 1 << WGM21 | 1 << WGM20; 263 | TCCR2B = (1 << WGM22) | 0b010; 264 | OCR2A = (F_CPU / (16000UL * 8)) - 1; 265 | if (duty == 0) { 266 | PWM_detach(3); 267 | PIN_set(3, LOW); 268 | } else { 269 | PWM_attach(3); 270 | OCR2B = map(duty, 0, 255, 0, OCR2A); 271 | } 272 | } 273 | 274 | /* ШИМ 20 кГц "8 Бит" на пине 3 */ 275 | void PWM_20KHZ_D3(uint8_t duty) { 276 | TCCR2A = 1 << COM2B1 | 1 << WGM21 | 1 << WGM20; 277 | TCCR2B = (1 << WGM22) | 0b010; 278 | OCR2A = (F_CPU / (20000UL * 8)) - 1; 279 | if (duty == 0) { 280 | PWM_detach(3); 281 | PIN_set(3, LOW); 282 | } else { 283 | PWM_attach(3); 284 | OCR2B = map(duty, 0, 255, 0, OCR2A); 285 | } 286 | } 287 | 288 | /* ШИМ 16 кГц "8 Бит" на пине 5 */ 289 | void PWM_16KHZ_D5(uint8_t duty) { 290 | TCCR0A = 1 << COM0B1 | 1 << WGM01 | 1 << WGM00; 291 | TCCR0B = (1 << WGM02) | 0b010; 292 | OCR0A = (F_CPU / (16000UL * 8)) - 1; 293 | if (duty == 0) { 294 | PWM_detach(5); 295 | PIN_set(5, LOW); 296 | } else { 297 | PWM_attach(5); 298 | OCR0B = map(duty, 0, 255, 0, OCR0A); 299 | } 300 | } 301 | 302 | /* ШИМ 20 кГц "8 Бит" на пине 5 */ 303 | void PWM_20KHZ_D5(uint8_t duty) { 304 | TCCR0A = 1 << COM0B1 | 1 << WGM01 | 1 << WGM00; 305 | TCCR0B = (1 << WGM02) | 0b010; 306 | OCR0A = (F_CPU / (20000UL * 8)) - 1; 307 | if (duty == 0) { 308 | PWM_detach(5); 309 | PIN_set(5, LOW); 310 | } else { 311 | PWM_attach(5); 312 | OCR0B = map(duty, 0, 255, 0, OCR0A); 313 | } 314 | } 315 | 316 | /* ШИМ 16 кГц "10 Бит" на пине 9 */ 317 | void PWM_16KHZ_D9(uint16_t duty) { 318 | TCCR1A = 1 << COM1A1 | 1 << WGM11; 319 | TCCR1B = 1 << WGM12 | 1 << WGM13 | 0b001; 320 | ICR1 = (F_CPU / 16000UL) - 1; 321 | OCR1A = map(duty, 0, 1023, 0, ICR1); 322 | } 323 | 324 | /* ШИМ 20 кГц "10 Бит" на пине 9 */ 325 | void PWM_20KHZ_D9(uint16_t duty) { 326 | TCCR1A = 1 << COM1A1 | 1 << WGM11; 327 | TCCR1B = 1 << WGM12 | 1 << WGM13 | 0b001; 328 | ICR1 = (F_CPU / 20000UL) - 1; 329 | OCR1A = map(duty, 0, 1023, 0, ICR1); 330 | } 331 | 332 | /* ШИМ 16 кГц "10 Бит" на пине 10 */ 333 | void PWM_16KHZ_D10(uint16_t duty) { 334 | TCCR1A = 1 << COM1B1 | 1 << WGM11; 335 | TCCR1B = 1 << WGM12 | 1 << WGM13 | 0b001; 336 | ICR1 = (F_CPU / 16000UL) - 1; 337 | OCR1B = map(duty, 0, 1023, 0, ICR1); 338 | } 339 | 340 | /* ШИМ 20 кГц "10 Бит" на пине 10 */ 341 | void PWM_20KHZ_D10(uint16_t duty) { 342 | TCCR1A = 1 << COM1B1 | 1 << WGM11; 343 | TCCR1B = 1 << WGM12 | 1 << WGM13 | 0b001; 344 | ICR1 = (F_CPU / 20000UL) - 1; 345 | OCR1B = map(duty, 0, 1023, 0, ICR1); 346 | } 347 | 348 | /* Генерация меандра с указанной частотой на пине 9 */ 349 | float PWM_square_D9(float frequency) { 350 | TCCR1A = 1 << COM1A0; 351 | TCCR1C = 1 << FOC1A; 352 | if (frequency < (F_CPU / (65535UL * 16))) { 353 | TCCR1B = 1 << WGM12 | 1 << WGM13 | 0b011; 354 | ICR1 = ((float)F_CPU / (frequency * 128UL)) - 1; 355 | return ((float)F_CPU / ((ICR1 + 1) * 128.0f)); 356 | } else if (frequency < (F_CPU / (65535UL * 2))) { 357 | TCCR1B = 1 << WGM12 | 1 << WGM13 | 0b010; 358 | ICR1 = ((float)F_CPU / (frequency * 16UL)) - 1; 359 | return ((float)F_CPU / ((ICR1 + 1) * 16.0f)); 360 | } else { 361 | TCCR1B = 1 << WGM12 | 1 << WGM13 | 0b001; 362 | ICR1 = ((float)F_CPU / (frequency * 2UL)) - 1; 363 | return ((float)F_CPU / ((ICR1 + 1) * 2.0f)); 364 | } 365 | } 366 | -------------------------------------------------------------------------------- /src/GyverPWM.h: -------------------------------------------------------------------------------- 1 | /* 2 | Библиотека для расширенной генерации ШИМ на ATmega328 (Arduino UNO/Nano/Pro Mini...) 3 | Документация: 4 | GitHub: https://github.com/GyverLibs/GyverPWM 5 | Возможности: 6 | - Аппаратная генерация ШИМ настраиваемой частоты и разрядности 7 | 8 | Egor Zaharov & AlexGyver, alex@alexgyver.ru 9 | https://alexgyver.ru/ 10 | MIT License 11 | 12 | Версии: 13 | v1.5 14 | v1.6 - поддержка ATmega168 15 | */ 16 | 17 | #ifndef GyverPWM_h 18 | #define GyverPWM_h 19 | #include 20 | 21 | #define CORRECT_PWM 1 22 | #define FAST_PWM 0 23 | 24 | #if not ( \ 25 | defined (__AVR_ATmega48P__) || \ 26 | defined (__AVR_ATmega88P__) || \ 27 | defined (__AVR_ATmega168P__) || \ 28 | defined (__AVR_ATmega168__) || \ 29 | defined (__AVR_ATmega328P__)) 30 | #error "This MCU is not supported in GyverPWM.h library" 31 | #endif 32 | 33 | #define MIN_PWMFREQ_CORRECT(a) ((F_CPU / a) / 510) 34 | #define MIN_PWMFREQ_FAST(a) ((F_CPU / a) / 256) 35 | 36 | // ============== Функции для расширенной генерации ШИМ сигнала ============== 37 | 38 | // Данные функции убирают один ШИМ выход у 8-ми битных таймеров, оставляя нам ШИМ пины D3, D5, D9 и D10 на ATmega328 39 | 40 | void PWM_frequency(uint8_t pin, uint32_t freq, uint8_t correct); 41 | /* PWM_freqency(пин, частота, режим) - запустить ШИМ с выбранной частотой 42 | - Пины: D3 (таймер 2), D5 (таймер 0 - сломает millis/delay), D9 и D10 (таймер 1) 43 | - Режим: 0 (FAST_PWM), 1 (CORRECT_PWM) 44 | - Частота: 250-200'000 Гц для всех таймеров 45 | - Для изменения заполнения используй PWM_set 46 | - Разрядность в этом режиме приведена к 8 битам, на деле шаги изменения разные! 47 | */ 48 | 49 | void PWM_resolution(uint8_t pin, uint8_t res, uint8_t correct); 50 | /* PWM_resolution(пин, разрядность, режим) - запустить ШИМ с выбранной разрядностью 51 | - Пины: D3 (таймер 2), D5 (таймер 0 - сломает millis/delay), D9 и D10 (таймер 1) 52 | - Режим: 0 (FAST_PWM), 1 (CORRECT_PWM) 53 | - Разрешение: D3 (4-8 бит), D5 (4-8 бит), D9 и D10 (4-16 бит) 54 | - Частота в этом режиме выбирается автоматически максимальная согласно возможностям таймера (см. таблицу) 55 | - Для изменения заполнения используй PWM_set 56 | - Пределы заполнения для разной разрядности указаны в таблице 57 | */ 58 | 59 | void PWM_set(uint8_t pin, uint16_t duty); 60 | /* PWM_set(пин, заполнение) - изменить заполнение на выбранном пине 61 | - Пин: D3, D5, D6, D9, D10, D11 62 | - Заполнение: зависит от разрешения и режима (см. таблицу) 63 | - При использовании PWM_frequency разрядность составляет 8 бит (0-255) 64 | - При использовании PWM_resolution макс. значение заполнения равно (2^разрядность - 1), также смотри таблицу 65 | */ 66 | 67 | void PWM_detach(uint8_t pin); // отключает ШИМ на выбранном пине (позволяет использовать digital Read/Write) 68 | void PWM_attach(uint8_t pin); // подключает ШИМ на выбранном пине (с последними настройками) 69 | void PWM_default(uint8_t pin); // сброс настроек соответствующего пину таймера на "стандартные" для Arduino 70 | 71 | void PWM_16KHZ_D3(uint8_t duty); 72 | /* Запуск ШИМ с частотой 16 кГц на пине D3 73 | - Отменяет настройки PWM_frequency/PWM_resolution 74 | - Разрядность приведена к 8 битам (заполнение 0-255) 75 | - Заполнение меняет сама (не нужно вызывать PWM_set) */ 76 | 77 | void PWM_20KHZ_D3(uint8_t duty); 78 | /* Запуск ШИМ с частотой 20 кГц на пине D3 79 | - Отменяет настройки PWM_frequency/PWM_resolution 80 | - Разрядность приведена к 8 битам (заполнение 0-255) 81 | - Заполнение меняет сама (не нужно вызывать PWM_set) */ 82 | 83 | void PWM_16KHZ_D5(uint8_t duty); 84 | /* Запуск ШИМ с частотой 16 кГц на пине D5 85 | - Отменяет настройки PWM_frequency/PWM_resolution 86 | - Разрядность приведена к 8 битам (заполнение 0-255) 87 | - Заполнение меняет сама (не нужно вызывать PWM_set) */ 88 | 89 | void PWM_20KHZ_D5(uint8_t duty); 90 | /* Запуск ШИМ с частотой 20 кГц на пине D5 91 | - Отменяет настройки PWM_frequency/PWM_resolution 92 | - Разрядность приведена к 8 битам (заполнение 0-255) 93 | - Заполнение меняет сама (не нужно вызывать PWM_set) */ 94 | 95 | void PWM_16KHZ_D9(uint16_t duty); 96 | /* Запуск ШИМ с частотой 16 кГц (15.6 кГц) на пине D9 97 | - Отменяет настройки PWM_frequency/PWM_resolution 98 | - Разрядность ровно 10 бит (заполнение 0-1023) 99 | - Заполнение меняет сама (не нужно вызывать PWM_set) */ 100 | 101 | void PWM_20KHZ_D9(uint16_t duty); 102 | /* Запуск ШИМ с частотой 20 кГц на пине D9 103 | - Отменяет настройки PWM_frequency/PWM_resolution 104 | - Разрядность приведена к 10 битам (заполнение 0-1023) 105 | - Заполнение меняет сама (не нужно вызывать PWM_set) */ 106 | 107 | void PWM_16KHZ_D10(uint16_t duty); 108 | /* Запуск ШИМ с частотой 16 кГц (15.6 кГц) на пине D10 109 | - Отменяет настройки PWM_frequency/PWM_resolution 110 | - Разрядность ровно 10 бит (заполнение 0-1023) 111 | - Заполнение меняет сама (не нужно вызывать PWM_set) */ 112 | 113 | void PWM_20KHZ_D10(uint16_t duty); 114 | /* Запуск ШИМ с частотой 20 кГц на пине D10 115 | - Отменяет настройки PWM_frequency/PWM_resolution 116 | - Разрядность приведена к 10 битам (заполнение 0-1023) 117 | - Заполнение меняет сама (не нужно вызывать PWM_set) */ 118 | 119 | float PWM_square_D9(float frequency); 120 | /* Генератор меандра (квадратная волна) на пине D9 121 | Частота от 2 Гц до 8 Мгц, шаг частоты зависит от частоты 122 | (начиная с 0.01 Гц и заканчивая десятками кГц!!!) 123 | Отключить можно вызвав PWM_detach(9); 124 | Для сброса таймера в режим по-умолчанию - PWM_default(9); 125 | Возвращает установленную частоту в герцах! 126 | 127 | Частота Погрешность 128 | 300 Гц 0.01 Гц 129 | 700 Гц 0.05 Гц 130 | 900 ГЦ 0.1 Гц 131 | 2 кГц 0.5 Гц 132 | 3 кГц 1 Гц 133 | 4 кГц 2 Гц 134 | 9 кГц 10 Гц 135 | 20 кГц 50 Гц 136 | 30 кГц 110 Гц 137 | 63 кГц 500 Гц 138 | 90 кГц 1000 Гц 139 | */ 140 | 141 | /* 142 | ============= Таблица №1 частот для расширенной генерации ШИМ (PWM_resolution) ============= 143 | _________________________________________________________________________________________________________________________ 144 | |Разрядность, бит |4 |5 |6 |7 |8 |9 |10 |11 |12 |13 |14 |15 |16 | 145 | |___________________|_______|_______|_______|_______|______|________|________|_______|_______|_______|______|______|______| 146 | |Макс. значение duty|15 |31 |63 |127 |255 |511 |1023 |2047 |4095 |8191 |16383 |32767 |65535 | 147 | |___________________|_______|_______|_______|_______|______|________|________|_______|_______|_______|______|______|______| 148 | |Fast | Пины 3, 5 |1 МГц |516 кГц|254 кГц|126 кГц|63 кГц|- |- |- |- |- |- |- |- | 149 | |PWM | 9, 10 |1 МГц |516 кГц|254 кГц|126 кГц|63 кГц|31.2 кГц|15.6 кГц|7.8 кГц|3.9 кГц|1.9 кГц|980 Гц|488 Гц|244 Гц| 150 | |_______|___________|_______|_______|_______|_______|______|________|________|_______|_______|_______|______|______|______| 151 | |Correct| Пины 3, 5 |571 кГц|266 кГц|129 кГц|63 кГц |32 кГц|- |- |- |- |- |- |- |- | 152 | |PWM | 9, 10 |571 кГц|266 кГц|129 кГц|63 кГц |32 кГц|15.7 кГц|7.8 кГц |3.9 кГц|1.9 кГц|976 Гц |488 Гц|244 Гц|122 Гц| 153 | |_______|___________|_______|_______|_______|_______|______|________|________|_______|_______|_______|______|______|______| 154 | */ 155 | 156 | // ============ Функции для настройки стандартной генерации ШИМ сигнала (analogWrite) ============ 157 | 158 | // Данные функции НЕ убирают один ШИМ выход у 8-ми битных таймеров, можно использовать все 6 ШИМ пинов с настроенной частотой! См. таблицу. 159 | 160 | void PWM_prescaler(uint8_t pin, uint8_t mode); 161 | /* PWM_prescaler(пин, режим) - установить предделитель таймера (меняет частоту ШИМ) 162 | - Пин: D3, D5, D6, D9, D10, D11 163 | - Режим: 1-7, см. таблицу частот 164 | */ 165 | 166 | void PWM_mode(uint8_t pin, uint8_t mode); 167 | /* PWM_mode(пин, режим) - установить режим генерации ШИМ 168 | - Пин: D3, D5, D6, D9, D10, D11 169 | - Режим: 0 - FastPWM, 1 - Phase-correct, см. таблицу частот 170 | */ 171 | 172 | void PWM_TMR1_8BIT(); // Установить таймер 1 (ШИМ на D9 и D10) в режим 8 бит. См. таблицу частот 173 | 174 | void PWM_TMR1_10BIT(); // Установить таймер 1 (ШИМ на D9 и D10) в режим 10 бит. См. таблицу частот 175 | 176 | /* 177 | ========== Таблица №2 частот для стандартной генерации ШИМ (PWM_prescaler) ========== 178 | 179 | Timer 0 по умолчанию работает в режиме Fast PWM 180 | Timer 1 и 2 по умолчанию работают в режиме Phase-correct 181 | _______________________________________________________________________________________________ 182 | | | Timer0 (пины 5 и 6) 8 bit | Timer 1 (пины 9 и 10) 10 bit | Timer2 (пины 3 и 11) 8 bit| 183 | | | Timer1 (пины 9 и 10) 8 bit| | | 184 | | |___________________________|_______________________________|___________________________| 185 | |mode | Phase-correct | Fast PWM | Phase-correct | Fast PWM | Phase-correct | Fast PWM | 186 | |_______|_______________|___________|___________________|___________|_______________|___________| 187 | |1 | 31.4 kHz | 62.5 kHz | 7.8 kHz | 15.6 kHz | 31.4 kHz | 62.5 kHz | 188 | |2 | 4 kHz | 7.8 kHz | 977 Hz | 2 kHz | 4 kHz | 8 kHz | 189 | |3 | 490 Hz | 976 Hz | 122 Hz | 244 Hz | 980 Hz | 2 kHz | 190 | |4 | 122 Hz | 244 Hz | 30 Hz | 61 Hz | 490 Hz | 980 Hz | 191 | |5 | 30 Hz | 61 Hz | 7.6 Hz | 15 Hz | 245 Hz | 490 Hz | 192 | |6 | - | - | - | - | 122 Hz | 244 Hz | 193 | |7 | - | - | - | - | 30 Hz | 60 Hz | 194 | |_______|_______________|___________|___________________|___________|_______________|___________| 195 | */ 196 | 197 | #endif --------------------------------------------------------------------------------