На этом уроке мы познакомимся с принципами широтной модуляции (ШИМ, PWM). Научимся регулировать скорость вращения нашего двигателя. Добавим первый орган управления «ручку газа».
А начнём мы наше путешествие с теории сигналов. Как известно вывод линии порта нашего МК может пребывать в 2-х состояниях +5В и 0В. Наш сигнал меняется раз в две секунды… попробуем изобразить это графически!
На графике вы видите периодический прямоугольный сигнал, положительной полярности, амплитудой A = +5В, частотой 0,25Гц, длительностью импульса tи = 2сек, длительностью паузы tп = 2сек, периодом Т = 4сек, скважностью Q = 2, сигнал вида, когда длительность импульса и длительность паузы равны называется «меандр». Давайте разберёмся с этими параметрами! Обозначим их на графике…
Как вы заметили из графика мы можем определить tи, tп, A и T. Период T вычисляется как сумма длительностей импульса и паузы T = tи + tп = 2сек + 2сек = 4сек. Частота сигнала вычисляется следующей формулой f = 1/T и равняется f = 1/4сек = 0,25Гц. Скважность определяется как отношение периода к длительности импульса Q = T/tи = 4сек/2сек = 2 (безразмерная величина).
Понятие скважности, на первых порах, трудно для понимания. Упростим задачу, будем оперировать так называемым коэффициентом заполнения, выраженном в процентах.
Ну и как же, скажете Вы, можно изменять скорость мотора при помощи такого сигнала? Оказывается ещё как можно, даже проигрывать музыку!
И поможет нам в этом Широтно-Импульсная Модуляция (ШИМ).
Допустим, что линия порта управляет яркостью светодиода. Выход микроконтроллера переключается между землёй и Vcc с частотой 1кГц и скважностью Q = 2. Глаз не замечает мерцания более 50 Гц, поэтому нам кажется, что светодиод не мерцает, а горит в пол силы. Аналогично, разогнанный мотор не может остановить вал за миллисекунды, поэтому ШИМ сигнал заставит вращаться его в неполную силу.
Коэффициент заполнения 10% — эквивалент 0,5 В
Коэффициент заполнения 50% — эквивалент 2,5 В
Коэффициент заполнения 90% — эквивалент 4,5 В
Теперь нужно определиться с органами управления.
Говоря о ШИМ управлении двигателем, мы естественно подразумеваем пропорциональное управление. Конечно, кнопка здесь не подойдёт. В аппаратуре радиоуправления используются аналоговые и цифровые джойстики.
Аналоговый джойстик представляет собой переменный резистор, измеренное сопротивление которого МК преобразует в сигнал управления приводом.
С цифровым джойстиком принцип тот же, за исключением того, что джойстик и МК общаются посредством цифрового интерфейса, I2C или SPI.
Есть, конечно, соблазн изучить эти интерфейсы, но они достаточно широко описаны в интернете, да и цена цифровых джойстиков не радует.
Я решил использовать переменный резистор. Это бюджетно, в конце концов, мы разберёмся с АЦП.
Итак, программа будет работать следующим образом. На переменный резистор («ручку газа») поступает опорное напряжение +5В. МК измеряет напряжение с вывода бегунка переменного резистора (0В – двигатель остановлен, +5В – двигатель работает на максимуме). Это напряжение преобразуется в эквивалентное значение скважности. Один из таймеров МК работает в режиме ШИМ и формирует цифровую последовательность на соответствующем выводе. Вот схема…
Приступаем к написанию программы!
Первым делом заведём таймер в режиме ШИМ. Будем использовать 8-bit Timer/Counter2 with PWM. Данный таймер формирует ШИМ последовательность на линии PB3/OC2. Эту линию необходимо настроить на выход…
DDRB |= (1<< PB3); //Настраиваем линию порта PB3/OC2 на вывод
Для работы с таймером настроим его…
В регистре настройки таймера включим режим быстрой ШИМ: Bit 6,3 = 1; разрешим формирование ШИМ на линии PB3/OC2: Bit 5 = 1, Bit 4 = 0; выберем предделитель, кстати, это действие также включит наш таймер. Коэффициент деления предделителя равен 128: Bit 2 = 0, Bit 1 = 0, Bit = 1…
TCCR2 = (0<< FOC2)| // Bit 7 – Force Output Compare
(1<< WGM20)| // Bit 6 – Waveform Generation Mode
(1<< COM21)| // Bit 5 – Compare Match Output Mode
(0<< COM20)| // Bit 4 – Compare Match Output Mode
(1<< WGM21)| // Bit 3 – Waveform Generation Mode
(1<< CS22)| // Bit 2 – Clock Select
(0<< CS21)| // Bit 1 – Clock Select
(1<< CS20); // Bit 0 – Clock Select
Теперь подключим нашу «ручку газа», для этого заведём наш АЦП. Как и таймер, АЦП нужно настроить. Ручку газа будем подключать к линии АЦП PC0/ADC0. Эту линию необходимо настроить на вход…
DRC &= ~(1<< PC0); //Настраиваем линию порта PCO/ADC0 на вход
В регистре управления АЦП выберем источник опорного напряжения (ИОН): опорное напряжение задаётся выводом AREF, внутренний ИОН отключён: Bit 7,6 = 0; для стабилизации измеренного значения вид представления результата измерения выберем левосторонний: Bit 5 = 1; используем аналоговый канал PC0/ADC0: Bit 3 = 0, Bit 2 = 0, Bit 1 = 0, Bit 0 = 0…
ADMUX = (0<< REFS1)| // Bit 7 – Reference Selection Bits
(0<< REFS0)| // Bit 6 – Reference Selection Bits
(1<< ADLAR)| // Bit 5 – ADC Left Adjust Result
(0<< MUX3)| // Bit 3 – Analog Channel and Gain Selection Bits
(0<< MUX2)| // Bit 2 – Analog Channel and Gain Selection Bits
(0<< MUX1)| // Bit 1 – Analog Channel and Gain Selection Bits
(0<< MUX0); // Bit 0 – Analog Channel and Gain Selection Bits
Далее необходимо включить модуль АЦП: Bit 7 = 1; выбрать предделитель частоты входной синхронизации АЦП, установим низкую частоту, коэффициент деления 128: Bit 2 = 1, Bit 1 = 1, Bit 7 = 1; включить режим автоматического перезапуска АЦП: Bit 5 = 1; запустить преобразование: Bit 6 = 1.
ADCSRA = (1<< ADEN)| // Bit 7 – ADC Enable
(1<< ADSC)| // Bit 6 – ADC Start Conversion
(1<< ADFR)| // Bit 5 – ADC Free Running Select
(0<< ADIE)| // Bit 3 – ADC Interrupt Enable
(1<< ADPS2)| // Bit 2 – ADC Prescaler Select Bits
(1<< ADPS1)| // Bit 1 – ADC Prescaler Select Bits
(1<< ADPS0); // Bit 0 – ADC Prescaler Select Bits
Ну а теперь разберёмся как и что мы будем измерять. Таймер формирует ШИМ последовательность с частотой:
N – это коэффициент предделителя.
Разрешение 10 битного АЦП – 1024 инженерные единицы, ИЕ (в двоичной системе 0b0000001111111111, в шестнадцатеричной системе 0х03FF, в десятичной системе 1024). Зная опорное напряжение и разрядность АЦП вычислим цену деления одной инженерной единицы. Разделим опорное напряжение на разрешение АЦП: +5В/1024ИЕ = 0,00488В.
К примеру, намерил что-то там наш АЦП 0x0312, что в десятичной системе равно 786… что это?? А мы возьмём да и умножим ИЕ на цену деления.… И вот получилось уже более понятное значение напряжения в 3,84В.
10 бит не умещаются в один байт. Регистр ADC, в котором хранится результат измерения, имеет размер два байта. Выглядит это так 0b0000 0011 1111 1111 (пробелы для наглядности, старший байт – одинарное подчёркивание, младший байт подчеркивание с курсивом).
К этим байтам можно обращаться по-отдельности, называются они ADCH и ADCL. Если мы попытаемся измерить +5В, АЦП в идеале выдаст 1024ИЕ, в регистре результата окажется ADC = 0х03FF, в старшем регистре ADCH = 0х03, в младшем ADCL = 0хFF. Два старших бита, расположены в старшем регистре результата ADCH, а восемь младших бит в младшем ADCL. Такое расположение результата называется правое выравнивание.
Для стабилизации измерений мы используем левое выравнивание, выглядит это так 0b1111 1111 1100 0000, ADC = 0хFFC0, а можно представить и так ADCH = 0хFF, ADCL = 0хC0.
Отбросим два младших бита результата, хранящихся в регистре ADCL, ну а поскольку их там всего два, этот регистр просто не используем. Уменьшая разрядность, мы уменьшаем точность, тем самым стабилизируя результат измерений. Теперь результат измерений хранится в регистре ADCH. Наше АЦП стало 8 битным с разрешением в 256ИЕ.
Загружать значение скважности в регистр OCR2 мы будем непосредственно из старшего регистра результата ADCH.
Прикрепленные файлы:
- urok5.zip (14 Кб)