From b13f199588271b34c2f1f4ce6bd18a10e11a60f5 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 4 Jul 2019 19:24:04 +0300 Subject: [PATCH] add --- GyverPWM/GyverPWM.cpp | 565 ++++++++++++++++++ GyverPWM/GyverPWM.h | 151 +++++ .../PWMdefFrequency/PWMdefFrequency.ino | 32 + .../examples/PWMfrequency/PWMfrequency.ino | 31 + .../examples/PWMresolution/PWMresolution.ino | 30 + GyverPWM/examples/PWMtest/PWMtest.ino | 19 + GyverPWM/examples/customPWM.xlsx | Bin 0 -> 10110 bytes GyverPWM/examples/defaultPWM.xlsx | Bin 0 -> 9097 bytes GyverPWM/keywords.txt | 42 ++ README.md | 158 +++++ 10 files changed, 1028 insertions(+) create mode 100644 GyverPWM/GyverPWM.cpp create mode 100644 GyverPWM/GyverPWM.h create mode 100644 GyverPWM/examples/PWMdefFrequency/PWMdefFrequency.ino create mode 100644 GyverPWM/examples/PWMfrequency/PWMfrequency.ino create mode 100644 GyverPWM/examples/PWMresolution/PWMresolution.ino create mode 100644 GyverPWM/examples/PWMtest/PWMtest.ino create mode 100644 GyverPWM/examples/customPWM.xlsx create mode 100644 GyverPWM/examples/defaultPWM.xlsx create mode 100644 GyverPWM/keywords.txt diff --git a/GyverPWM/GyverPWM.cpp b/GyverPWM/GyverPWM.cpp new file mode 100644 index 0000000..a71c863 --- /dev/null +++ b/GyverPWM/GyverPWM.cpp @@ -0,0 +1,565 @@ +#include "GyverPWM.h" + +boolean defFlag0, defFlag2, mapFlag0, mapFlag1, mapFlag2; + +void PIN_set(uint8_t pin, uint8_t x) { + if (pin < 8) bitWrite(PORTD, pin, x); + else if (pin < 14) bitWrite(PORTB, (pin - 8), x); + else if (pin < 20) bitWrite(PORTC, (pin - 14), x); + else return; +} + +/* биты делителя называются CSn2/CSn1/CSn0 в регистре TCCRnB где n- номер таймера*/ +void PWM_default(byte pin) { // тут настроен максимально дефолтные настройки таймера, делитель 64 + switch (pin) { + case 3: //Timer2_B // не хочешь /64 можешь сделать /1 + defFlag2 = 1; // врубаем флаг дефолт для ноги 3 + mapFlag2 = 0; //выкл масштабирование + TCCR2A = 0b10100001; //default pwm 8 bit phaseCorrect + TCCR2B = 0b00000100; // prescaler /64 // крайние левые 3 бита поменять на 001 для делителя 1 + break; + case 5: //Timer0_B + defFlag0 = 1; // врубаем флаг дефолт для ноги 5 + mapFlag0 = 0; + TCCR0A = 0b10100011; //default pwm 8 bit FastPWM + TCCR0B = 0b00000011; // prescaler /64 + break; + case 6: //Timer0_A + defFlag0 = 1; // врубаем флаг дефолт для ноги 5 + mapFlag0 = 0; + TCCR0A = 0b10100011; //default pwm 8 bit FastPWM + TCCR0B = 0b00000011; // prescaler /64 + break; + case 9: //Timer1_A + mapFlag1 = 0; + TCCR1A = 0b10100001; // default pwm 8 bit phaseCorrect + TCCR1B = 0b00000011; // prescaler /64 // крайние левые 3 бита в 001 для делителя 1 + break; + case 10: //Timer1_B + mapFlag1 = 0; + TCCR1A = 0b10100001; // default pwm 8 bit phaseCorrect + TCCR1B = 0b00000011; // prescaler /64 + break; + case 11: //Timer2_A + defFlag0 = 1; // врубаем флаг дефолт для ноги 5 + mapFlag0 = 0; + TCCR2A = 0b10100011; //default pwm 8 bit FastPWM + TCCR2B = 0b00000011; // prescaler /64 + break; + } +} + +void PWM_frequency(byte pin, long freq, boolean correct) { + byte top0 , top2; + unsigned int top1; + freq = constrain(freq, 250, 200000); + switch (pin) { + case 3: + mapFlag2 = 1; // вкл масштабирование + defFlag2 = 0; // откл дефолтность + switch (correct) { + case 1: //T2_corr + TCCR2A = 0b00100001; // тут настраиваем коррект (2 с права бит в 0) + if (freq > 31373) { //разбиваем на диапазоны частот + TCCR2B = 0b00001001; //1 подбираем делители + top2 = 8000000 / freq; // формула для расчета предела счета в режиме короректа + } + if (freq <= 31373 && freq > 3922) { + TCCR2B = 0b00001010; //8 + top2 = 1000000 / freq; // для каждого делителя свои расчеты + } + if (freq <= 3922 && freq > 981) { + TCCR2B = 0b00001011; //32 + top2 = 250000 / freq; + } + if (freq <= 981 && freq > 491) { + TCCR2B = 0b00001100; //64 + top2 = 125000 / freq; + } + if (freq <= 491 && freq > 246) { + TCCR2B = 0b00001101; //128 + top2 = 62500 / freq; + } + OCR2A = top2; // в конце подставили предел счета + break; + case 0: //T2_fast // тут настраивается фаст + TCCR2A = 0b00100011; + if (freq > 62500) { + TCCR2B = 0b00001001; //1 + top2 = (16000000 / freq) - 1; // формула для режима фаста + } + if (freq <= 62500 && freq > 7813) { + TCCR2B = 0b00001010; //8 + top2 = (2000000 / freq) - 1; + } + if (freq <= 7813 && freq > 1954) { + TCCR2B = 0b00001011; //32 + top2 = (500000 / freq) - 1; + } + if (freq <= 1954 && freq > 977) { + TCCR2B = 0b00001100; //64 + top2 = (250000 / freq) - 1; + } + if (freq <= 977 && freq > 489) { + TCCR2B = 0b00001101; //128 + top2 = (125000 / freq) - 1; + } + if (freq <= 489) { + TCCR2B = 0b00001110; //256 + top2 = (62500 / freq) - 1; + } + OCR2A = top2; + break; + } + break; + case 5: + mapFlag0 = 1; + defFlag0 = 0; + switch (correct) { + case 1: //T0_corr + TCCR0A = 0b00100001; + if (freq > 31373) { + TCCR0B = 0b00001001; //1 + top0 = 8000000 / freq; + } + if (freq <= 31373 && freq > 3922) { + TCCR0B = 0b00001010; //8 + top0 = 1000000 / freq; + } + if (freq <= 3922 && freq > 491) { + TCCR0B = 0b00001011; //64 + top0 = 125000 / freq; + } + if (freq <= 491) { + TCCR0B = 0b00001100; //256 + top0 = 31250 / freq; + } + OCR0A = top0; + break; + case 0: //T0_fast + TCCR0A = 0b00100011; + if (freq > 62500) { + TCCR0B = 0b00001001; //1 + top0 = (16000000 / freq) - 1; + } + if (freq <= 62500 && freq > 7813) { + TCCR0B = 0b00001010; //8 + top0 = (2000000 / freq) - 1; + } + if (freq <= 7813 && freq > 977) { + TCCR0B = 0b00001011; //64 + top0 = (250000 / freq) - 1; + } + if (freq <= 977) { + TCCR0B = 0b00001100; //256 + top0 = (62500 / freq) - 1; + } + OCR0A = top0; + break; + } + break; + case 9: // тут таймер 1 и ему хорошо + mapFlag1 = 1; + switch (correct) { + case 1: //T1_corr + TCCR1A = 0b10100010; // сразу настраиваем коррект или нет + TCCR1B = 0b00010001; // сразу ставим делитель 1 + top1 = 8000000 / freq; // тупо считаем топ и подставляем + ICR1H = highByte(top1); + ICR1L = lowByte(top1); + break; + case 0: //T1_fast + TCCR1A = 0b10100010; // аналогично для режима фаст + TCCR1B = 0b00011001; + top1 = (16000000 / freq) - 1; + ICR1H = highByte(top1); + ICR1L = lowByte(top1); + break; + } + break; + case 10: + mapFlag1 = 1; + switch (correct) { + case 1: //T1_corr + TCCR1A = 0b10100010; + TCCR1B = 0b00010001; + top1 = 8000000 / freq; + ICR1H = highByte(top1); + ICR1L = lowByte(top1); + break; + case 0: //T1_fast + TCCR1A = 0b10100010; + TCCR1B = 0b00011001; + top1 = (16000000 / freq) - 1; + ICR1H = highByte(top1); + ICR1L = lowByte(top1); + break; + } + break; + } +} + +void PWM_resolution(byte pin, byte res, boolean correct) { + res = constrain(res, 4, 16); // предел счета это кол-во ступеней (2 в степени) + unsigned int top = pow(2, res) - 1; + switch (pin) { + case 3: //Timer2_B + defFlag2 = 0; // выключаем флаг дефолтности для таймера 2 + mapFlag2 = 0; // выключаем флаг мастабирования + if (correct) { + TCCR2A = 0b10100001; // настроили как коррект + TCCR2B = 0b00001001; // вкл делитель 1 + OCR2A = constrain(top, 0, 255); // ограничили значение до 8 бит + } + else { + TCCR2A = 0b10100011; //настроили как фаст + TCCR2B = 0b00001001; // вкл делитель 1 + OCR2A = constrain(top, 0, 255); + } + break; + case 5: //Timer0_B + defFlag0 = 0; + mapFlag0 = 0; + if (correct) { + TCCR0A = 0b10100001; + TCCR0B = 0b00001001; + OCR0A = constrain(top, 0, 255); + } + else { + TCCR0A = 0b10100011; // аналогично + TCCR0B = 0b00001001; + OCR0A = constrain(top, 0, 255); + } + break; + case 9: //Timer1_A + mapFlag1 = 0; + if (correct) { + TCCR1A = 0b10100010; + TCCR1B = 0b00010001; + ICR1H = highByte(top); // раскидалии топ по 2м битам + ICR1L = lowByte(top); + } + else { + TCCR1A = 0b10100010; + TCCR1B = 0b00011001; + ICR1H = highByte(top); + ICR1L = lowByte(top); + } + break; + case 10: //Timer1_B + mapFlag1 = 0; + if (correct) { + TCCR1A = 0b10100010; + TCCR1B = 0b00010001; + ICR1H = highByte(top); + ICR1L = lowByte(top); + } + else { + TCCR1A = 0b10100010; + TCCR1B = 0b00011001; + ICR1H = highByte(top); + ICR1L = lowByte(top); + } + break; + } +} + +void PWM_set(byte pin , unsigned int duty) { // имеем баг с таймерами в режиме fastPWM с прямым шим и исправляем его супер образом + cli(); //запрет прерываний + switch (pin) { // баг заключается в то, что при заполнении 0 на выходе заполнение около 1-5% + case 3: //Timer2_B + if (mapFlag2) { + duty = map(duty, 0, 255, 0, OCR2A); // от 0 до top который пизданули с регистра + } + if (duty == 0) { + TCCR2A &= ~(1 << COM2B1); //отрубаем регистр сравнения + bitClear(PORTD, 3); // выкл + } else if (duty == OCR2A) { + TCCR2A &= ~(1 << COM2B1); //отрубаем регистр сравнения + bitSet(PORTD, 3); // вкл + } else { + TCCR2A |= (1 << COM2B1); // подрубаем к пину регистр сравнения + OCR2B = duty; // настроили скважность + } + break; + case 5: //Timer0_B + if (mapFlag0) { + duty = map(duty, 0, 255, 0, OCR0A); + } + if (duty == 0) { + TCCR0A &= ~(1 << COM0B1); + bitClear(PORTD, 5); + } else if (duty == OCR0A) { + TCCR0A &= ~(1 << COM0B1); + bitSet(PORTD, 5); + } else { + TCCR0A |= (1 << COM0B1); + OCR0B = duty; + } + break; + case 6: //Timer0_A + if (defFlag0) { + if (duty == 0) { + TCCR0A &= ~(1 << COM0B1); + bitClear(PORTD, 6); + } else if (duty == 255) { + TCCR0A &= ~(1 << COM0B1); + bitSet(PORTD, 6); + } else { + TCCR0A |= (1 << COM0B1); + OCR0A = duty; + } + } else { + bitSet(TCCR0A, COM0A1); + OCR0A = duty; + } + break; + case 9: //Timer1_A + if (mapFlag1) { + duty = map(duty, 0, 255, 0, ICR1L + (ICR1H << 8)); + } + if (duty == 0) { + TCCR1A &= ~(1 << COM1A1); + bitClear(PORTB, 1); + } else if (duty == (ICR1L + (ICR1H << 8)) ) { + TCCR1A &= ~(1 << COM1A1); + bitSet(PORTB, 1); + } else { + TCCR1A |= (1 << COM1A1); + OCR1AH = highByte(duty); + OCR1AL = lowByte(duty); + } + break; + case 10: //Timer1_B + if (mapFlag1) { + duty = map(duty, 0, 255, 0, ICR1L + (ICR1H << 8)); + } + if (duty == 0) { + TCCR1A &= ~(1 << COM1B1); + bitClear(PORTB, 2); + } else if (duty == (ICR1L + (ICR1H << 8)) ) { + TCCR1A &= ~(1 << COM1B1); + bitSet(PORTB, 2); + } else { + TCCR1A |= (1 << COM1B1); + OCR1BH = highByte(duty); + OCR1BL = lowByte(duty); + } + break; + case 11: //Timer2_A // аналогично, будет работать только с функцией pwm_default(11); + if (defFlag2) { + if (duty == 0) { + TCCR2A &= ~(1 << COM2A1); + bitClear(PORTB, 3); + } else if (duty == 255) { + TCCR2A &= ~(1 << COM2A1); + bitSet(PORTB, 3); + } else { + TCCR2A |= (1 << COM2A1); + OCR2A = duty; + } + } else { + bitSet(TCCR2A, COM2A1); + OCR2A = duty; + } + break; + } + sei(); +} + +void PWM_detach(byte pin) { + switch (pin) { + case 3: TCCR2A &= ~(1 << COM2B1); + PIN_set(3, 0); + break; + case 5: TCCR0A &= ~(1 << COM0B1); + PIN_set(5, 0); + break; + case 6: TCCR0A &= ~(1 << COM0B1); + PIN_set(6, 0); + break; + case 9: TCCR1A &= ~(1 << COM1A1); + PIN_set(9, 0); + break; + case 10: TCCR1A &= ~(1 << COM1B1); + PIN_set(10, 0); + break; + case 11: TCCR2A &= ~(1 << COM2A1); + PIN_set(11, 0); + break; + } +} + +void PWM_attach(byte pin) { + switch (pin) { + case 3: TCCR2A |= (1 << COM2B1); + break; + case 5: TCCR0A |= (1 << COM0B1); + break; + case 6: TCCR0A |= (1 << COM0B1); + break; + case 9: TCCR1A |= (1 << COM1A1); + break; + case 10: TCCR1A |= (1 << COM1B1); + break; + case 11: TCCR2A |= (1 << COM2A1); + break; + } +} + +void PWM_prescaler(byte pin, byte mode) { + byte prescale; + if (pin == 5 || pin == 6) { + switch (mode) { + case 1: prescale = 0x01; break; + case 2: prescale = 0x02; break; + case 3: prescale = 0x03; break; + case 4: prescale = 0x04; break; + case 5: prescale = 0x05; break; + default: return; + } + } else if (pin == 9 || pin == 10) { + switch (mode) { + case 1: prescale = 0x01; break; + case 2: prescale = 0x02; break; + case 3: prescale = 0x03; break; + case 4: prescale = 0x04; break; + case 5: prescale = 0x05; break; + default: return; + } + } else if (pin == 3 || pin == 11) { + switch (mode) { + case 1: prescale = 0x01; break; + case 2: prescale = 0x02; break; + case 3: prescale = 0x03; break; + case 4: prescale = 0x04; break; + case 5: prescale = 0x05; break; + case 6: prescale = 0x06; break; + case 7: prescale = 0x07; break; + default: return; + } + } + if (pin == 5 || pin == 6) { + TCCR0B = 0; + TCCR0B = TCCR0B & 0b11111000 | prescale; + } else if (pin == 9 || pin == 10) { + TCCR1B = 0; + TCCR1B = TCCR1B & 0b11111000 | prescale; + } else if (pin == 3 || pin == 11) { + TCCR2B = 0; + TCCR2B = TCCR2B & 0b11111000 | prescale; + } +} + +void PWM_mode(byte pin, byte mode) { // 0 - FastPWM, 1 - Phase-correct PWM + if (pin == 5 || pin == 6) { + if (mode) TCCR0A |= _BV(WGM00); + else TCCR0A |= _BV(WGM00) | _BV(WGM01); + } else if (pin == 9 || pin == 10) { + if (mode) TCCR1B &= ~_BV(WGM12); + else TCCR1B |= _BV(WGM12); + } else if (pin == 3 || pin == 11) { + if (mode) TCCR2A |= _BV(WGM20); + else TCCR2A |= _BV(WGM20) | _BV(WGM21); + } else { + return; + } +} + +void PWM_TMR1_8BIT() { + TCCR1A = TCCR1A & 0xe0 | 1; +} +void PWM_TMR1_10BIT() { + TCCR1A = TCCR1A & 0xe0 | 3; +} + +void PWM_16KHZ_D3(byte duty) { + TCCR2A = 0b10100011; + TCCR2B = 0b00001010; + OCR2A = 124; + if (duty == 0) { + bitClear(TCCR2A, COM2B1); + //PIN_set(3, 0); + bitClear(PORTD, 3); + } else { + bitSet(TCCR2A, COM2B1); + OCR2B = map(duty, 0, 255, 0, 124); + } +} + +void PWM_20KHZ_D3(byte duty) { + TCCR2A = 0b10100011; + TCCR2B = 0b00001010; + OCR2A = 99; + if (duty == 0) { + bitClear(TCCR2A, COM2B1); + //PIN_set(3, 0); + bitClear(PORTD, 3); + } else { + bitSet(TCCR2A, COM2B1); + OCR2B = map(duty, 0, 255, 0, 99); + } +} + +void PWM_16KHZ_D5(byte duty) { + TCCR0A = 0b10100011; + TCCR0B = 0b00001010; + OCR0A = 124; + if (duty == 0) { + bitClear(TCCR0A, COM0B1); + //PIN_set(5, 0); + bitClear(PORTD, 5); + } else { + bitSet(TCCR0A, COM0B1); + OCR0B = map(duty, 0, 255, 0, 124); + } +} + +void PWM_20KHZ_D5(byte duty) { + TCCR0A = 0b10100011; + TCCR0B = 0b00001010; + OCR0A = 99; + if (duty == 0) { + bitClear(TCCR0A, COM0B1); + //PIN_set(5, 0); + bitClear(PORTD, 5); + } else { + bitSet(TCCR0A, COM0B1); + OCR0B = map(duty, 0, 255, 0, 99); + } +} + +void PWM_16KHZ_D9(int duty) { + TCCR1A = 0b10100010; + TCCR1B = 0b00011001; + ICR1H = 3; // highByte(1023) + ICR1L = 255; // lowByte(1023) + OCR1AH = highByte(duty); + OCR1AL = lowByte(duty); +} +void PWM_20KHZ_D9(int duty) { + TCCR1A = 0b10100010; + TCCR1B = 0b00011001; + ICR1H = 3; // highByte(799) + ICR1L = 31; // lowByte(799) + duty = map(duty, 0, 1023, 0, 799); + OCR1AH = highByte(duty); + OCR1AL = lowByte(duty); +} +void PWM_16KHZ_D10(int duty) { + TCCR1A = 0b10100010; + TCCR1B = 0b00011001; + ICR1H = 3; // highByte(1023) + ICR1L = 255; // lowByte(1023) + OCR1BH = highByte(duty); + OCR1BL = lowByte(duty); +} +void PWM_20KHZ_D10(int duty) { + TCCR1A = 0b10100010; + TCCR1B = 0b00011001; + ICR1H = 3; // highByte(799) + ICR1L = 31; // lowByte(799) + duty = map(duty, 0, 1023, 0, 799); + OCR1BH = highByte(duty); + OCR1BL = lowByte(duty); +} \ No newline at end of file diff --git a/GyverPWM/GyverPWM.h b/GyverPWM/GyverPWM.h new file mode 100644 index 0000000..894f612 --- /dev/null +++ b/GyverPWM/GyverPWM.h @@ -0,0 +1,151 @@ +#ifndef GyverPWM_h +#define GyverPWM_h +#include + +#define CORRECT_PWM 1 +#define FAST_PWM 0 + +/* + Библиотека для расширенной генерации ШИМ на ATmega328 (Arduino UNO/Nano/Pro Mini...) + Разработчики: Egor Zaharov и AlexGyver +*/ + +// ============== Функции для расширенной генерации ШИМ сигнала ============== + +// Данные функции убирают один ШИМ выход у 8-ми битных таймеров, оставляя нам ШИМ пины D3, D5, D9 и D10 на ATmega328 + +void PWM_frequency(byte pin, long freq, boolean 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, boolean 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) */ +/* + ============= Таблица №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, byte 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 | +|_______|_______________|___________|___________________|___________|_______________|___________| +*/ + +#endif \ No newline at end of file diff --git a/GyverPWM/examples/PWMdefFrequency/PWMdefFrequency.ino b/GyverPWM/examples/PWMdefFrequency/PWMdefFrequency.ino new file mode 100644 index 0000000..9fc9e1c --- /dev/null +++ b/GyverPWM/examples/PWMdefFrequency/PWMdefFrequency.ino @@ -0,0 +1,32 @@ +#include + +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); +} diff --git a/GyverPWM/examples/PWMfrequency/PWMfrequency.ino b/GyverPWM/examples/PWMfrequency/PWMfrequency.ino new file mode 100644 index 0000000..1dd8ca0 --- /dev/null +++ b/GyverPWM/examples/PWMfrequency/PWMfrequency.ino @@ -0,0 +1,31 @@ +#include + +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 бит) +} diff --git a/GyverPWM/examples/PWMresolution/PWMresolution.ino b/GyverPWM/examples/PWMresolution/PWMresolution.ino new file mode 100644 index 0000000..80b94c2 --- /dev/null +++ b/GyverPWM/examples/PWMresolution/PWMresolution.ino @@ -0,0 +1,30 @@ +#include + +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) +} diff --git a/GyverPWM/examples/PWMtest/PWMtest.ino b/GyverPWM/examples/PWMtest/PWMtest.ino new file mode 100644 index 0000000..f7abda4 --- /dev/null +++ b/GyverPWM/examples/PWMtest/PWMtest.ino @@ -0,0 +1,19 @@ +#include + +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() { +} diff --git a/GyverPWM/examples/customPWM.xlsx b/GyverPWM/examples/customPWM.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..afaf4e3310fd769a5c5cb7778cd82f9ef48e8727 GIT binary patch literal 10110 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 E0c6EZ5C8xG literal 0 HcmV?d00001 diff --git a/GyverPWM/examples/defaultPWM.xlsx b/GyverPWM/examples/defaultPWM.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..94276a628c3c4ad5834b4a0818530e9e488d5cb8 GIT binary patch literal 9097 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 +РАЗВЕРНУТЬ +

+Смотри примеры в папке examples! + +```C +// ============== Функции для расширенной генерации ШИМ сигнала ============== + +// Данные функции убирают один ШИМ выход у 8-ми битных таймеров, оставляя нам ШИМ пины D3, D5, D9 и D10 на ATmega328 + +void PWM_frequency(byte pin, long freq, boolean 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, boolean 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) */ +/* + ============= Таблица №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, byte 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 | +|_______|_______________|___________|___________________|___________|_______________|___________| +*/ +``` +

+ + +--- + + ### ServoSmooth v1.3 [СКАЧАТЬ](https://github.com/AlexGyver/GyverLibs/releases/download/ServoSmooth/ServoSmooth.zip) Библиотека для плавного управления сервоприводами - Является дополнением к стандартной библиотеке Servo