Библиотека TimerOne

Adno
Offline
Зарегистрирован: 21.09.2012

Существует такая библиотека 16-ти разрядного таймера

http://www.pjrc.com/teensy/td_libs_TimerOne.html

Использовал, работает хорошо

Обнаружил в ней функцию pwm ( pin, duty, microseconds)

Пытался запустить, результатов не обнаружил, а главное не понял почему

P.S. для сторонников analogWrite() сразу сообщаю, что надеюсь получить 16-ти разрядный PWM

Adno
Offline
Зарегистрирован: 21.09.2012

P.S.
Обращаю внимание, функция pwm работает с пинами 1,2 или 9,10

Adno
Offline
Зарегистрирован: 21.09.2012

Нашел такой вот пример у испанцев кажется

#include 

/*
    PWM Pin 10
*/

void setup () {
 
 Timer1.initialize (10000); // inizialize period
 Timer1.pwm(10,512);
 pinMode(10, OUTPUT);
 
}

void loop() {
 Timer1.start();
 delay(2000);
 Timer1.stop();
 digitalWrite(10, LOW);
 delay(500);
}

не работает

Adno
Offline
Зарегистрирован: 21.09.2012

Нашел ещё такую фигню.

Each timer controls PWM pins. While uses these libraries,
analogWrite() to those pins will not work normally, but you can use the library pwm() function.

Board                     TimerOne      TimerThree
                            PWM Pins      PWM Pins	

Teensy 3.1             3, 4               25, 32
Teensy 3.0             3, 4	
Teensy 2.0             4, 14, 15          9
Teensy++ 2.0           25, 26, 27       14, 15, 16
Arduino Uno            9, 10	
Arduino Leonardo       9, 10, 11         5
Arduino Mega           11, 12, 13        2, 3, 5
Wiring-S               4, 5	
Sanguino              12, 13	
leshak
Offline
Зарегистрирован: 29.09.2011

Если очень нужно, то можно и на других пинах получить PWM этой либой, только уже программно.

Делаете attachInterrupt на интервал поменьше, и уже в обработчике, делаете что-то типа

static volatile byte pwmCnt;
byte level=100; // уровень заполнения шима. 255 - 100%
void handler(){
  pwmCnt++;
  
  digitalWrite(PIN,pwmCnt<level);
  
}

Для скорости-точности можно digitalWrite заменить прямым управление портом.

Strangeman
Offline
Зарегистрирован: 28.11.2014

Adno пишет:
Нашел ещё такую фигню. Each timer controls PWM pins. While uses these libraries, analogWrite() to those pins will not work normally, but you can use the library pwm() function.

Board                     TimerOne      TimerThree
                            PWM Pins      PWM Pins	

Teensy 3.1             3, 4               25, 32
Teensy 3.0             3, 4	
Teensy 2.0             4, 14, 15          9
Teensy++ 2.0           25, 26, 27       14, 15, 16
Arduino Uno            9, 10	
Arduino Leonardo       9, 10, 11         5
Arduino Mega           11, 12, 13        2, 3, 5
Wiring-S               4, 5	
Sanguino              12, 13	

Возможно, давно неактуально, но не смог запустить на Arduino Mega2560, начал разбираться.

Ещё один момент — можно указывать в качестве номера пина 1 и 2 вместо 9 и 10, но здесь тоже нужно быть внимательным: если указать 1 или 2, то это сработает и на Arduino Mega (пины 11 и 12), и на простой Arduino (пины 9 и 10), но если указать 9 или 10, то сработает только на Arduino… Брр, и что только автор библиотеки курил?

Казалось бы, все ясно, но не тут то было. Я нигде не увидел, что для использования библиотекой пины нужно предварительно инициализировать на выход.

В общем, заработало так:
 

  pinMode(11, OUTPUT);
  Timer1.initialize(20);
  Timer1.pwm(1, 512);

Запустить на 13м выводе не удалось.

Для выводов 11 и 12 их нужно инициализировать на выход, а библиотеке передавать 1 или 2 соответственно.

Maverik
Offline
Зарегистрирован: 12.09.2012

Вопрос только один - а зачем весь этот огород ?

Strangeman
Offline
Зарегистрирован: 28.11.2014

Какой?

Maverik
Offline
Зарегистрирован: 12.09.2012

ну, зачем добиваться того, что аппаратно не поддерживается изначально, ведь всё равно это будет только эмуляция 16 разрядов,  зато это уже есть в arduino due ?

Strangeman
Offline
Зарегистрирован: 28.11.2014

Аппаратно не поддерживается что? 16 разрядный таймер-счетчик? Т.е. документация на контроллеры врет? Даже в Atmega8 заявлено:

One 16-bit Timer/Counter with Separate Prescaler, Compare Mode, and Capture
Mode

И что делать? Всем срочно переходить на arduino due ?

Что касается самой библиотеки - да, с ней проблем хватает, во всяком случае у меня таймер нормально не заработал. При установке тика на 100мс получил тик в 120мс.

Maverik
Offline
Зарегистрирован: 12.09.2012

а, точно, 16 разрядов.

s1292oia
Offline
Зарегистрирован: 04.09.2015

Не могу разобраться с библиотекой TimerOne. Я новичок в Arduino. Собрал самодельную плату на Atmega 8. Установил Arduino IDE 1.6.5 (OS XP). Прошил bootloader, загружал скетчи, все работает. Столкнулся с необходимостью использования библиотеки TimerOne. Скачал последнюю версию, распаковал в папку libraries. Запустил IDE, проверил, библиотека добавилась. Решил посмотреть работу библиотеки из примеров. Открыл ISRBlink из папки. Запустил компилятор и получил в ответ ошибку.  Нашел более старую версию библиотеки, заменил - результат тот же. вычитал, что может глючить новый компилятор. откатился на версию Arduino IDE 1.5.5 - результат ошибка.

Текст ошибки: Arduino: 1.5.5-r2 (Windows XP), Board: "Arduino NG or older, ATmega8"

 
C:\Program Files\Arduino\libraries\TimerOne\TimerOne.cpp: In member function 'void TimerOne::attachInterrupt(void (*)(), long int)':
C:\Program Files\Arduino\libraries\TimerOne\TimerOne.cpp:117: error: 'TIMSK1' was not declared in this scope
C:\Program Files\Arduino\libraries\TimerOne\TimerOne.cpp: In member function 'void TimerOne::detachInterrupt()':
C:\Program Files\Arduino\libraries\TimerOne\TimerOne.cpp:125: error: 'TIMSK1' was not declared in this scope
C:\Program Files\Arduino\libraries\TimerOne\TimerOne.cpp: In member function 'void TimerOne::start()':
C:\Program Files\Arduino\libraries\TimerOne\TimerOne.cpp:143: error: 'TIMSK1' was not declared in this scope
C:\Program Files\Arduino\libraries\TimerOne\TimerOne.cpp:144: error: 'GTCCR' was not declared in this scope
C:\Program Files\Arduino\libraries\TimerOne\TimerOne.cpp:144: error: 'PSRSYNC' was not declared in this scope
 
  This report would have more information with
  "Show verbose output during compilation"
  enabled in File > Preferences.
Не знаю, где копать! Остается грешить на OS, т.к. вычитал на буржуйском сайте, что была подобная проблема на MAC.
dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

s1292oia, этой библой не пользуюсь, но могу прокмментировать по ошибкам - в меге8 нет перечисленных регистров. Там есть аналогичные, но они по другому называются. Соответссно можно предположить что библа не поддерживает мегу8.

s1292oia
Offline
Зарегистрирован: 04.09.2015

Спасибо за подсказку. Для проверки поменял плату в Arduino IDE на Arduino UNO и все скомпилировалось! Сейчас начну крючить библиотеку под atmega 8.

s1292oia
Offline
Зарегистрирован: 04.09.2015

Запустил библиотеку для atmega 8 добавив в файл TimerOne.cpp строки:

// enable support for ATMEGA8
#if defined(__AVR_ATmega8__)
#define TIMSK1 TIMSK
#define GTCCR SFIOR
#define PSRSYNC PSR10
#endif

Источник:http://forum.arduino.cc/index.php?topic=244553.0

Arafrael
Offline
Зарегистрирован: 12.01.2016

Уважаемые форумчена подскажите. Нужно реализовать нормальный ШИМ на Arduino, решил сделать на данной библиотеке. Покопавшись в интерете, почитал форумы статьи, вроде бы все просто. Но не тут то было, набросал тестовую програмку и понял что ничего не понял

#include <TimerOne.h>


const int shim = 11;

void setup ()
{
  Timer1.initialize (20);  // обьясните если не сложно зачем число в скобках и как оно влияет на работу, так и не разобрался
  Timer1.pwm (1, 512); //тут вроде все понятно
  pinMode (shim, OUTPUT);
  }

  void loop()

  {
    Timer1.start(); //я так понимаю когда явызвал ШИМ  он должен работать до STOP 100мс? 
    delay(100);
    Timer1.stop();
    //digitalWrite (shim, LOW); //с этой строкой светодиод вновь не загорается
    delay(1000);
    Timer1.resume();    //тут я так понимаю старт ШИМа перезапускается
    }
 
но беда в следующем, при увеличении скважности светодиод или не полностью тухнет  или горит дольше 100мс или подергается потухнет и т.д.
что не так в коде
 
ПС и если не затруднит еще одно  все это у меня должно работать по нажатию на кнопку (нажал кнопку ШИМ проработал n-времени и остановился, но эта фигня также не заработала)
 
ПСПС Спасибо всем кто отпишется
Blackhock
Offline
Зарегистрирован: 09.02.2018

Подскажите, пожалуйста, как переделать в библиотеку TimerOne так, чтобы на его выходных выходах (Ардуино МЕГА) можно было менять вместо скважинных импульсов, фазных импульсов в пределах 0-1023 значения должны быть не изменены 50%. Ввод TimerOne.h, но сам не могу мало опыта.

  Что сдесь нужно изменить?

/ *
 * Утилиты прерывания и ШИМ для 16-битного Таймера1 на ATmega168 / 328
 * Оригинальный код Джесси Тейна для http://labs.ideo.com Август 2008
 * Изменено в марте 2009 года Жеромом Деспати и Джесси Таном для поддержки ATmega328
 * Изменено в июне 2009 года Майклом Полли и Джесси Тейном для исправления ошибки в setPeriod (), которая приводила к остановке таймера
 * Изменено в апреле 2012 года Полом Стоффрегеном - перенос на другие чипы AVR, использует встроенные функции
 * Изменено снова, июнь 2014 года Полом Стоффрегеном - поддержка Teensy 3.x и даже больше чипов AVR
 *  
 *
 * Это бесплатное программное обеспечение. Вы можете распространять его и / или изменять его в разделе
 * условия лицензии Creative Commons Attribution 3.0 United States. 
 * Чтобы просмотреть копию этой лицензии, посетите http://creativecommons.org/licenses/by/3.0/us/ 
 * или отправьте письмо в Creative Commons, 171 Second Street, Suite 300, Сан-Франциско, Калифорния, 94105, США.
 *
 * /

#ifndef TimerOne_h_
#define TimerOne_h_

#iffined (ARDUINO) && ARDUINO> = 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

#include "config / known_16bit_timers.h"

#define TIMER1_RESOLUTION 65536UL // Таймер1 16-битный


// Размещение почти всего кода в этом .h файле позволяет функциям быть
// встроено компилятором. В очень распространенном случае с постоянными значениями
// компилятор выполнит все вычисления и просто напишет константы
// к аппаратным регистрам (например, setPeriod).


класс TimerOne
{


#iffined (__ AVR__)
  общественности:
    // ****************************
    // Конфигурация
    // ****************************
    void initialize (unsigned long microseconds = 1000000) __attribute __ ((always_inline)) {
	TCCR1B = _BV (WGM13); // установить режим как фазу и частоту правильного ШИМ, остановить таймер
	TCCR1A = 0; // очистить регистр управления A
	setPeriod (микросекунды);
    }
    void setPeriod (беззнаковые длинные микросекунды) __attribute __ ((always_inline)) {
	const беззнаковые длинные циклы = (F_CPU / 2000000) * микросекунды;
	if (циклы <TIMER1_RESOLUTION) {
		clockSelectBits = _BV (CS10);
		pwmPeriod = циклы;
	} еще
	if (циклы <TIMER1_RESOLUTION * 8) {
		clockSelectBits = _BV (CS11);
		pwmPeriod = циклов / 8;
	} еще
	if (циклы <TIMER1_RESOLUTION * 64) {
		clockSelectBits = _BV (CS11) | _BV (CS10);
		pwmPeriod = циклов / 64;
	} еще
	if (циклы <TIMER1_RESOLUTION * 256) {
		clockSelectBits = _BV (CS12);
		pwmPeriod = циклов / 256;
	} еще
	if (циклы <TIMER1_RESOLUTION * 1024) {
		clockSelectBits = _BV (CS12) | _BV (CS10);
		pwmPeriod = циклов / 1024;
	} еще {
		clockSelectBits = _BV (CS12) | _BV (CS10);
		pwmPeriod = TIMER1_RESOLUTION - 1;
	}
	ICR1 = pwmPeriod;
	TCCR1B = _BV (WGM13) | clockSelectBits;
    }

    // ****************************
    // Запуск управления
    // ****************************
    void start () __attribute __ ((always_inline)) {
	TCCR1B = 0;
	TCNT1 = 0; // TODO: это вызывает нежелательное прерывание?
	продолжить();
    }
    void stop () __attribute __ ((always_inline)) {
	TCCR1B = _BV (WGM13);
    }
    void restart () __attribute __ ((always_inline)) {
	Начните();
    }
    void resume () __attribute __ ((always_inline)) {
	TCCR1B = _BV (WGM13) | clockSelectBits;
    }

    // ****************************
    // ШИМ-выходы
    // ****************************
    void setPwmDuty (символьный штифт, беззнаковая int обязанность) __attribute __ ((always_inline)) {
	unsigned long dutyCycle = pwmPeriod;
	dutyCycle * = обязанность;
	dutyCycle >> = 10;
	if (pin == TIMER1_A_PIN) OCR1A = dutyCycle;
	#ifdef TIMER1_B_PIN
	иначе if (pin == TIMER1_B_PIN) OCR1B = dutyCycle;
	#endif
	#ifdef TIMER1_C_PIN
	иначе if (pin == TIMER1_C_PIN) OCR1C = dutyCycle;
	#endif
    }
    void pwm (char pin, unsigned int обязанности) __atribute __ ((always_inline)) {
	if (pin == TIMER1_A_PIN) {pinMode (TIMER1_A_PIN, OUTPUT); TCCR1A | = _BV (COM1A1); }
	#ifdef TIMER1_B_PIN
	иначе if (pin == TIMER1_B_PIN) {pinMode (TIMER1_B_PIN, OUTPUT); TCCR1A | = _BV (COM1B1); }
	#endif
	#ifdef TIMER1_C_PIN
	иначе if (pin == TIMER1_C_PIN) {pinMode (TIMER1_C_PIN, OUTPUT); TCCR1A | = _BV (COM1C1); }
	#endif
	setPwmDuty (pin, duty);
	TCCR1B = _BV (WGM13) | clockSelectBits;
    }
    void pwm (символьная булавка, беззнаковая int обязанность, беззнаковые длинные микросекунды) __attribute __ ((always_inline)) {
	if (микросекунды> 0) setPeriod (микросекунды);
	ШИМ (штифт, долг);
    }
    void disablePwm (char pin) __attribute __ ((always_inline)) {
	if (pin == TIMER1_A_PIN) TCCR1A & = ~ _BV (COM1A1);
	#ifdef TIMER1_B_PIN
	иначе if (pin == TIMER1_B_PIN) TCCR1A & = ~ _BV (COM1B1);
	#endif
	#ifdef TIMER1_C_PIN
	иначе if (pin == TIMER1_C_PIN) TCCR1A & = ~ _BV (COM1C1);
	#endif
    }

    // ****************************
    // Функция прерывания
    // ****************************
    void attachInterrupt (void (* isr) ()) __attribute __ ((always_inline)) {
	isrCallback = isr;
	TIMSK1 = _BV (TOIE1);
    }
    void attachInterrupt (void (* isr) (), длинные микросекунды без знака) __atribute __ ((always_inline)) {
	if (микросекунды> 0) setPeriod (микросекунды);
	attachInterrupt (ISR);
    }
    void detachInterrupt () __attribute __ ((always_inline)) {
	TIMSK1 = 0;
    }
    static void (* isrCallback) ();
    static void isrDefaultUnused ();

  частный:
    // свойства
    static unsigned short pwmPeriod;
    статический символ без знака clockSelectBits;






#elif определен (__ arm__) && определен (CORE_TEENSY)

#iffined (KINETISK)
#define F_TIMER F_BUS
#eliffined (KINETISL)
#define F_TIMER (F_PLL / 2)
#endif

  общественности:
    // ****************************
    // Конфигурация
    // ****************************
    void initialize (unsigned long microseconds = 1000000) __attribute __ ((always_inline)) {
	setPeriod (микросекунды);
    }
    void setPeriod (беззнаковые длинные микросекунды) __attribute __ ((always_inline)) {
	const беззнаковые длинные циклы = (F_TIMER / 2000000) * микросекунды;
  // намного быстрее if-else
  // Это похоже на бинарное дерево поиска и оценивается не более 3 условий.
  // Я не проверял, становится ли это значительно длиннее ASM, чем простая лестница.
  // Это выглядит очень похоже на лестницу tho: same # of if's and else's
 
  / *
  // Этот код работает не во всех случаях :(
  // https://github.com/PaulStoffregen/TimerOne/issues/17 
  if (циклы <TIMER1_RESOLUTION * 16) {
    if (циклы <TIMER1_RESOLUTION * 4) {
      if (циклы <TIMER1_RESOLUTION) {
        clockSelectBits = 0;
        pwmPeriod = циклы;
      } Еще {
        clockSelectBits = 1;
        pwmPeriod = циклы >> 1;
      }
    } Еще {
      if (циклы <TIMER1_RESOLUTION * 8) {
        clockSelectBits = 3;
        pwmPeriod = циклы >> 3;
      } Еще {
        clockSelectBits = 4;
        pwmPeriod = циклы >> 4;
      }
    }
  } Еще {
    if (циклы> TIMER1_RESOLUTION * 64) {
      if (циклы> TIMER1_RESOLUTION * 128) {
        clockSelectBits = 7;
        pwmPeriod = TIMER1_RESOLUTION - 1;
      } Еще {
        clockSelectBits = 7;
        pwmPeriod = циклы >> 7;
      }
    }
    еще {
      if (циклы> TIMER1_RESOLUTION * 32) {
        clockSelectBits = 6;
        pwmPeriod = циклы >> 6;
      } Еще {
        clockSelectBits = 5;
        pwmPeriod = циклы >> 5;
      }
    }
  }
  * /
	if (циклы <TIMER1_RESOLUTION) {
		clockSelectBits = 0;
		pwmPeriod = циклы;
	} еще
	if (циклы <TIMER1_RESOLUTION * 2) {
		clockSelectBits = 1;
		pwmPeriod = циклы >> 1;
	} еще
	if (циклы <TIMER1_RESOLUTION * 4) {
		clockSelectBits = 2;
		pwmPeriod = циклы >> 2;
	} еще
	if (циклы <TIMER1_RESOLUTION * 8) {
		clockSelectBits = 3;
		pwmPeriod = циклы >> 3;
	} еще
	if (циклы <TIMER1_RESOLUTION * 16) {
		clockSelectBits = 4;
		pwmPeriod = циклы >> 4;
	} еще
	if (циклы <TIMER1_RESOLUTION * 32) {
		clockSelectBits = 5;
		pwmPeriod = циклы >> 5;
	} еще
	if (циклы <TIMER1_RESOLUTION * 64) {
		clockSelectBits = 6;
		pwmPeriod = циклы >> 6;
	} еще
	if (циклы <TIMER1_RESOLUTION * 128) {
		clockSelectBits = 7;
		pwmPeriod = циклы >> 7;
	} еще {
		clockSelectBits = 7;
		pwmPeriod = TIMER1_RESOLUTION - 1;
	}

	uint32_t sc = FTM1_SC;
	FTM1_SC = 0;
	FTM1_MOD = pwmPeriod;
	FTM1_SC = FTM_SC_CLKS (1) | FTM_SC_CPWMS | clockSelectBits | (sc & FTM_SC_TOIE);
    }

    // ****************************
    // Запуск управления
    // ****************************
    void start () __attribute __ ((always_inline)) {
	стоп();
	FTM1_CNT = 0;
	продолжить();
    }
    void stop () __attribute __ ((always_inline)) {
	FTM1_SC = FTM1_SC & (FTM_SC_TOIE | FTM_SC_CPWMS | FTM_SC_PS (7));
    }
    void restart () __attribute __ ((always_inline)) {
	Начните();
    }
    void resume () __attribute __ ((always_inline)) {
	FTM1_SC = (FTM1_SC & (FTM_SC_TOIE | FTM_SC_PS (7))) | FTM_SC_CPWMS | FTM_SC_CLKS (1);
    }

    // ****************************
    // ШИМ-выходы
    // ****************************
    void setPwmDuty (символьный штифт, беззнаковая int обязанность) __attribute __ ((always_inline)) {
	unsigned long dutyCycle = pwmPeriod;
	dutyCycle * = обязанность;
	dutyCycle >> = 10;
	if (pin == TIMER1_A_PIN) {
		FTM1_C0V = dutyCycle;
	} else if (pin == TIMER1_B_PIN) {
		FTM1_C1V = dutyCycle;
	}
    }
    void pwm (char pin, unsigned int обязанности) __atribute __ ((always_inline)) {
	setPwmDuty (pin, duty);
	if (pin == TIMER1_A_PIN) {
		* portConfigRegister (TIMER1_A_PIN) = PORT_PCR_MUX (3) | PORT_PCR_DSE | PORT_PCR_SRE;
	} else if (pin == TIMER1_B_PIN) {
		* portConfigRegister (TIMER1_B_PIN) = PORT_PCR_MUX (3) | PORT_PCR_DSE | PORT_PCR_SRE;
	}
    }
    void pwm (символьная булавка, беззнаковая int обязанность, беззнаковые длинные микросекунды) __attribute __ ((always_inline)) {
	if (микросекунды> 0) setPeriod (микросекунды);
	ШИМ (штифт, долг);
    }
    void disablePwm (char pin) __attribute __ ((always_inline)) {
	if (pin == TIMER1_A_PIN) {
		* portConfigRegister (TIMER1_A_PIN) = 0;
	} else if (pin == TIMER1_B_PIN) {
		* portConfigRegister (TIMER1_B_PIN) = 0;
	}
    }

    // ****************************
    // Функция прерывания
    // ****************************
    void attachInterrupt (void (* isr) ()) __attribute __ ((always_inline)) {
	isrCallback = isr;
	FTM1_SC | = FTM_SC_TOIE;
	NVIC_ENABLE_IRQ (IRQ_FTM1);
    }
    void attachInterrupt (void (* isr) (), длинные микросекунды без знака) __atribute __ ((always_inline)) {
	if (микросекунды> 0) setPeriod (микросекунды);
	attachInterrupt (ISR);
    }
    void detachInterrupt () __attribute __ ((always_inline)) {
	FTM1_SC & = ~ FTM_SC_TOIE;
	NVIC_DISABLE_IRQ (IRQ_FTM1);
    }
    static void (* isrCallback) ();
    static void isrDefaultUnused ();

  частный:
    // свойства
    static unsigned short pwmPeriod;
    статический символ без знака clockSelectBits;

#undef F_TIMER

#endif
};

внешний таймер один таймер1;

#endif

 

RockKenny
Offline
Зарегистрирован: 20.10.2017

Подскажите плз как заставить эту библу генерировать шим на D5 и/или D6?

Что поправить в библиотеке?

Green
Offline
Зарегистрирован: 01.10.2015

"Может в консерватории что надо подправить?"

RockKenny
Offline
Зарегистрирован: 20.10.2017

Хорошо давай в консерватории. Напиши как.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

RockKenny пишет:

Хорошо давай в консерватории. Напиши как.

Перечитайте тему с начала. В ней ответ на Ваш вопрос уже есть.

RockKenny
Offline
Зарегистрирован: 20.10.2017

andriano пишет:

RockKenny пишет:

Хорошо давай в консерватории. Напиши как.

Перечитайте тему с начала. В ней ответ на Ваш вопрос уже есть.

Если вы про сообщение №4, то я ничего не понял, что надо сделать. 

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

 

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Форум - не учебное заведение. Здесь никто не будет поднимать уровень новичка с нуля. Если новичок заинтересован чего-то достичь, то должен сам проявить некоторую активность, чтобы иметь представление хотя бы об основах.

Вот какие именно слова Вы не понимаете в сообщении №4?

RockKenny
Offline
Зарегистрирован: 20.10.2017

 

Например: "Делаете attachInterrupt на интервал поменьше," - Меньше чего? На какой интервал?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

RockKenny пишет:

 

Например: "Делаете attachInterrupt на интервал поменьше," - Меньше чего? На какой интервал?

Встречный вопрос: а что такое ШИМ? Как Вы это понимаете?

RockKenny
Offline
Зарегистрирован: 20.10.2017

Высокий уровень некой продолжительности, повторяющейся с некой частотой.

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Ладно, тогда именно этими терминами (продолжительность и частота) и будем пользоваться.

Для ШИМ, вообще-то, характерно две частоты: одна характеризует частоту повторения импульсов, другая имеет как бы второстепенное значение, но на самом деле именно она является главной частотой с точки зрения реализации. Так вот, "продолжительность" должна представлять собой целое число периодов этой самой "второстепенной" частоты. Собственно, 1 период - это единица измерения "продолжительности". Если мы хотим, чтобы ШИМ имела 100 градаций (т.е. описывалась целым количеством процентов), то "второстепенная" частота должна быть в 100 раз выше частоты ШИМ. Именно на нее мы и настраиваем наш ТаймерОдин. А внутри прерывания смотрим, пора переключать уровень или еще нет. Ну и, поскольку код "приблизительный", в нем еще забыли обнулять счетчик по достижении им числа 100.

Т.е. "интервал" - это интервал между вызовами прерывания, в данном случае период "второстепенной частоты", и он должен быть во столько раз меньше частоты ШИМ, сколько мы хотим получить градаций.

RockKenny
Offline
Зарегистрирован: 20.10.2017

С чем связан именно этот путь решения проблемы, в самой библиотеке переназначить пины нет возможности?

Возможно, я ошибаюсь, из-за поверхностных знаний, но мне кажется, что метод, предложенный в 4 сообщении, не позволит мне получать sweep сигнал. От 0 до 20кгц.

Это единственная библиотека, которую я нашел, позволяет получить sweep сигнал, не используя дополнительные покупные модули-генераторы. Но 9 и 10 заняты...

 

 

 

sadman41
Offline
Зарегистрирован: 19.10.2016

В 328 МК к таймеру жёстко привязаны пины. На хардварном уровне на других пинах генерацию получить возможности нет.

b707
Offline
Зарегистрирован: 26.05.2017

RockKenny пишет:

Это единственная библиотека, которую я нашел, позволяет получить sweep сигнал, не используя дополнительные покупные модули-генераторы. Но 9 и 10 заняты...

А какие параметры ШИм вам нужны? На 5 и 6 можно получить ШИМ вплоть до 62 КГц вообще без библиотек

RockKenny
Offline
Зарегистрирован: 20.10.2017

b707 пишет:

RockKenny пишет:

Это единственная библиотека, которую я нашел, позволяет получить sweep сигнал, не используя дополнительные покупные модули-генераторы. Но 9 и 10 заняты...

А какие параметры ШИм вам нужны? На 5 и 6 можно получить ШИМ вплоть до 62 КГц вообще без библиотек

Научите пожалуйста. Мне надо меандр т.е ШИМ с 50% скважностью. Частоту которого можно менять о 1 до 20000гц. Делаю это просто, по средствам: Hz ++;

ps: Желательно с хорошей точностью. У TimerOne точность хорошая если написано 4кГц, так и получается +- пару герц.

RockKenny
Offline
Зарегистрирован: 20.10.2017

sadman41 пишет:
В 328 МК к таймеру жёстко привязаны пины. На хардварном уровне на других пинах генерацию получить возможности нет.

Как тогда правильно понимать эту картинку? Шим вроде как на 3,5,6,9,10,11

b707
Offline
Зарегистрирован: 26.05.2017

RockKenny пишет:

Научите пожалуйста. Мне надо меандр т.е ШИМ с 50% скважностью. Частоту которого можно менять о 1 до 20000гц. Делаю это просто, по средствам: Hz ++;

Какой же это ШИМ? Главное свойство ШИМ сигнала - переменное заполнение при постоянной частоте. Аппаратный ШИМ на пинах 5 и 6 может иметь только фиксированную частоту - 62 Кгц, 31, 8, 4, 1 КГц и дальше вниз

А то что вы хотите - это никакой не ШИМ, а генератор частоты. Такое можно сделать только программно, по методике , описанной andriano на пару сообщений выше.

И, кстати. библиотека ТаймерOne для этого совершенно необязательна, на регистрах таймера будет быстрее и проще

b707
Offline
Зарегистрирован: 26.05.2017

RockKenny пишет:

Как тогда правильно понимать эту картинку? Шим вроде как на 3,5,6,9,10,11

Timer1 - это только 9 и 10

D5 D6 - это Timer0

D3 D11 - это Timer2

Но таймер0 и таймер2 - 8 битные, на них хорошую точность не получить

RockKenny
Offline
Зарегистрирован: 20.10.2017

Похоже я всех запутал, извиняюсь.

Без примеров я думаю не разберусь с генерацией сигнала на регистрах. Наберусь наглости попросить пример, похоже у гугла я тоже как-то не верно спрашиваю. (Плавное изменение частоты шим arduino) 

ЗЫ: Как дергать ноги регистрами знаю, но что там с таймерами делать не осилю пока.

b707
Offline
Зарегистрирован: 26.05.2017

RockKenny пишет:

Это единственная библиотека, которую я нашел, позволяет получить sweep сигнал, не используя дополнительные покупные модули-генераторы. Но 9 и 10 заняты...

Если на этой библиотеке вы получаете то, что нужно - самое правильное решение будет освободить 9 и 10 пины. Все остальные варианты сложнее и хуже.

RockKenny
Offline
Зарегистрирован: 20.10.2017

Да, меня полностью устраивает. Ок, буду думать как освободить...

b707
Offline
Зарегистрирован: 26.05.2017

RockKenny пишет:

Без примеров я думаю не разберусь с генерацией сигнала на регистрах. Наберусь наглости попросить пример, похоже у гугла я тоже как-то не верно спрашиваю. (Плавное изменение частоты шим arduino)

"Плавное изменение частоты ШИМ" - это неверный запрос. Плавно изменять частоту ШИМ довольно сложно и это возможно только в небольших пределах. Но вам это и не нужно.

Для того чтобы просто генерить прямоугольный сигнал, достаточно настроить прерывание по совпадению и в обработчике инвертировать уровень на пине. Тогда меняя регистр сравнения - вы будете плано менять частоту. Это все описано в любом руковдстве по таймерам.

Вот, например, статья самого базового уровня для начала https://habr.com/ru/post/453276/

 

Но если вы хотите менять частоту в таком широком диапазоне - 0- 20 КГц, да еще и иметь хорошую точность во всех частях диапазона - задача усложняется. Для каждой частоты надо сначала подбирать оптимальный делитесь.

так что идея освбождения пинов 9 и 10, наверно, самая правильная

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

RockKenny пишет:

Мне надо меандр т.е ШИМ с 50% скважностью. Частоту которого можно менять о 1 до 20000гц. Делаю это просто, по средствам: Hz ++;

ps: Желательно с хорошей точностью. У TimerOne точность хорошая если написано 4кГц, так и получается +- пару герц.

Вы неправильно формулируете.

Судя по всему, ШИМ Вам вообще не нужен, а нужен исключительно меандр. Точнее, генератор меандра с регулируемой частотой. ШИМ как бы подразумевает, что частоту мы не меняем, а меняем только скважность.

sadman41
Offline
Зарегистрирован: 19.10.2016

Меандр присутствует в генераторе от Димакса, промежду прочим. И частота вполне в нем регулируется.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

RockKenny пишет:

как заставить эту библу генерировать шим на D5 и/или D6?

Как обычно - добрым словом и пистолетом.