75

Arduino. Регулировка частоты ШИМ настройками таймера - счетчика

Понадобилось мне недавно установить частоту ШИМ у Arduino на 20кГц, с возможностью менять скважность (отношение периода повторения импульсов к длительности импульса). Хотелось это сделать без использования библиотек - настройками таймера счетчика. Убив на это два дня, перелопатив кучу форумов, перепробовав кучу вариантов(хз, это я такой тупой или выложены нерабочие коды) удалось найти на ютубе рабочий вариант на канале: "микроконтроллеры с нуля!" в видео с номером 26. Решил поделиться этим на Пикабу, вдруг кому пригодится.

Сам код:

cli(); //запрет прерываний

//режим вывода не инверсный
TCCR1A|=(1<<COM1A1);  //1
TCCR1A&=~(1<<COM1A0);  //0

//режим шим c точной фазой и частотой
TCCR1A&=~(1<<WGM10);  //0
TCCR1A&=~(1<<WGM11);  //0
TCCR1B&=~(1<<WGM12);  //0
TCCR1B|=(1<<WGM13);  //1

//предделитель 8
TCCR1B|=(1<<CS11);  //1
TCCR1B&=~((1<<CS10)|(1<<CS12));  //0 0

OCR1A =25;  // 50% длительность импульса
ICR1=50;  // 20кГц

sei(); //разрешение прерываний

Код нужно добавить в Setup. Настраивается таймер - счетчик 1, только канал А, соответственно нужный сигнал будет только на пине D9. Частота задается значением в регистре ICR1. Ниже представлены протестированные значения и соответствующая им частота.
ICR1=10; // 100 кГц
ICR1=20; // 50 кГц
ICR1=30; // 33 кГц
ICR1=40; // 25 кГц
ICR1=50; // 20 кГц
ICR1=60; // 16,6 кГц
ICR1=70; // 14,3 кГц
ICR1=80; // 12,5 кГц
ICR1=90; // 11,1 кГц
ICR1=100; // 10 кГц

Если изменить предделитель, то частоты будут другие, например при предделителе 64 и ICR1=50, частота будет 2,5 кГц.

Скважность регулируется значением в регистре OCR1A, она зависит от значения в ICR1, таким образом, что максимальное значение OCR1A равно значению в ICR1, если они равны получится постоянный сигнал. При значении OCR1A = ICR1 / 2 получится меандр (длительность импульса и длительность паузы между импульсами равны). Еще пример: при ICR1 = 50 (20кГц) и OCR1A = 10, длительность импульса будет 20%.

В loop можно менять значение OCR1A и соответственно будет меняться скважность.

Протестировано в Proteus, затем было выполнено на Arduino Nano, все работает.

P.S. Если кто - то знает еще рабочие способы изменения частоты шим и скважности, особенно на таймере - счетчике 2 буду благодарен за информацию.

Arduino. Регулировка частоты ШИМ настройками таймера - счетчика Arduino, Шим, Длиннопост

UPD: Еще один вариант

Дубликаты не найдены

+6
Я знаю верный способ. Называется чтение даташитов...
раскрыть ветку 2
+1
Летят двое на воздушном шаре... Унесло их, и не знают, где они сейчас... Пролетают мимо холма, на котором сидит человек. Храбрые воздухоплаватели спрашивают его:
- Скажите, пожалуйста, где мы сейчас находимся?
Человек на холме долго думает, после чего отвечает:
- На воздушном шаре.
Более пожилой и, следовательно более умудренный опытом воздухоплаватель говорит другому:
- Этот человек на холме - математик.
- Почему же?
- Он долго раздумывал над простым вопросом, после чего дал абсолютно точный и совершенно бесполезный ответ
раскрыть ветку 1
+1
Я слышал немного другую версию, про Холмса и Ватсона. Начало примерно похожее, но там человек пас овец.
Ну и после ответа "на воздушном шаре" Холмс и говорит:
- Мы в России, Ватсон.
- Но как?
- Элементарно. Только программист мог дать абсолютно точный и абсолютно бесполезный ответ, и только в России программист может пасти овец.
+1
Писал я как-то посты на тему шим
раскрыть ветку 8
0
Да, видел, пробовал часть 2, не заработало у меня, причем полностью скопировал код, выдает то ли постоянно 1 то ли 0
раскрыть ветку 7
0

Пин как выход значит забыл сделать) бывает

0
Надо тоже на протоне попробывать... вообще похоже что фьюзы не правильно настроены. Т.к. на протоне ты используешь атмегу 8?
раскрыть ветку 5
+1

Вот в этом и есть проклятие Ардуино. Никто ничего не понимает. Использовать либу для ШИМа. Для ШИМа Карл! Это пиздец, товарищи. Там ведь все элементарно. Есть книга Евстифеева "Микроконтроллеры семейства Mega", по сути перевод даташита. С нее и стоит начинать изучение AVR.

Это же простейшие контроллеры, за несколько дней можно полностью разобраться что там как работает, а не как слепой котенок копипасть куски кода.

раскрыть ветку 3
+1

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

раскрыть ветку 1
+1

Это просто бред. Ардуино создано для детей, по сути это детский конструктор. Никто и не говорит, что это плохо. Отнюдь. Что вы собрались на нем прототипировать? Тем более быстро? В продакшн на Ардуино писать никто в уме не будет. Сделать простенький термостат, часы или еще чего - базара нет. Но как только что то начинает идти не так, все - затык. "Библиотека ШИМ" И где ваше "быстро"? Что-бы делать быстро нужно знать контроллер и периферию. И все. Что бы эффективно и быстро писать нужно знать как устроен контроллер.

0
Спасибо, ознакомлюсь
+1
Если кто - то знает еще рабочие способы изменения частоты шим и скважности, особенно на таймере - счетчике 2 буду благодарен за информацию.

Сразу не скажу, я холодильники продаю в Эльдорадо.

Но через пару дней попробуй подкинуть пару идей.

0
В среде разработки Code vision avr есть удобный генератор программ. Там можно указать нужные настройки для любого таймера и получить сразу готовый код.
раскрыть ветку 1
0
Интересно, гляну попозже
0

Гайвер перенастраивать таймеры кажись в приставке к компу.

В зависимости от настроек может некорректно работать функция millis()

раскрыть ветку 5
+2

У Гайвера полно информации об этом на сайте, есть даже либа готовая под любую частоту

раскрыть ветку 3
0

О, сам маэстро. Снимаю шляпу

0
Есть либа, но я хотел без либы.
раскрыть ветку 1
0
Millis и micros будет некорректно работать только если менять настройки таймера - счетчика 0
0

Как-то делал на таймерах монофонический синтезатор. Сложно, но в какой-то степени, получилось :)

https://m.habr.com/ru/post/453276/

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

раскрыть ветку 5
+1

Попробовал оттуда режим сброс по совпадению, изменение частоты работает, только не понял как менять скважность в этом режиме и можно ли это вообще, в том примере длительность импульса 50% и как я понял не меняется.

раскрыть ветку 4
0

Если я правильно помню, там настраивается таймер на определенный шаг, а второй таймер отвечает за duty-cycle - сколько времени за цикл будет on, сколько - off.


Если первый таймер будет довольно быстрым, а максимальный счётчик второго будет в половину первого - то длительность будет 50/50. Если счётчик второго равен первому - то 100% on. И если второй таймер считает до 0, то ток не идёт вовсе.


Вроде, это настраивается через OCR1 и OCR2.

compare match register - до скольки считает таймер до сброса счётчика.


Штука в том, что первый таймер в начале каждого своего шага будет включать диод (подавать ток), а второй - отключает.


Поэтому, если, в начале шага первого таймера, второй сразу выключит диод - то только после сброса первого таймера он снова включится - и снова выключится. Если счётчик второго таймера = 0.


Если 100% - то диод будет выключаться в конце шага первого таймера, и сразу включаться в начале следующего шага.

раскрыть ветку 3
0

Писал как-то для Proteus свои компоненты.

раскрыть ветку 1
0
STM8 уже напишите)
0

1. Скачиваете пасспорт на свою микросхему (datasheet).

2. Ищите там схему делителей (и умножителей, если есть). Можно поиском поискать по документу - "divider". У каждого семейства контроллеров своя схема, код настройки отличается.

3. В комплекте с исходниками к макетной плате иногда кладут эксель-файл, который помогает рассчитать значения делителей (это у ARM-ов помоему есть, для Atmel-ов такое не припомню).

4. Далее понимаете, какой конкретно ШИМ вам нужен и какая частота - смотрите в схему делителей и комбинируя значения получаете частоту, наиболее близкую к искомой (ну или может получиться прям ту, какую нужно). Потом листаете в раздел, где этот шим описан. Смотрите как включается.

5. Правки в программу, прошиваем, замеряем частоту на нужной ноге. Если не получилось - перейти к п. 1.

раскрыть ветку 6
0

Печаль в том, что например на втором таймере счетчике с помощью делителя можно задать только такие частоты:

62.5 кГц  -- делитель 1 -- fast pwm

31.4 кГц  -- делитель 1 -- phase correct

8 кГц  -- делитель 8 -- fast pwm

4 кГц -- делитель 8 -- phase correct

2 кГц -- делитель 32 -- fast pwm

980 Гц -- делитель 32 -- phase correct

980 Гц -- делитель 64 -- fast pwm

490 Гц - по умолчанию -- делитель 64 -- phase correct

490 Гц -- делитель 128 -- fast pwm

245 Гц -- делитель 128 -- phase correct

245 Гц -- делитель 256 -- fast pwm

122 Гц -- делитель 256 -- phase correct

60 Гц -- делитель 1024 -- fast pwm

30 Гц -- делитель 1024 -- phase correct

Взято с сайта alexgyver.ru

раскрыть ветку 5
0

На этом же сайте на этой же странице чуть ниже есть ссылка на библиотеки, которые можно или заюзать, или взять нужный кусок кода и вставить себе. Там даже готовый ШИМ 20 кГц есть

раскрыть ветку 4
-1

Просто СПАСИБО.  Просто вот так, от начинающего самоучки.  Подписываюсь и лайк всегда с меня.

раскрыть ветку 1
+1
Я врятли буду еще писать, только если попадется заковыристая задачка, типо этой
Похожие посты