Платы Arduino предоставляют псвевдоаналоговые выходы с помощью функции analogWrite(). Эта функция доступна не для всех портов, а только для тех, которые помечены символом ~. Функция analogWrite не предоставляет реального аналогового выхода, вместо этого эмулируя аналоговый сигнал с помощью ШИМ (PWM).
[Что такое ШИМ]
Сигнал широтно-импульсной модуляции ШИМ (английская аббревиатура PWM, обозначающая Pulse Width Modulation) это сигнал, состоящий из последовательности специально сформированного двоичного сигнала. Термин "двоичный" означает, что сигнал может иметь только два состояния "HIGH" (лог. 1) и "LOW" (лог. 0). Аналоговая информация передается не уровнями сигнала, а соотношением между лог. 1 и лог. 0 (скважностью) генерируемых импульсов.
Если устройство, подключенное к выводу импульсов ШИМ, имеем меньшую полосу передачи частот, чем частота ШИМ, то получается результат фильтра низких частот (ФНЧ), и тогда ШИМ передает усредненное значение, воспринимаемой устройством как аналоговый сигнал. Выводы PWM платы Arduino Leonardo используют частоты модуляции 488 Гц или 976 Гц. Когда Вы используете функцию analogWrite, нацеленную на управление светодиодом (LED). то у светодиода полоса частот включения и выключения обычно заведомо превышает 1 кГц. Однако наши глаза имеют максимально распознаваемую частоту пульсацию не выше 100 Гц. Так как полоса частот мерцаний LED значительно превышает полосу воспринимаемых частот для глаза человека, то мы видим только среднее значение импульсов PWM (среднюю яркость свечения), не замечая того факта, что светодиод полностью включается и выключается за короткие промежутки времени импульсов PWM.
Тот же самый принцип действует, когда мы используем сигнал PWM для управления мотором. Обычные моторы постоянного тока из-за своей инерции и индуктивности обмоток имеют полосу пропускания ниже полосы PWM программ Arduino, поэтому мотор работает от импульсов PWM так же, как если бы питался от постоянного напряжения. Фактически PWM даже на низких частотах позволяет улучшить работу мотора на низких скоростях.
В целом частоты PWM в диапазоне от 500 Гц до 1 кГц коробочного Arduino вполне адекватны для управления моторами. Однако если мы хотим генерировать звуковой сигнал, то функция analogWrite не будет работать. Люди слышат частоты в диапазоне до примерно 20 кГц, что намного выше, чем частота Arduino PWM. Обычные динамики, если на них подать сигнал PWM, будут выдавать слышимый тональный звук с частотой PWM.
Решить проблему может генерация PWM на высокой частоте, которая выше частоты восприятия человеческим ухом, тогда мы сможем использовать сигнал PWM для генерации аудиосигнала.
[Возможности ШИМ плат Arduino Leonardo]
Давайте рассмотрим, как формируется ШИМ на платах Arduino Leonardo. Большинство плат Arduino генерирует сигналы ШИМ с помощью таймеров. Периферийное устройство таймера предоставляет аппаратную генерацию ШИМ, не вовлекающую вычисления CPU для непосредственного формирования импульсов ШИМ. Каждый таймер имеет ограниченное количество сигналов ШИМ, которые можно генерировать аппаратно.
Плата Arduino Leonardo использует микроконтроллер ATmega32U4. У него на кристалле имеется 4 таймера: Timer 0, Timer 1, Timer 3 и Timer 4. Таймеры 1 и 3 одинаковые, однако остальные таймеры несколько отличаются. Другие платы Arduino используют другие таймеры, которые есть в наличии у микроконтроллера, установленного на плате.
В следующей таблице показано использование таймеров для генерации ШИМ платой Arduino Leonardo.
Порт Arduino
Таймер, канал
Частота ШИМ, Гц
Режим
3
Timer 0, B
976
Single Slope (Fast PWM)
5
Timer 3, A
488
Dual Slope (Phase Corrected)
6
Timer 4, D
488
Dual Slope (Phase Corrected)
9
Timer 1, A
488
Dual Slope (Phase Corrected)
10
Timer 1, B
488
Dual Slope (Phase Corrected)
11
Timer 0, A
976
Single Slope (Fast PWM)
13
Timer 4, A
488
Dual Slope (Phase Corrected)
Arduino использует таймеры и для других функций. Например, Timer 0 также используется для записи прошедшего времени, что необходимо для работы функций millis(), micros(), delay() и delayMicroseconds(). Не забывайте о том, что работа Timer 0 может нарушить все другие функции времени.
Некоторые библиотеки Arduino также используют таймеры. Библиотека Servo на плате Leonardo использует Timer 1, то время как библиотека MsTimer2 использует Timer 4. Вам следует знать требования используемых библиотек к таймерам, поскольку они могут повлиять на генерацию ШИМ, связанную с их таймером.
Есть два основных способа создать сигнал ШИМ с помощью таймера. Если нужны дополнительные подробности по устройству таймера 4, см. [2].
[Single Slope PWM]
Работа таймеров основана на счетчике. У счетчика есть тактовый вход, и с каждым активным перепадом уровня на этом входе счетчик меняет свое состояние. Самый типовой режим работы - увеличение значения счетчика на единицу с каждым активным тактовым перепадом, пока счетчик не достигнет максимального значения. Как только это максимальное значение достигнуто, счетчик возвращает свое значение к нулю, и процесс счета импульсов тактов повторяется. Это дает пилообразную диаграмму отображения значения счетчика, что показано на картинке ниже, так называемый односкатный ШИМ (Single Slope PWM). Один полный цикл пилы (зуб) требует Count Max + 1 тактовых импульсов (здесь Count Max это максимальное значение счетчика).
Периферийное устройство таймера также включает в себя несколько регистров захвата/сравнения. Чтобы создать сигнал ШИМ, регистр сравнения связывается с аппаратным выходом микроконтроллера таким образом, что значение на этом выходе лог. 1, пока значение счетчика меньше или равно значению регистра сравнения. Это дает сигнал ШИМ для каждого регистра сравнения, где скважность сигнала ШИМ зависит от значения в регистре сравнения.
Все сигналы ШИМ, генерируемые одним и тем же таймером, будут иметь одинаковую частоту, потому что начало генерируемых импульсов будет находится на спаде зуба пилы, отображающей значение счетчика. Если у нас есть несколько сигналов ШИМ, генерируемых разными регистрами сравнения одного и того же таймера, то все эти сигналы получат начальный импульс периода ШИМ в одно и то же время.
Функция Arduino analogWrite() работает с Timer 0 микроконтроллера ATmega32u4 по принципу одного наклона пилы (single slope). Используется тактовая частота 250 кГц, полученная делением на 64 системной тактовой частоты 16 МГц. В результате получается частота импульсов ШИМ 976 Гц.
У Timer 0 есть два канала сравнения A и B, связанные с двумя регистрами сравнения OCR0A и OCR0B. Эти два канала имеют два аппаратных выхода OC0A и OC0B, использующие выводы 11 и 3 платы Arduino.
[Dual Slope PWM]
Другой способ генерировать ШИМ состоит в конфигурации счетчика для счета вперед и назад. Счетчик увеличивается с каждым тактом, и когда достигнет максимального значения, начинает уменьшаться на каждом такте. Уменьшение происходит до момента достижения счетчиком нуля, после чего опять начинается счет на увеличение. Это дает треугольную форму диаграммы изменения состояния счетчика вместо пилообразной, получается так называемый двухскатный ШИМ (Dual Slope PWM).
Также мы можем сконфигурировать регистр сравнения, чтобы генерируемый выходной сигнал был в лог. 1, когда счетчик содержит значение меньшее, чем в этом регистре. Это также будет генерировать импульсы ШИМ, как это было в режиме Single Slope. Отличие в том, что генерируемый сигнал ШИМ получается синхронизированным по центру генерируемых импульсов.
Способ генерации ШИМ Dual Slope более точен, и поэтому лучше подходит для управления моторами. Однако его частота получается в 2 раза ниже, чем у Single Slope. В любом случае, частота ШИМ будет одинаковой у всех каналов сравнения, когда они используют один и тот же таймер.
Функция Arduino analogWrite() в режиме Dual Slope работает на микроконтроллере ATmega32U4 на таймерах 1, 3 и 4. Причина того, что Timer 0 не работает Dual Slope возможно в том, что Timer 0 используется для отслеживания реального времени, поэтому было бы сложно реализовать и на нем двухскатный принцип формирования ШИМ. В режиме двухскатного ШИМ все выводы, связанные с этим ШИМ, работают на половине частоты Timer 0, 488 Гц.
У Timer 1 есть три канала сравнения A, B и C, и соответствующие регистры сравнения OCR1A, OCR1B, OCR1C, связанные с входами OC1A, OC1B и OC1C. Программное обеспечение Arduino использует только каналы A и B, подключенные к портам Arduino 9 и 10. Канал C и его выход OC1C связан с тем же самым портом 11 Arduino, который управляется от Timer 0. По какой-то причине разработчики библиотек Arduino предпочли назначить управление выводом 11 через Timer 0 по принципу Single Slope вместо использования для этого порта Timer 1 в режиме Dual Slope.
Timer 3 имеет только один аппаратный выход OC3A на порту 5 Arduino, связанный с регистром сравнения OCR3A.
Timer 4 особенный, но в контексте ШИМ он работает в Dual Slope так же, как и таймеры 1 и 3. У Timer 4 есть аппаратные выходы OC4A, OC4B и OC4D, связанные с регистрами сравнения OCR4A, OCR4B и OCR4D. Библиотеки Arduino используют каналы A и D, связанные с выводами портов 13 и 6. Канал B связан с тем же самым портом, что и OC1B Timer 1. Разработчики Arduino выбрали управление этим выводом от Timer 1 вместо Timer 4.
Все это дает 7 выводов ШИМ, управляемых библиотеками Arduino.
[Fast PWM на Timer 1]
Если частоты 976 Гц, которую предлагает analogWrite из библиотек Arduino, недостаточно, то нам придется самостоятельно реализовать не низком уровне управление ШИМ. Timer 1 хороший кандидат, так как у него есть 3 канала сравнения, и он не будет пересекаться с функциями задержки Arduino. Следует иметь в виду, что библиотека Servo также использует Timer 1, поэтому при её использовании лучше выбрать другой таймер для ШИМ.
Timer 1 основан на 16-разрядном счетчике. Это означает, что он может считать от 0 до 65535 до возникновения переполнения. Этот таймер имеет несколько режимов работы, включая 12 режимов PWM. Самый быстрый PWM доступен в режиме Single Slope с разрядностью 8 бит, когда таймер считает от 0 до 255. Поскольку Single Slope быстрее, чем Dual Slope, этот режим также называется быстрым ШИМ (Fast PWM).
Вы также можете использовать режимы PWM разрядностью 9 и 10 бит (счет до 511 и до 1023 соответственно), которые могут работать в односкатном и двухскатном режимах. Три режима разрядности 8, 9 и 10 бит для Single Slope PWM и Single Slope PWM дают 6 режимов ШИМ. Еще 6 дополнительных режимов ШИМ дает программирование предельного счета до любого 16-разрядного значения, не ограничиваясь 255, 511 или 1023.
Таймер получает тактирование от глобального прескалера тактов микроконтроллера, что дает 5 вариантов частот тактирования, получаемых от системной частоты (у Arduino Leonardo это 16 МГц). Прескалер может делить системную частоту на 1 (т. е. нет деления), 8, 64, 256 и 1024. В таблице ниже показаны варианты частот тактирования и получающихся частот ШИМ для режима при использовании стандартных разрядностей 8, 9 и 10 бит:
Делитель
1
8
64
256
1024
Макс. значение счета
Частота тактов, Гц
16000000
2000000
250000
62500
15625
8 бит Fast PWM, Гц
62500
7812.5
976.6
244.1
61
256
9 бит Fast PWM, Гц
31250
3906.3
488.3
122.1
30.5
512
10 бит Fast PWM, Гц
15625
1953.1
244.1
61.0
15.3
1024
8 бит Dual Slope PWM, Гц
31250
3906.3
488.3
122.1
30.5
256
9 бит Dual Slope PWM, Гц
15625
1953.1
244.1
61.0
15.3
512
10 бит Dual Slope PWM, Гц
7812.5
976.6
122.1
30.5
7.6
1024
В режиме двухскатного ШИМ (Dual Slope PWM) максимальная частота ШИМ будет в 2 раза меньше. Из предыдущей таблицы мы видели, что максимальная частота ШИМ у Timer 1 составляет 62.5 кГц (Single Slope PWM). Это достаточно высокая частота для генерации аудиосигнала с помощью ШИМ.
Чтобы сконфигурировать Timer 1, мы должны запрограммировать регистры TCCR1A и TCCR1B.
• Bit 7:6 – COM1A1:0: Compare Output Mode for Channel A • Bit 5:4 – COM1B1:0: Compare Output Mode for Channel B • Bit 3:2 – COM1C1:0: Compare Output Mode for Channel C
Биты COM1A1:0, COM1B1:0 и COM1C1:0 управляют поведением выводов сравнения (OC1A, OC1B и OC1C соответственно). Если один или оба бита COM1A1:0 установлены в лог. 1, то выход OC1A заменяет обычный функционал порта GPIO на функционал ШИМ. То же самое относится и к битам COM1B1:0 и COM1C1:0, они по тому же самому принципу переназначают функционал портов GPIO для выводов, к которым относятся сигналы OC1B и OC1C. Однако имейте в виду, что регистр направления (Data Direction Register, DDR) должен иметь в лог. 1 биты, соответствующие разрядам OCnA, OCnB или OCnC, чтобы разрешить работу выходного драйвера для сигналов ШИМ.
Когда сигналы OC1A, OC1B или OC1C подключены к выводу порта, функция бит COM1A1:0, COM1B1:0 или COM1C1:0 зависит от настройки бит WGM13:0. Таблица 14-1 показывает функциональность бит COM1x1:0, когда биты WGM13:0 установлены в режим Normal или CTC (режимы не PWM).
Таблица 14-1. Compare Output Mode, не PWM.
COM1A1, COM1B1, COM1C1
COM1A0, COM1B0, COM1C0
Поведение выходов OC1A, OC1B, OC1C
0
0
Обычная работа порта, сигнал ШИМ отключен от OC1x.
0
1
Переключение в противоположное состояние OC1x при Compare Match.
1
0
Очистка OC1x при Compare Match (сброс в лог. 0).
1
1
Установка OC1x при Compare Match (установка в лог. 1).
Таблица 14-2 показывает функционал бит COM1x1:0, когда биты WGM13:0 установлены в режим Fast PWM.
Таблица 14-2. Compare Output Mode, Fast PWM(1).
COM1A1, COM1B1, COM1C1
COM1A0, COM1B0, COM1C0
Поведение выходов OC1A, OC1B, OC1C
0
0
Обычная работа порта, сигнал ШИМ отключен от OC1x.
0
1
При битах WGM13:0 в значении 14 или 15: переключение OC1A при Compare Match, OC1B и OC1C отключены (обычная работа порта GPIO). Для всех других настроек WGM1 обычная работа порта, сигналы ШИМ отключены от OC1x. См. таблицу 14-4.
1
0
Очистка OC1x при Compare Math, установка при достижении TOP.
1
1
Установка при Compare Match, очистка при достижении TOP.
Примечание (1). Специальный случай возникает, когда значение OCR1A, OCR1B, OCR1C равно TOP, и установлены биты COM1A1, COM1B1, COM1C1. В этом случае событие совпадения (Compare Match) игнорируется, но установка или очистка осуществляется на значении TOP. Подробнее см. описание "Fast PWM Mode" в даташите на микроконтроллер ATmega32U4.
Таблица 14-3 показывает функционал бит COM1x1:0, когда биты WGM13:0 установлены в режим Phase Correct and Frequency Correct PWM.
Таблица 14-3. Compare Output Mode, Phase Correct and Phase and Frequency Correct PWM(1).
COM1A1, COM1B1, COM1C1
COM1A0, COM1B0, COM1C0
Поведение выходов OC1A, OC1B, OC1C
0
0
Обычная работа порта, сигнал ШИМ отключен от OC1x.
0
1
При битах WGM13:0 в значении 8, 9. 10 или 11: переключение OC1A при Compare Match, OC1B и OC1C отключены (обычная работа порта GPIO). Для всех других настроек WGM1 обычная работа порта, сигналы ШИМ отключены от OC1x. См. таблицу 14-4.
1
0
Очистка OC1x при Compare Math, когда идет счет вверх. Установка OC1x при Compare Math, когда идет счет вниз.
1
1
Установка OC1x при Compare Match, когда идет счет вверх. Сброс при Compare Math, когда идет счет вниз.
Примечание (1). Специальный случай возникает, когда значение OCR1A, OCR1B, OCR1C равно TOP, и установлены биты COM1A1, COM1B1, COM1C1. Подробнее см. описание "Phase Correct PWM Mode" в даташите на микроконтроллер ATmega32U4.
• Bit 1:0 – WGM11:0: Waveform Generation Mode
Вместе с битами WGM13:2, которые находятся в регистре TCCR1B (см. врезку ниже), эти биты управляют последовательностью счета, источником максимального значения (TOP) счетчика, и какой будет использоваться тип генерации формы сигнала, см. таблицу 14-4. Режимы работы, поддерживаемые таймером/счетчиком: Normal mode (счетчик), Clear Timer on Compare match (CTC) mode (сброс таймера при совпадении), и три типа режимов ШИМ (Pulse Width Modulation, PWM). Подробнее см. "Modes of Operation" в даташите на микроконтроллер ATmega32U4.
Таблица 14-4. Описание бит режимов генерации (Waveform Generation).
Mode
WGM13:10
Режим работы таймера/счетчика
TOP
Когда произойдет обновление OCR1x
Когда установится флаг TOV1
0
0000
Normal
0xFFFF
Немедленно
MAX
1
0001
PWM, Phase Correct, 8-bit
0x00FF
TOP
BOTTOM
2
0010
PWM, Phase Correct, 9-bit
0x01FF
TOP
BOTTOM
3
0011
PWM, Phase Correct, 10-bit
0x03FF
TOP
BOTTOM
4
0100
CTC
OCR1A
Немедленно
MAX
5
0101
Fast PWM, 8-bit
0x00FF
TOP
TOP
6
0110
Fast PWM, 9-bit
0x01FF
TOP
TOP
7
0111
Fast PWM, 10-bit
0x03FF
TOP
TOP
8
1000
PWM, Phase and Frequency Correct
ICR1
BOTTOM
BOTTOM
9
1001
PWM, Phase and Frequency Correct
OCR1A
BOTTOM
BOTTOM
10
1010
PWM, Phase Correct
ICR1
TOP
BOTTOM
11
1011
PWM, Phase Correct
OCR1A
TOP
BOTTOM
12
1100
CTC
ICR1
Немедленно
MAX
13
1101
Зарезервировано
-
-
-
14
1110
Fast PWM
ICR1
TOP
TOP
15
1111
Fast PWM
OCR1A
TOP
TOP
Примечание: имена бит CTC1 и PWM11:0 устарели. Используйте вместо них имена WGM12:0. Однако функциональность этих бит и их размещение в регистрах совместимы с предыдущими версиями таймера.
Установка этого бита в лог. 1 активирует подавитель шума на входе захвата (Input Capture Noise Canceler). Когда активирован Noise Canceler, то сигнал с вывода Input Capture Pin (ICP1) проходит через цифровой фильтр. Функция фильтра требует, чтобы на входе появились друг за другом 4 одинаковые выборки уровня, чтобы было определено действительное изменение ICP1. Таким образом, захват по входу в случае фильтрации срабатывает с задержкой 4 такта системных тактов.
• Bit 6 – ICESn: Input Capture Edge Select
Этот бит выбирает, какой перепад на Input Capture Pin (ICP1) используется для срабатывания события захвата. Когда бит ICES1 записан в лог. 0, в качестве активного перепада используется переход логического уровня из 1 в 0, и когда ICES1 установлен в лог. 1, активным будет перепад нарастания (0 -> 1).
Когда сработал захват в соответствии с установкой бита ICES1, значение счетчика копируется в регистр захвата Input Capture Register (ICR1). Это событие также установит бит Input Capture Flag (ICF1), и это вызовет прерывание Input Capture Interrupt, если оно разрешено.
Когда ICR1 используется в качестве значения TOP (см. описание бит WGM13:0, которые находятся в регистрах TCCR1A и TCCR1B), то ICP1 отключается, и соответственно функция захвата по входу запрещена.
• Bit 5 – Reserved Bit
Этот бит зарезервирован для использования в будущем. Чтобы обеспечить совместимость с будущими микроконтроллерами, в него следует записывать 0, когда записывается регистр TCCR1B.
• Bit 4:3 – WGM13:2: Waveform Generation Mode
См. информацию по этим битам в описании регистра TCCR1A (врезка выше, таблица 14-4).
• Bit 2:0 – CS12:0: Clock Select
Эти три бита выбирают тактовую частоту для таймера счетчика, см. рис. 13-8 и 13-9 в даташите на микроконтроллер ATmega32U4.
Таблица 14-5. Описание бит выбора тактов.
CS12
CS11
CS10
Asynchronous Clocking Mode
0
0
0
Timer/Counter1 остановлен
0
0
1
clkI/O/1 (прескалер отключен)
0
1
0
clkI/O/8 (от выхода прескалера)
0
1
1
clkI/O/64 (от выхода прескалера)
1
0
0
clkI/O/256 (от выхода прескалера)
1
0
1
clkI/O/1024 (от выхода прескалера)
1
1
0
Внешний сигнал тактирования, поданный на вывод T1. Активный перепад 1->0.
1
1
1
Внешний сигнал тактирования, поданный на вывод T1. Активный перепад 0->1.
Если используется внешний вывод для тактирования Timer/Counter1, то перепады на выводе T1 все равно будут подсчитаны счетчиком, даже если T1 сконфигурирован как выход. Эта функция дает возможность программно управлять счетом.
Биты 0, 1 и 2 регистра TCCR1B (CS10, CS11 и CS12) управляют опциями тактирования таймера 1, как это показано в таблице 14-5 (см. выше врезку с описанием регистра TCCR1B).
Биты 0 и 1 регистра TCCR1A (WGM10, WGM11) и биты 3 и 4 (WGM12, WGM13) регистра TCCR1B конфигурируют вид формы генерации сигнала. Соответствующие настройки показаны в таблице 14-4 (см. описание регистра TCCR1A во врезке выше). Режимы 1, 2, 3, 5, 6 и 7 из таблицы 14-4 соответствуют стандартным режимам ШИМ.
После того, как таймер сконфигурирован в один из режимов ШИМ, каждый из трех каналов сравнения A, B и C можно разрешить для генерации сигнала PWM. Для этого нужно сконфигурировать биты COM1x0 и COM1x1 (x заменяется на A, B или C) регистра TCCR1A в соответствии с таблицей 14-2 (см. описание регистра TCCR1A).
Значение сравнения ШИМ для каждого канала следует запрограммировать в регистры OCR1A, OCR1B и OCR1C.
Конфигурирования бит TCCR1A недостаточно, чтобы сигналы ШИМ появились на выводах микроконтроллера. Нам также нужно сконфигурировать их в режим выхода. По цоколевке ATmega32U4 можно увидеть, что выходы OC1A, OC1B и OC1C связаны с разрядами портов PB5, PB6 и PB7 (соответствуют портам Arduino 9, 10 и 11). Таким образом, нужно настроить эти ножки портов как выходы, что делается программирование в лог. 1 разрядов PB5, PB6 и PB7 регистра DDRB.
[Fast PWM на Timer 4]
Используя таймеры 0, 1 или 3 мы можем получить сигналы ШИМ частотой импульсов до 62.5 кГц, но максимальной частоты ШИМ можно достичь только с помощью Timer 4.
Timer 4 это 10-разрядный таймер, который может работать на очень высокой скорости счета, потому что для него есть дополнительные варианты тактирования.
В микроконтроллере ATmega32U4 имеется периферийное устройство USB. Этот периферийное устройство требует для своей работы частоты 48 МГц, которая генерируется из 16 МГц системной частоты с помощью встроенной ФАПЧ (соответствующий английский аналог этого термина Phase Locked Loop, сокращенно PLL). В плате Arduino Leonardo PLL получает на входе 16 МГц системной тактовой частоты, и умножением на 6 получает 96 МГц.
Имейте в виду, что неправильная конфигурация PLL микроконтроллера Arduino Leonardo нарушит обмен данными через её интерфейс USB. Вам всего лишь следует знать, что PLL может предоставлять свой выходной сигнал для тактирования Timer 4.
Регистр PLLFRQ, управляющий конфигурацией PLL, имеет много других установок, но нас интересуют только биты PLLTM0 и PLLTM1, которые определяют входную тактовую частоту для Timer 4.
Этот бит выбирает входную тактовую частоту для PLL:
PINMUX = 0: вход PLL подключен к PLL Prescaler, который получает в качестве источника главную системную частоту (Primary System Clock).
PINMUX = 1: вход PLL напрямую подключен к внутреннему калиброванному RC-генератору 8 МГц. Этот режим позволяет работать USB Low Speed без использования внешнего кварцевого резонатора, или при использовании внешнего резонатора на частоту, отличающуюся от 8 или 16 МГц.
• Bit 6– PLLUSB: PLL Postcaler for USB Peripheral
Этот бит выбирает коэффициент деления между выходной частотой PLL и входной частотой модуля USB:
PLLUSB = 1: частота PLL Output делится на 2, и передается в модуль USB (если PLL Output = 96 МГц).
• Bit 5:4 – PLLTM1:0: PLL Postcaler for High Speed Timer
Эти биты кодируют коэффициент деления между выходной частотой ФАПЧ (PLL Output) и тактовым входом высокоскоростного таймера (High Speed Timer).
Имейте в виду, что коэффициент деления 1.5 вводит некоторый дополнительный джиттер в тактовую частоту, но связанная с этим ошибка близка к нулю, поскольку средняя скважность тактов 50% (см. рис. 6-7).
PLLTM1
PLLTM0
Коэффициент постскалера PLL для высокоскоростного таймера
0
0
0 (отключено)
0
1
1
1
0
1.5
1
1
2
Рис. 6-7. Работа PLL Postcaler с коэффициентом деления 1.5.
• Bit 3:0 – PDIV3:0 PLL Lock Frequency
Эти биты конфигурируют опорную частоту внутреннего генератора ФАПЧ, управляемого напряжением (PLL internal VCO clock reference) в соответствии с требуемой выходной частотой.
PDIV3
PDIV2
PDIV1
PDIV0
Выходная частота PLL
0
0
0
0
Не допускается
0
0
0
1
Не допускается
0
0
1
0
Не допускается
0
0
1
1
40 МГц
0
1
0
0
48 МГц
0
1
0
1
56 МГц
0
1
1
0
Не допускается
0
1
1
1
72 МГц
1
0
0
0
80 МГц
1
0
0
1
88 МГц
1
0
1
0
96 МГц
1
0
1
1
Не допускается
1
1
0
0
Не допускается
1
1
0
1
Не допускается
1
1
1
0
Не допускается
1
1
1
1
Не допускается
Оптимальная конфигурация PLL на 5V (выделено в таблице жирным шрифтом): PLL output = 96 МГц, поделенная на 1.5 для генерации тактов 64 МГц для High Speed Timer, и деленная на 2 для генерации тактовой частоты 48 МГц блока USB.
Есть 4 опции тактирования: не использовать PLL для тактирования таймера (тогда он будет получать системные такты), или использовать выход PLL, поделенный на 1, 1.5 или 2. Последние 3 варианта дадут тактовые частоты 96, 64 или 48 МГц.
У Timer 4 есть дополнительный делитель, конфигурируемый битами CS40 .. CS43 регистра TCCR4B (см. таблицу 15-14 из врезки ниже).
Когда этот бит установлен в лог. 1, выбирается режим инверсии ШИМ (PWM Inversion Mode), и инвертируются выходы Dead Time Generator, OC4x и ~OC4x.
• Бит 6 - PSR4: Prescaler Reset Timer/Counter4
Когда этот бит установлен в лог. 1, прескалер Timer/Counter4 будет сброшен (без влияния на TCNT4). Этот бит очистится аппаратно после завершения выполнения этой операции сброса прескалера. Запись в лог. 0 этого бита не оказывает никакого эффекта. Этот бит всегда читается как 0.
• Биты 5,4 - DTPS41, DTPS40: Dead Time Prescaler
Отдельный прескалер Dead Time, установленный перед Dead Time Generator, может делить частоту тактов Timer/Counter4 (PCK или CK) на коэффициенты 1, 2, 4 или 8, предоставляя тем самым большой диапазон регулировки интервалов мертвого времени. Прескалер Dead Time управляется двумя битами DTPS41 и DTPS40 регистра Dead Time Prescaler. Эти биты определяют коэффициент деления прескалера Dead Time (см. таблицу 15-13).
Таблица 15-13. Коэффициенты деления прескалера мертвого времени.
DTPS41
DTPS40
Коэффициент, на который прескалер делит частоту тактов Timer/Counter4
Установка этого бита в лог. 1 разрешает прерывание Fault Protection.
• Бит 6– FPEN4: Fault Protection Mode Enable
Установка этого бита в лог. 1 активирует Fault Protection Mode.
• Бит 5 – FPNC4: Fault Protection Noise Canceler
Установка этого бита в лог. 1 активирует Fault Protection Noise Canceler (подавитель помех сигнала срабатывания защиты). Когда подавитель помех активирован, вход вывода Fault Protection (INT0) проходит через цифровой фильтр. Эта функция требует четырех одинаковых значений, появившихся на выводе INT0, чтобы был обнаружен сигнал. Таким образом, срабатывание защиты Fault Protection имеет задержку на 4 такта системного генератора, когда функция подавителя помех активирована.
• Бит 4 – FPES4: Fault Protection Edge Select
Этот бит выбирает, какой перепад на выводе Fault Protection (INT0) будет использоваться как событие сигнала для срабатывания защиты. Когда в бит FPES4 записан лог. 0, активным сигналом будет спад уровня, и когда в бит FPES4 записана лог. 1, активным сигналом будет нарастание уровня.
• Бит 3 - FPAC4: Fault Protection Analog Comparator Enable
Когда в этот бит записана лог. 1, то разрешена функция Fault Protection для Timer/Counter4, срабатывающая от выхода аналогового компаратора. В этом случае выход этого компаратора напрямую подключается ко входу логики Fault Protection, при этом сигнал от компаратора использует те же функции подавителя помех и выбора перепада, как это работало со входом INT0. Когда в этот бит записан лог. 0, то между функцией Fault Protection и аналоговым компаратором соединение отсутствует. Чтобы компаратор вызвал срабатывание прерывания Timer/Counter4 Fault Protection, должен быть установлен бит FPIE4 регистра управления Timer/Counter4 Control Register D (TCCR4D).
• Бит 2 - FPF4: Fault Protection Interrupt Flag
Когда бит FPIE4 установлен в лог. 1, разрешено прерывание Fault Protection. Активность на этом выводе в любом случае вызовет запрос на прерывание, даже если вывод Fault Protection сконфигурирован как выход. Прерывание, соответствующее запросу Fault Protection Interrupt, запустится по адресу Fault Protection Interrupt Vector. Бит FPF4 очищается аппаратно, когда выполняется соответствующий вектор прерывания. Альтернативно FPF4 очищается после такта синхронизации путем записи лог. 1 в этот флаг. Когда когда установлен бит I регистра SREG, а также биты FPIE4 и FPF4, запустится обработчик прерывания Fault Protection.
Эти биты связаны с битом PWM4x для совместного управления последовательностью счета таймера и типом формируемого сигнала (см. таблицу 15-18).
Режимы работы, поддерживаемые Timer/Counter4: Normal mode (обычный режим, счетчик), Fast PWM Mode (быстрый ШИМ), Phase and Frequency Correct PWM (ШИМ повышенного качества) и PWM6 (режим для управления трехфазными бесколлекторными двигателями BLDC).
Таблица 15-18. Описание бит настройки режима Waveform Generation.
PWM4x
WGM41:40
Режим работы таймера/счетчика
TOP
Когда произойдет обновление OCR4x
Когда установится флаг TOV4
0
00
Normal
OCR4C
Немедленно
TOP
1
00
Fast PWM
OCR4C
TOP
TOP
1
01
Phase and Frequency Correct PWM
OCR4C
BOTTOM
BOTTOM
1
10
PWM6 / Single-slope
OCR4C
TOP
TOP
1
11
PWM6 / Dual-slope
OCR4C
BOTTOM
BOTTOM
Доступны опции Fast PWM, Phase and Frequency Correct PWM, PWM6 Single Slope и PWM6 Dual Slope (см. таблицу 15-18 врезки выше).
Обратите внимание, что для сигнала ШИМ максимальное значение счета определяется регистром OCR4C. Так как регистр OCR4C связан с пределом счета, он не зависит от выхода канала C ШИМ (у Timer 4 вообще нет канала C для ШИМ).
PWM6 это специальный режим PWM, который для управления BLDC двигателем использует сразу 3 канала ШИМ, A, B и D (подробнее см. [2]).
После конфигурирования входных тактов каждый из каналов x = A, B и D таймера 4 можно сконфигурировать своими отдельными битами COM4x0, COM4x1 и PWM4x, которые находятся в регистрах TCCR4A и TCCR4C. Как уже упоминалось, канал C использует для задания предела счета, и у него нет блока выхода для генерации сигнала ШИМ.
Эти биты управляют поведением выхода генератора сигналов Waveform Output (OCW4A) и подключением вывода Output Compare (OC4A). Если установлены оба бита COM4A1:0, то выход OC4A отменяет обычный функционал порта GPIO, к которому OC4A подключен. Комплементарный выход ~OC4A подключается только в режимах PWM, когда биты COM4A1:0 установлены в 01. Обратите внимание, что биты регистра направления (DDR), соответствующие сигналам OC4A и ~OC4A, должны быть установлены, чтобы заработал выходной драйвер этих сигналов.
Функция бит COM4A1:0 зависит от настроек бит PWM4A, WGM40 и WGM41. Таблица 15-5 показывает функциональность бит COM4A1:0, когда установлен бит PWM4A, в обычном режиме (Normal Mode, не PWM).
Таблица 15-5. Compare Output Mode, Normal Mode (не PWM).
COM4A1
COM4A0
Поведение OCW4A
Выв. OC4A
Выв. ~OC4A
0
0
Обычная работа порта
Отключен
Отключен
0
1
Переключение при Compare Match
Подключен
Отключен
1
0
Очистка при Compare Match
Подключен
Отключен
1
1
Установка при Compare Match
Подключен
Отключен
Таблица 15-6 показывает функциональность бит COM4A1:0, когда биты PWM4A, WGM40 и WGM41 установлены в режим быстрого ШИМ.
Таблица 15-6. Compare Output Mode, Fast PWM Mode.
COM4A1
COM4A0
Поведение OCW4A
Выв. OC4A
Выв. ~OC4A
0
0
Обычная работа порта
Отключен
Отключен
0
1
Очистка при Compare Match, установка при TCNT4=0x000
Подключен
Подключен
1
0
Подключен
Отключен
1
1
Установка при Compare Match, очистка при TCNT4=0x000
Подключен
Отключен
Таблица 15-7 показывает функциональность бит COM4A1:0, когда биты PWM4A, WGM40 и WGM41 установлены в режим Phase and Frequency Correct PWM.
Таблица 15-7. Compare Output Mode, Phase and Frequency Correct PWM Mode.
COM4A1
COM4A0
Поведение OCW4A
Выв. OC4A
Выв. ~OC4A
0
0
Обычная работа порта
Отключен
Отключен
0
1
Очистка при Compare Match и счете вверх, установка при Compare Match и счете вниз
Подключен
Подключен
1
0
Подключен
Отключен
1
1
Установка при Compare Match и счете вверх, очистка при Compare Match и счете вниз
Подключен
Отключен
Таблица 15-8 показывает функциональность бит COM4A1:0, когда биты PWM4A, WGM40 и WGM41 установлены в односкатный режим PWM6. В режиме PWM6 используется один и тот же сигнал Waveform Output (OCW4A) для генерации всех сигналов, и значения Output Compare OC4A и ~OC4A подключены к выводам OC4A, ~OC4A, OC4B, ~OC4B, OC4D и ~OC4D.
Очистка при Compare Match и счете вверх, установка при Compare Match и счете вниз
OC4A
~OC4A
1
0
OC4A
OC4A
1
1
Установка при Compare Match и счете вверх, очистка при Compare Match и счете вниз
OC4A
OC4A
• Биты 5,4 - COM4B1, COM4B0: Comparator B Output Mode
Эти биты управляют поведением выхода генератора сигнала Waveform Output (OCW4B), и подключается в ножке Output Compare (OC4B). Если один или оба бита COM4B1:0 установлены, то выход OC4B отменяет нормальный функционал порта GPIO вывода микроконтроллера, к которому подключен OC4B. Комплементарный выход ~OC4B подключен только в режимах PWM, когда биты COM4B1:0 установлены в 01. Обратите внимание, что биты регистра направления (DDR), соответствующие сигналу OC4B, должны быть установлены, чтобы разрешить работу выходного драйвера.
Функция бит COM4B1:0 зависит от настроек бит PWM4B и WGM40.
Таблица 15-10 показывает функциональность бит COM4B1:0, когда бит PWM4B установлен в режим Normal (не PWM).
Таблица 15-10. Compare Output Mode, Normal Mode (не PWM).
COM4B1
COM4B0
Поведение OCW4B
Выв. OC4B
Выв. ~OC4B
0
0
Обычная работа порта
Отключен
Отключен
0
1
Переключение при Compare Match
Подключен
Отключен
1
0
Очистка при Compare Match
Подключен
Отключен
1
1
Установка при Compare Match
Подключен
Отключен
Таблица 15-11. Показывает функциональность бит COM4B1:0, когда биты PWM4B и WGM40 установлены в режим Fast PWM.
Таблица 15-11. Compare Output Mode, Fast PWM Mode.
COM4B1
COM4B0
Поведение OCW4B
Выв. OC4B
Выв. ~OC4B
0
0
Обычная работа порта
Отключен
Отключен
0
1
Очистка при Compare Match, установка при TCNT4=0x000
Подключен
Подключен
1
0
Подключен
Отключен
1
1
Установка при Compare Match, очистка при TCNT4=0x000
Подключен
Отключен
Таблица 15-12 показывает функциональность бит COM4B1:0, когда биты PWM4B и WGM40 установлены в режим Phase and Frequency Correct PWM.
Таблица 15-12. Compare Output Mode, Phase and Frequency Correct PWM Mode.
COM4B1
COM4B0
Поведение OCW4B
Выв. OC4B
Выв. ~OC4B
0
0
Обычная работа порта
Отключен
Отключен
0
1
Очистка при Compare Match и счете вверх, установка при Compare Match и счете вниз
Подключен
Подключен
1
0
Подключен
Отключен
1
1
Установка при Compare Match и счете вверх, очистка при Compare Match и счете вниз
Подключен
Отключен
• Бит 3 - FOC4A: Force Output Compare Match 4A
Бит FOC4A активен только когда бит PWM4A задает режим не PWM.
При записи лог. 1 в этот бит принудительно меняется сигнал Waveform Output (OCW4A) и вывод Output Compare (OC4A) в соответствии со значениями, уже установленными в COM4A1 и COM4A0. Если COM4A1 и COM4A0 записаны в том же цикле, что и FOC4A, то будут использоваться новые установки. Бит Force Output Compare может использоваться для изменения значения выходного вывода, не обращая внимание на значение таймера. Произойдет автоматическое действие, запрограммированное COM4A1 и COM4A0, как если бы произошло событие совпадения, но при этом не будет сгенерировано прерывание.
Бит FOC4A всегда читается как 0.
• Бит 2 - FOC4B: Force Output Compare Match 4B
Бит FOC4B активен только когда бит PWM4B задает режим не PWM.
При записи лог. 1 в этот бит принудительно меняется сигнал Waveform Output (OCW4B) и вывод Output Compare (OC4B) в соответствии со значениями, уже установленными в COM4B1 и COM4B0. Если COM4B1 и COM4B0 записаны в том же цикле, что и FOC4B, то будут использоваться новые установки. Бит Force Output Compare может использоваться для изменения значения выходного вывода, не обращая внимание на значение таймера. Произойдет автоматическое действие, запрограммированное COM4B1 и COM4B0, как если бы произошло событие совпадения, но при этом не будет сгенерировано прерывание.
Бит FOC4B всегда читается как 0.
• Бит 1 - PWM4A: Pulse Width Modulator A Enable
Когда этот бит установлен в лог. 1, то разрешается режим PWM, основанный на компараторе OCR4A.
• Бит 0 - PWM4B: Pulse Width Modulator B Enable
Когда этот бит установлен в лог. 1, то разрешается режим PWM, основанный на компараторе OCR4B.
• Биты 7,6 - COM4A1S, COM4A0S: Comparator A Output Mode
Эти биты затеняют биты COM4A1 и COM4A0, как это указано в описании регистра TCCR4A – Timer/Counter4 Control Register A (см. врезку выше).
• Биты 5,4 - COM4B1S, COM4B0S: Comparator B Output Mode
Эти биты затеняют биты COM4B1 и COM4B0, как это указано в описании регистра TCCR4A – Timer/Counter4 Control Register A (см. врезку выше).
• Биты 3,2 - COM4D1, COM4D0: Comparator D Output Mode
Эти биты управляют поведением выхода генератора сигнала Waveform Output (OCW4D) и подключением к выводу Output Compare (OC4D). Если один или оба бита COM4D1:0 установлены, то выход OC4D отменяет функциональность ножек порта GPIO, к которым подключается сигнал OC4D. Комплементарный выход ~OC4D подключается только в режимах PWM, когда биты COM4D1:0 установлены в 01. Обратите внимание, что биты регистра направления (DDR), соответствующие ножкам OC4D, должны быть установлены, чтобы разрешить работу выходного драйвера.
Функция бит COM4D1:0 зависит от настроек бит PWM4D и WGM40.
Таблица 15-15 показывает функционал бит COM4D1:0, когда бит PWM4D установлен в режим Normal (не PWM).
Таблица 15-15. Compare Output Mode, Normal Mode (не PWM).
COM4D1
COM4D0
Поведение OCW4D
Выв. OC4D
Выв. ~OC4D
0
0
Обычная работа порта
Отключен
Отключен
0
1
Переключение при Compare Match
Подключен
Отключен
1
0
Очистка при Compare Match
Подключен
Отключен
1
1
Установка при Compare Match
Подключен
Отключен
Таблица 15-16 показывает функционал бит COM4D1:0, когда биты PWM4D и WGM40 установлены в режим быстрого ШИМ.
Таблица 15-16. Compare Output Mode, Fast PWM Mode.
COM4D1
COM4D0
Поведение OCW4D
Выв. OC4D
Выв. ~OC4D
0
0
Обычная работа порта
Отключен
Отключен
0
1
Очистка при Compare Match, установка при TCNT4=0x000
Подключен
Подключен
1
0
Подключен
Отключен
1
1
Установка при Compare Match, очистка при TCNT4=0x000
Подключен
Отключен
Таблица 15-17 показывает функциональность бит COM4D1:0, когда биты PWM4D и WGM40 установлены в режим Phase and Frequency Correct PWM.
Таблица 15-17. Compare Output Mode, Phase and Frequency Correct PWM Mode.
COM4D1
COM4D0
Поведение OCW4D
Выв. OC4D
Выв. ~OC4D
0
0
Обычная работа порта
Отключен
Отключен
0
1
Очистка при Compare Match и счете вверх, установка при Compare Match и счете вниз
Подключен
Подключен
1
0
Подключен
Отключен
1
1
Установка при Compare Match и счете вверх, очистка при Compare Match и счете вниз
Подключен
Отключен
• Бит 1 - FOC4D: Force Output Compare Match 4D
Бит FOC4D активен только когда бит PWM4D задает режим не PWM.
При записи лог. 1 в этот бит принудительно меняется сигнал Waveform Output (OCW4D) и вывод Output Compare (OC4D) в соответствии со значениями, уже установленными в COM4D1 и COM4D0. Если COM4D1 и COM4D0 записаны в том же цикле, что и FOC4D, то будут использоваться новые установки. Бит Force Output Compare может использоваться для изменения значения выходного вывода, не обращая внимание на значение таймера. Произойдет автоматическое действие, запрограммированное COM4D1 и COM4D0, как если бы произошло событие совпадения, но при этом не будет сгенерировано прерывание.
Бит FOC4D всегда читается как 0.
• Бит 0 - PWM4D: Pulse Width Modulator D Enable
Когда этот бит установлен в лог. 1, то разрешается режим PWM, основанный на компараторе OCR4D.
Чтобы один канал x заработал в режиме ШИМ, нужно установить в лог. 1 соответствующий бит PWM4x. После этого биты COM4x0 и COM4x1 будут определять режим работы ШИМ. В случае канала A режим Fast PWM можно выбрать по таблице 15-6 (см. выше врезку с описанием регистра TCCR4A).
В скетче Arduino, показанном ниже, собраны все режимы генерации ШИМ на основе Fast PWM. В скетче имеется код, необходимый для работы 5 выводов портов, связанных с таймерами 1 и 4 в режимах Fast PWM. Этот скетч доступен на GitHub [3].
/********************************************************** Fast PWM TestДемонстрируется генерация быстрого ШИМ на таймерах 1 и 4.Состоит из двух частей кода. Одна использует TIMER1,и генерирует ШИМ на портах 9, 10 и 11 с частотамипериода до 62 кГц. Вторая часть использует TIMER4,формируя ШИМ на портах 6 и 13 с частотами периодадо 187 кГц.История версий: 12/12/2014 - Version 1.0. 22/12/2014 - Добавлено пропущенное значение OCR4C. ***********************************************************//********************************************************** Fast PWM на портах 9, 10, 11 (TIMER1) Не используйте функцию analogWrite для портов 9, 10 или 11, если используете эти функции, так как analogWrite использует тот же таймер на этих портах. Эти функции скорее всего будут конфликтовать с библиотекой servo. Используется 5 частот ШИМ между 61 Гц и 62.5 кГц.**********************************************************/// Частотные режимы для TIMER1:#define PWM62k 1 //62500 Гц#define PWM8k 2 // 7812 Гц#define PWM1k 3 // 976 Гц#define PWM244 4 // 244 Гц#define PWM61 5 // 61 Гц// Макросы для непосредственного изменения скважности ШИМ:#define PWM9 OCR1A#define PWM10 OCR1B#define PWM11 OCR1C// Конфигурация тактирования ШИМ.// В аргументе указывается один из пяти определенных// макросами режимов (1..5).voidpwm91011configure(int mode)
{
// Конфигурация TCCR1A// 00 : Канал A запрещен (порт 9)// 00 : Канал B запрещен (порт 10)// 00 : Канал C запрещен (порт 11)// 01 : Fast PWM 8 bit
TCCR1A=1;
// Конфигурация TCCR1B// Режим тактирования и Fast PWM 8 bit
TCCR1B=mode|0x08;
// Конфигурация TCCR1C
TCCR1C=0;
}
// Устанавливает ШИМ на порту 9// В аргументе передается скважность ШИМ от 0 до 255voidpwmSet9(int value)
{
OCR1A=value; // Установка значения ШИМ
DDRB|=1<<5; // Настройка на выход ножки порта PB5
TCCR1A|=0x80; // Активация канала
}
// Устанавливает ШИМ на порту 10// В аргументе передается скважность ШИМ от 0 до 255voidpwmSet10(int value)
{
OCR1B=value; // Установка значения ШИМ
DDRB|=1<<6; // Настройка на выход ножки порта PB6
TCCR1A|=0x20; // Активация канала
}
// Устанавливает ШИМ на порту 11// В аргументе передается скважность ШИМ от 0 до 255voidpwmSet11(int value)
{
OCR1C=value; // Установка значения ШИМ
DDRB|=1<<7; // Настройка на выход ножки порта PB7
TCCR1A|=0x08; // Активация канала
}
/********************************************************** Fast PWM на портах 6, 13 (High Speed TIMER4) Не используйте функцию analogWrite для портов 6 или 13, если используете эти функции, потому что analogWrite использует тот же таймер для этих портов. Эта функция будет конфликтовать с библиотекой MSTIMER2. Используется 7 частот ШИМ в диапазоне от 2930 Гц до 187.5 кГц. TIMER4 использует для входного тактирования PLL, благодаря чему его тактовая частота может быть до 96 МГц на стандартной плате Arduino Leonardo. Автор ограничил входную частоту значением 48 МГц для генерации ШИМ на частоте периода 187.5 кГц. Если необходимо, то частота ШИМ может быть удвоена и достичь 375 кГц.**********************************************************/// Частотные режимы для TIMER4#define PWM187k 1 // 187500 Гц#define PWM94k 2 // 93750 Гц#define PWM47k 3 // 46875 Гц#define PWM23k 4 // 23437 Гц#define PWM12k 5 // 11719 Гц#define PWM6k 6 // 5859 Гц#define PWM3k 7 // 2930 Гц// Макросы для непосредственного изменения скважности ШИМ:#define PWM6 OCR4D#define PWM13 OCR4A// Сюда записывается предел счета:#define PWM6_13_MAX OCR4C// Конфигурация тактирования ШИМ.// В аргументе указывается один из семи определенных// макросами режимов (1..7).voidpwm613configure(int mode)
{
// Конфигурация TCCR4A
TCCR4A=0;
// Конфигурация TCCR4B
TCCR4B=mode;
// Конфигурация TCCR4C
TCCR4C=0;
// Конфигурация TCCR4D
TCCR4D=0;
// Конфигурация PLL// Используется частота 96 / 2 = 48 МГц
PLLFRQ=(PLLFRQ&0xCF)|0x30;
// Этот вариант настройки удваивает все частоты:// PLLFRQ=(PLLFRQ&0xCF)|0x10;// Предел счета для ШИМ TIMER4
OCR4C=255;
}
// Устанавливает ШИМ на порту 6 (канал D TIMER4)// В аргументе передается скважность ШИМ от 0 до 255voidpwmSet6(int value)
{
OCR4D=value; // Установка значения ШИМ
DDRD|=1<<7; // Настройка на выход ножки порта PD7
TCCR4C|=0x09; // Активация канала
}
// Устанавливает ШИМ на порту 13 (канал A TIMER4)// В аргументе передается скважность ШИМ от 0 до 255voidpwmSet13(int value)
{
OCR4A=value; // Установка значения ШИМ
DDRC|=1<<7; // Настройка на выход ножки порта PC7
TCCR4A=0x82; // Активация канала
}
/************** Дополнительные определения ****************/// Макрос преобразует скважность в процентах (0..100)// в значение сравнения для ШИМ (0..255)#define DUTY2PWM(x) ((255*(x))/100)/**********************************************************/// Функция первоначального запуска демонстрационного кода.// Генерируется 4 сигнала ШИМ, два постоянных, и два// с изменяющейся скважностью.voidsetup()
{
// Конфигурирование TIMER1 (порты 9, 10 и 11)// Он может генерировать ШИМ на частоте 62 кГц.// Допустимые параметры для настройки:// PWM62k, PWM8k, PWM1k, PWM244 and PWM61
pwm91011configure(PWM62k);
// Конфигурирование TIMER4 (порты 6 и 13)// Он может генерировать ШИМ на частоте 187 кГц.// Допустимые параметры для настройки:// PWM187k, PWM94k, PWM47k, PWM23k, PWM12k, PWM6k and PWM3k
pwm613configure(PWM187k);
// Запуск генерации ШИМ на порте 11 со скважностью// 30%. Перед этим вызовом требуется обязательно// вызвать pwm91011configure. Здесь демонстрируется// использование макроса DUTY2PWM.
pwmSet11(DUTY2PWM(30));
// Запуск генерации ШИМ на выводе 13 со скважностью// 75%. Перед этим вызовом требуется обязательно// вызвать pwm613configure. Здесь не используется// макрос DUTY2PWM для установки скважности в %,// вместо этого указывает прямое значение // сравнения (может быть в диапазоне 0..255).
pwmSet13(192);
// Порты 9 и 6 будут менять значения скважности// в цикле loop. Здесь они предварительно// конфигурируются.// Подготовка вывода 9 для использования ШИМ.// Перед этим вызовом требуется обязательно// вызвать pwm91011configure. Здесь мы настраиваем// начальную скважность ШИМ 0%.
pwmSet9(0);
// Подготовка вывода 6 для использования ШИМ.// Перед этим вызовом требуется обязательно// вызвать pwm613configure. Здесь мы настраиваем// начальную скважность ШИМ 0%.
pwmSet6(0);
}
int value=0;
voidloop()
{
// Установка значения скважности ШИМ для портов 9 и 6:
PWM9=value;
PWM6=value;
// Инкремент значения скважности ШИМ и переход к 0 после// достижения значения 255:
value=(value+1)%256;
// Небольшая задержка 10 мс:
delay(10);
}
Код Timer 1. Этот код включает 4 функции и соответствующие определения. Используются все три канала сравнения Timer 1 для генерации сигналов ШИМ на портах Arduino 9, 10 и 11.
Функция pwm91011configure должна быть предварительно вызвана, чтобы можно было воспользоваться любыми другими функциями, связанными с этим таймером. Она сконфигурирует таймер для работы в режиме Single Slope Fast PWM, и установит прескалер в режим, указанный в аргументе функции. Есть 5 возможных режимов PWM62k, PWM8k, PWM1k, PWM244 и PWM61, связанных с четырьмя доступными частотами режимов Single Slope 8 bit PWM.
Функции pwmSet9, pwmSet10 и pwmSet11 конфигурируют каналы Timer 1, связанные с выводами портов 9, 10 и 11 для запуска режима ШИМ и установки значения ШИМ (от 0 до 255).
После того, как будет вызвана одна из трех вышеуказанных функций, значение ШИМ может быть быстро изменено прямым доступом к соответствующему регистру сравнения канала. Для упрощения доступа сделаны три определения PWM9, PWM10 и PWM11, связанные с регистрами OCR1A, OCR1B и OCR1C.
Код Timer 4. Этот код включает 3 функции и несколько определений. Используется два из трех доступных каналов сравнения A и D, связанных с портами Arduino 13 и 6. Канал B не используется, потому что он конфликтует с портом 10 Arduino, который используется в канале B Timer 1.
Функция pwm613configure подобна аналогичной, определенной для Timer 1. Она установит режимы PLL и PWM для правильного конфигурирования Timer 4 в высокоскоростном режиме 48 МГц PLL, и установит предел счета в регистре OCR4C установкой всех его 8 бит (значение 255).
Входной аргумент установит один из семи доступных частот прескалера для 48 МГц на тактовом входе Timer 4: PWM187k (187500 Гц), PWM94k (93750 Гц), PWM47k (46875 Гц), PWM23k (23437 Гц), PWM12k (11719 Гц), PWM6k (5859 Гц) и PWM3k (2930 Гц). Если Вы помните, у Timer 4 есть 15 опций прескалера тактов. Нижняя частота не реализована в этих определениях, поскольку она не дает никаких преимуществ перед функционалом стандартной функции analogWrite.
Функции pwmSet13 и pwmSet6 конфигурируют каналы Timer 4, связанные с портами 13 и 6 Arduino, чтобы они работали в режиме ШИМ, и устанавливает значение для ШИМ (от 0 до 255).
Подобно тому, как это делается для таймера 1, посте того, как одна из этих двух функций будет вызвана, значение ШИМ может быть быстро изменено прямым доступом к соответствующему регистру сравнения. Для этой цели сделаны два определения PWM13 и PWM6, связанные соответственно с регистрами сравнения OCR4A и OCR4D. Добавлено дополнительное определение PWM6_13_MAX для доступа к регистру OCR4C, что установит предельное значение счета ШИМ (по умолчанию установлено 255, что дает разрешающую способность ШИМ 8 бит).
Код Setup и Loop. Для проверки работы всех этих функций Timer 1 сконфигурирован в функции setup для генерации сигналов ШИМ на частоте 62.5 кГц. Timer 4 сконфигурирован на частоту 187 кГц. Генерируется 4 сигнала ШИМ. На выводах портов 11 и 13 установлены значения скважности ШИМ 11% и 75%. Для выводов портов 6 и 9 в функции loop программируется переменное значение скважности ШИМ от 0% до 100%.
Форма сгенерированных сигналов ШИМ. На следующей картинке показаны полученные сигналы ШИМ, захвачены логическим анализатором.
Сигналы Timer 1 на выводах портов 9 и 11 имеют одинаковый фронт нарастания уровня, потому что они работают на одном и том же таймере и в одинаковом режиме. То же самое относится и к портам 6 и 13, сигналы на которых генерируются Timer 4. Сигналы ШИМ разных таймеров имеют разные частоту, поэтому фронт нарастания уровня сигналов ШИМ не совпадает у разных таймеров.
Это простой пример программирования микроконтроллера ATmega32U4 на языке C. Микроконтроллер установлен на плате AVR-USB32U4 [4] (аналог Arduino Leonardo). Пищалка (пьезокерамический излучатель звука) подключен к выходу канала B таймера 4, это ножки портов PB5 (~OC4B) и PB6 (OC4B).
Таймер 4 тактируется от системной тактовой частоты 16 МГц, поделенной на 256. ШИМ настраивается в 10-битном режиме Fast PWM, с противофазным формированием сигнала на ~OC4B и OC4B. Генерация пищания запускается функцией Beep, длительность генерации звука отслеживается обработчиком beephandler, который должен вызваться каждые 10 мс.
Заголовочный файл beep.h:
#ifndef __BEEP__
#define __BEEP__
#include "types.h"
#define BEEP_DDR DDRB
#define BEEP_PORT PORTB
#define BEEP_PHASE_A PB5
#define BEEP_PHASE_B PB6
#define BEEP_NONE 0
#define BEEP_START 1
#define BEEP_PROGRESS 2
voidBeep (u16 hz, u16 ms);
voidbeephandler (void);
#endif
Модуль кода beep.c:
#include < avr/io.h>
#include "beep.h"
#include "pins.h"
static u16 beeptimems =0;
static u8 beepstate = BEEP_NONE;
//Запрет таймера 4, в биты CS43, CS42, CS41, CS40 нужно записать 0000: