Расширенная генерация ШИМ на Arduino

БИБЛИОТЕКА


Библиотека для расширенной генерации ШИМ на Arduino

  • Генерация ШИМ любой частоты от 250 Гц до 200 кГц на пинах D3, D5, D9 и D10
  • Изменение разрядности ШИМ (пины D3 и D5: 4-8 бит, пины D9 и D10: 4-16 бит) с максимальной частотой (пример: 4 бита – 1 МГц ШИМ) на пинах D3, D5, D9 и D10. Или 12 бит ШИМ на частоте 4 кГЦ (пины 9 и 10)
  • Несколько функций для фиксированных частот 16/20 кГц (на пинах D3 и D5 8 бит, на пинах D9 и D10 – 10 бит)
  • Генерация меандра на пине D9 с частотой от 2 Гц до 8 МГц с максимальной точностью
  • Несколько частот на выбор (30 Гц – 62 кГц) для генерации ШИМ стандартной analogWrite на всех ШИМ пинах (D3, D5, D6, D9, D10, D11)
  • Изменение режима работы ШИМ (Fast/Correct PWM)
  • Отдельное спасибо Egor Zaharov

Поддерживаемые платформы: платы на ATmega328/168 (Arduino Nano, UNO, Pro Mini)

УСТАНОВКА


  • Библиотеку можно найти и установить через менеджер библиотек по названию GyverPWM в:
    • Arduino IDE (Инструменты/Управлять библиотеками)
    • Arduino IDE v2 (вкладка «Library Manager»)
    • PlatformIO (PIO Home, вкладка «Libraries»)
  • Про ручную установку читай здесь

ДОКУМЕНТАЦИЯ


// ============== Функции для расширенной генерации ШИМ сигнала ==============
// Данные функции убирают один ШИМ выход у 8-ми битных таймеров, оставляя нам ШИМ пины D3, D5, D9 и D10 на ATmega328
void PWM_frequency(byte pin, long freq, modes correct);
/*  PWM_freqency(пин, частота, режим) - запустить ШИМ с выбранной частотой
 - Пины: D3 (таймер 2), D5 (таймер 0 - сломает millis/delay), D9 и D10 (таймер 1)
 - Режим: 0 (FAST_PWM), 1 (CORRECT_PWM)
 - Частота: 250-200'000 Гц для всех таймеров
 - Для изменения заполнения используй PWM_set
  - Разрядность в этом режиме приведена к 8 битам, на деле шаги изменения разные!
*/
void PWM_resolution(byte pin, byte res, modes correct);
/*  PWM_resolution(пин, разрядность, режим) - запустить ШИМ с выбранной разрядностью
 - Пины: D3 (таймер 2), D5 (таймер 0 - сломает millis/delay), D9 и D10 (таймер 1)
 - Режим: 0 (FAST_PWM), 1 (CORRECT_PWM)
 - Разрешение: D3 (4-8 бит), D5 (4-8 бит), D9 и D10 (4-16 бит)
 - Частота в этом режиме выбирается автоматически максимальная согласно возможностям таймера (см. таблицу)
 - Для изменения заполнения используй PWM_set
  - Пределы заполнения для разной разрядности указаны в таблице
*/
void PWM_set(byte pin, unsigned int duty);
/*  PWM_set(пин, заполнение) - изменить заполнение на выбранном пине
 - Пин: D3, D5, D6, D9, D10, D11
 - Заполнение: зависит от разрешения и режима (см. таблицу)
  - При использовании PWM_frequency разрядность составляет 8 бит (0-255)
  - При использовании PWM_resolution макс. значение заполнения равно (2^разрядность - 1), также смотри таблицу
*/
void PWM_detach(byte pin);    // отключает ШИМ на выбранном пине (позволяет использовать digital Read/Write)
void PWM_attach(byte pin);    // подключает ШИМ на выбранном пине (с последними настройками)
void PWM_default(byte pin);    // сброс настроек соответствующего пину таймера на "стандартные" для Arduino
void PWM_16KHZ_D3(byte duty);
/*   Запуск ШИМ с частотой 16 кГц на пине D3
 - Отменяет настройки PWM_frequency/PWM_resolution
 - Разрядность приведена к 8 битам (заполнение 0-255)
 - Заполнение меняет сама (не нужно вызывать PWM_set) */
void PWM_20KHZ_D3(byte duty);
/*   Запуск ШИМ с частотой 20 кГц на пине D3
 - Отменяет настройки PWM_frequency/PWM_resolution
 - Разрядность приведена к 8 битам (заполнение 0-255)
 - Заполнение меняет сама (не нужно вызывать PWM_set) */
void PWM_16KHZ_D5(byte duty);
/*   Запуск ШИМ с частотой 16 кГц на пине D5
 - Отменяет настройки PWM_frequency/PWM_resolution
 - Разрядность приведена к 8 битам (заполнение 0-255)
 - Заполнение меняет сама (не нужно вызывать PWM_set) */
void PWM_20KHZ_D5(byte duty);
/*   Запуск ШИМ с частотой 20 кГц на пине D5
 - Отменяет настройки PWM_frequency/PWM_resolution
 - Разрядность приведена к 8 битам (заполнение 0-255)
 - Заполнение меняет сама (не нужно вызывать PWM_set) */
void PWM_16KHZ_D9(int duty);
/*   Запуск ШИМ с частотой 16 кГц (15.6 кГц) на пине D9
 - Отменяет настройки PWM_frequency/PWM_resolution
 - Разрядность ровно 10 бит (заполнение 0-1023)
 - Заполнение меняет сама (не нужно вызывать PWM_set) */
void PWM_20KHZ_D9(int duty);
/*   Запуск ШИМ с частотой 20 кГц на пине D9
 - Отменяет настройки PWM_frequency/PWM_resolution
 - Разрядность приведена к 10 битам (заполнение 0-1023)
 - Заполнение меняет сама (не нужно вызывать PWM_set) */
void PWM_16KHZ_D10(int duty);
/*   Запуск ШИМ с частотой 16 кГц (15.6 кГц) на пине D10
 - Отменяет настройки PWM_frequency/PWM_resolution
 - Разрядность ровно 10 бит (заполнение 0-1023)
 - Заполнение меняет сама (не нужно вызывать PWM_set) */
void PWM_20KHZ_D10(int duty);
/*   Запуск ШИМ с частотой 20 кГц на пине D10
 - Отменяет настройки PWM_frequency/PWM_resolution
 - Разрядность приведена к 10 битам (заполнение 0-1023)
 - Заполнение меняет сама (не нужно вызывать PWM_set) */
 
float PWM_square_D9(float frequency);
/*  Генератор меандра (квадратная волна) на пине D9
 Частота от 2 Гц до 8 Мгц, шаг частоты зависит от частоты
 (начиная с 0.01 Гц и заканчивая десятками кГц!!!)
 Отключить можно вызвав PWM_detach(9);
 Для сброса таймера в режим по-умолчанию - PWM_default(9);
 Возвращает установленную частоту в герцах!
 
 Частота    Погрешность
 300 Гц    0.01 Гц
 700 Гц    0.05 Гц
 900 ГЦ    0.1 Гц
 2 кГц    0.5 Гц
 3 кГц    1 Гц
 4 кГц    2 Гц
 9 кГц    10 Гц
 20 кГц    50 Гц
 30 кГц    110 Гц
 63 кГц    500 Гц
 90 кГц    1000 Гц
*/
/*
 ============= Таблица №1 частот для расширенной генерации ШИМ (PWM_resolution) =============
 _________________________________________________________________________________________________________________________
|Разрядность, бит   |4      |5      |6      |7      |8     |9       |10      |11     |12     |13     |14    |15    |16    |
|___________________|_______|_______|_______|_______|______|________|________|_______|_______|_______|______|______|______|
|Макс. значение duty|15     |31     |63     |127    |255   |511     |1023    |2047   |4095   |8191   |16383 |32767 |65535 |
|___________________|_______|_______|_______|_______|______|________|________|_______|_______|_______|______|______|______|
|Fast   | Пины 3, 5 |1 МГц  |516 кГц|254 кГц|126 кГц|63 кГц|-       |-       |-      |-      |-      |-     |-     |-     |
|PWM    | 9, 10     |1 МГц  |516 кГц|254 кГц|126 кГц|63 кГц|31.2 кГц|15.6 кГц|7.8 кГц|3.9 кГц|1.9 кГц|980 Гц|488 Гц|244 Гц|
|_______|___________|_______|_______|_______|_______|______|________|________|_______|_______|_______|______|______|______|
|Correct| Пины 3, 5 |571 кГц|266 кГц|129 кГц|63 кГц |32 кГц|-       |-       |-      |-      |-      |-     |-     |-     |
|PWM    | 9, 10     |571 кГц|266 кГц|129 кГц|63 кГц |32 кГц|15.7 кГц|7.8 кГц |3.9 кГц|1.9 кГц|976 Гц |488 Гц|244 Гц|122 Гц|
|_______|___________|_______|_______|_______|_______|______|________|________|_______|_______|_______|______|______|______|
*/
// ============ Функции для настройки стандартной генерации ШИМ сигнала (analogWrite) ============
// Данные функции НЕ убирают один ШИМ выход у 8-ми битных таймеров, можно использовать все 6 ШИМ пинов с настроенной частотой! См. таблицу.
void PWM_prescaler(byte pin, byte mode);
/*  PWM_prescaler(пин, режим) - установить предделитель таймера (меняет частоту ШИМ)
 - Пин: D3, D5, D6, D9, D10, D11
 - Режим: 1-7, см. таблицу частот
*/
void PWM_mode(byte pin, modes mode);
/*  PWM_mode(пин, режим) - установить режим генерации ШИМ
 - Пин: D3, D5, D6, D9, D10, D11
 - Режим: 0 - FastPWM, 1 - Phase-correct, см. таблицу частот
*/
void PWM_TMR1_8BIT();  // Установить таймер 1 (ШИМ на D9 и D10) в режим 8 бит. См. таблицу частот
void PWM_TMR1_10BIT();  // Установить таймер 1 (ШИМ на D9 и D10) в режим 10 бит. См. таблицу частот
/*
 ========== Таблица №2 частот для стандартной генерации ШИМ (PWM_prescaler) ==========
 
 Timer 0 по умолчанию работает в режиме Fast PWM 
 Timer 1 и 2 по умолчанию работают в режиме Phase-correct
 _______________________________________________________________________________________________
|       | Timer0 (пины 5 и 6) 8 bit | Timer 1 (пины 9 и 10) 10 bit  | Timer2 (пины 3 и 11) 8 bit|
|       | Timer1 (пины 9 и 10) 8 bit|                               |                           |
|       |___________________________|_______________________________|___________________________|
|mode   | Phase-correct | Fast PWM  | Phase-correct     | Fast PWM  | Phase-correct | Fast PWM  |
|_______|_______________|___________|___________________|___________|_______________|___________|
|1      | 31.4 kHz      | 62.5 kHz  | 7.8 kHz           | 15.6 kHz  | 31.4 kHz      | 62.5 kHz  |
|2      | 4 kHz         | 7.8 kHz   | 977 Hz            | 2 kHz     | 4 kHz         | 8 kHz     |
|3      | 490 Hz        | 976 Hz    | 122 Hz            | 244 Hz    | 980 Hz        | 2 kHz     |
|4      | 122 Hz        | 244 Hz    | 30 Hz             | 61 Hz     | 490 Hz        | 980 Hz    |
|5      | 30 Hz         | 61 Hz     | 7.6 Hz            | 15 Hz     | 245 Hz        | 490 Hz    |
|6      | -             | -         | -                 | -         | 122 Hz        | 244 Hz    |
|7      | -             | -         | -                 | -         | 30 Hz         | 60 Hz     |
|_______|_______________|___________|___________________|___________|_______________|___________|
*/

ПРИМЕРЫ


Остальные примеры смотри в папке examples библиотеки, также примеры можно открыть из Arduino IDE/Файл/Примеры

#include "GyverPWM.h"
void setup() {
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  
  // Данные функции НЕ УБИРАЮТ один ШИМ выход у 8-ми битных таймеров, оставляя нам ШИМ пины D3, D5, D9 и D10 на ATmega328
  PWM_prescaler(3, 1);  // установить частоту ШИМ на пине D3 равной 31.4 кГц (см. таблицу №2 в GyverPWM.h)
  // частота автоматически будет установлена для пина D11!
  PWM_prescaler(6, 2);  // установить частоту ШИМ на пине D6 равной 7.8 кГц (см. таблицу №2 в GyverPWM.h)
  // частота автоматически будет установлена для пина D5! Также это сломает millis() и delay()
  PWM_prescaler(9, 1);  // установить частоту ШИМ на пине D9 равной 7.8 кГц (см. таблицу №2 в GyverPWM.h)
  // частота автоматически будет установлена для пина D10!
  PWM_mode(9, 1);       // установить режим работы таймера 1 в Fast PWM. Частота будет 15.6 кГц (см. таблицу №2 в GyverPWM.h)
  // режим автоматически будет установлен для пина D10!
}
void loop() {
  // можем пользоваться ШИМом на всех 6-ти пинах!
  analogWrite(3, 123);
  analogWrite(5, 241);
  analogWrite(6, 26);
  analogWrite(9, 98);
  analogWrite(10, 165);
  analogWrite(11, 152);
}
#include "GyverPWM.h"
void setup() {
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  
  // Данные функции убирают один ШИМ выход у 8-ми битных таймеров, оставляя нам ШИМ пины D3, D5, D9 и D10 на ATmega328
  // запустить ШИМ на D3 с частотой 66.666 Гц, режим FAST_PWM
  PWM_frequency(3, 66666, FAST_PWM);
  // запустить ШИМ на D5 с частотой 25'000 Гц, режим CORRECT_PWM. Сломает millis()!
  PWM_frequency(5, 25000, CORRECT_PWM);
  // запустить ШИМ на D9 с частотой 150'000 Гц, режим FAST_PWM
  PWM_frequency(9, 150000, FAST_PWM);
  // запустить ШИМ на D10 с частотой 150'000 Гц, режим FAST_PWM
  PWM_frequency(10, 150000, FAST_PWM);
  // пины 9 и 10 работают на одной частоте, запустить на разных не получится!
}
void loop() {
  PWM_set(3, analogRead(0) / 4);  // заполнение регулируем потенциометром на А0 (8 бит)
  PWM_set(5, analogRead(0) / 4);  // заполнение регулируем потенциометром на А0 (8 бит)
  PWM_set(9, analogRead(0) / 4);  // заполнение регулируем потенциометром на А0 (8 бит)
  PWM_set(10, 255 - analogRead(0) / 4);  // заполнение регулируем потенциометром на А0 (8 бит)
}
#include "GyverPWM.h"
void setup() {
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  
  // Данные функции убирают один ШИМ выход у 8-ми битных таймеров, оставляя нам ШИМ пины D3, D5, D9 и D10 на ATmega328
  // запустить ШИМ на D3, разрядность 4 бита (0-15), частота 1 МГц (см. таблицу №1 в GyverPWM.h), режим FAST_PWM
  PWM_resolution(3, 4, FAST_PWM);
  // запустить ШИМ на D5, разрядность 6 бит (0-63), частота 254 кГц (см. таблицу №1 в GyverPWM.h), режим FAST_PWM. Сломает millis()!
  PWM_resolution(5, 6, FAST_PWM);
  // запустить ШИМ на D9, разрядность 12 бит (0-4095), частота 3.9 кГц (см. таблицу №1 в GyverPWM.h), режим FAST_PWM
  PWM_resolution(9, 12, FAST_PWM);
  // запустить ШИМ на D10, разрядность 12 бит (0-4095), частота 3.9 кГц (см. таблицу №1 в GyverPWM.h), режим FAST_PWM
  PWM_resolution(10, 12, FAST_PWM);
  // пины 9 и 10 работают на одной разрядности, запустить на разных не получится!
}
void loop() {
  PWM_set(3, 3);      // установить заполнение ШИМ на D3, равное 3 из 15, частота 1 МГц (см. таблицу №1 в GyverPWM.h)
  PWM_set(5, 40);     // установить заполнение ШИМ на D5, равное 40 из 63, частота 254 кГц (см. таблицу №1 в GyverPWM.h)
  PWM_set(9, 2842);   // установить заполнение ШИМ на D9, равное 2842 из 4095, частота 3.9 кГц (см. таблицу №1 в GyverPWM.h)
  PWM_set(10, 1248);  // установить заполнение ШИМ на D10, равное 1248 из 4095, частота 3.9 кГц (см. таблицу №1 в GyverPWM.h)
}
#include "GyverPWM.h"
void setup() {
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  // Данные функции убирают один ШИМ выход у 8-ми битных таймеров, оставляя нам ШИМ пины D3, D5, D9 и D10 на ATmega328
  PWM_16KHZ_D3(30);   // ШИМ 16 кГц на пине D3, заполнение 30 из 255
  PWM_20KHZ_D5(50);   // ШИМ 20 кГц на пине D5, заполнение 50 из 255. Сломает millis() и delay()!
  PWM_16KHZ_D9(760);  // ШИМ 16 кГц на пине D9, заполнение 760 из 1023
  PWM_16KHZ_D10(800); // ШИМ 16 кГц на пине D10, заполнение 800 из 1023
  // пины 9 и 10 работают на одной частоте, запустить на разных не получится
}
void loop() {
}
#include "GyverPWM.h"
void setup() {
  pinMode(9, OUTPUT);
  PWM_square_D9(78.65);
}
void loop() {  
}

ПОДДЕРЖАТЬ


Вы можете поддержать меня за создание доступных проектов с открытым исходным кодом, полный список реквизитов есть вот здесь.

5/5 - (5 голосов)
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

5 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
Прокрутить вверх