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: Еще один вариант

Arduino & Pi

1.4K постов20.6K подписчиков

Добавить пост

Правила сообщества

В нашем сообществе запрещается:

• Добавлять посты не относящиеся к тематике сообщества, либо не несущие какой-либо полезной нагрузки (флуд)

• Задавать очевидные вопросы в виде постов, не воспользовавшись перед этим поиском

• Выкладывать код прямо в посте - используйте для этого сервисы ideone.com, gist.github.com или схожие ресурсы (pastebin запрещен)

• Рассуждать на темы политики

• Нарушать установленные правила Пикабу

Вы смотрите срез комментариев. Показать все
1
Автор поста оценил этот комментарий
Писал я как-то посты на тему шим
раскрыть ветку (8)
1
Автор поста оценил этот комментарий
Да, видел, пробовал часть 2, не заработало у меня, причем полностью скопировал код, выдает то ли постоянно 1 то ли 0
раскрыть ветку (7)
Автор поста оценил этот комментарий

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

Автор поста оценил этот комментарий
Надо тоже на протоне попробывать... вообще похоже что фьюзы не правильно настроены. Т.к. на протоне ты используешь атмегу 8?
раскрыть ветку (5)
Автор поста оценил этот комментарий
Arduino uno используется, из дополнительной библиотеки. Щас попробую еще раз, может я где то ошибся
раскрыть ветку (4)
Автор поста оценил этот комментарий
Попробуй в протеусе не ардуину использовать а именно сам камень 328p
раскрыть ветку (3)
Автор поста оценил этот комментарий
Щас попробовал еще раз на ардуине, сам код работает, но это не то что мне нужно, у вас реализация шим на любом пине, а мне нужно именно что установить частоту произвольно, а в вашей реализации частота стандартная для 2 таймера счетчика 490 гц. Если с этой частотой подкючить, например вентилятор, то будет слышен писк
раскрыть ветку (2)
Автор поста оценил этот комментарий
490Гц секрет этой цифры я нашёл когда в ардуине никак не мог включить таймер со сбросом при совпадении, это помойму на 2 таймере оно не включается, хотя мануалы пишут именно на них.. если удается включить - то умножай на частоту почти на 255. Главное что ты нашёл как сделать. Сохраню постик в полезности =)
раскрыть ветку (1)
Автор поста оценил этот комментарий

Оо, сброс при совпадении, сколько же он мне крови попил, я так и не понял как с помощью него реализовать шим, смог вывести только однотактовый сигнал.

Вы смотрите срез комментариев. Чтобы написать комментарий, перейдите к общему списку