PIC. Урок 14. Модуль CCP. Режим PWM



Продолжаем изучение модуля CCP, который служит для расширения функционала таймеров. И в данном уроке мы познакомимся и ощутим на практике третий и последний режим модуля CCP — режим PWM (Pulse-Width Modulation) или ШИМ (широтно-импульсная модуляция).

С данным типом модуляции или процессом управления мощностью путём изменения скважности мы уже знакомились подробно в уроках по другим микроконтроллерам, но всё же для повторения давайте немного вспомним о нём.

ШИМ — это управление свечением светодиодов, вращением двигателей, и прочими устройствами необычным способом, при котором данное управление осуществляется не приложенным напряжением к контактам, а квадратными импульсами. При этом напряжение будет только двух видов — высокое (1) и низкое (0). При данном способе результирующее напряжение вычисляется как среднее по времени между временем высокого состояния в одном импульсе и временем низкого состояния. Мы вычисляем отношение времени (или широты) высокого состояния к общему периоду импульса. Называем мы это скважностью импульса. То есть чем больше в периоде напряжение находилось в высоком состоянии, тем больше скважность, а, следовательно, тем больше и результирующее среднее напряжение. То есть, чтобы найти результирующее напряжение, нам необходимо и достаточно вычисленную скважность умножить на напряжение и разделить на 100, так как скважность как правило измеряется в процентах. Например, если у нас в квадратном импульсе широта логического нуля равна широте логической единицы, то скважность у нас будет 50 процентов, и, если напряжение будет 5 вольт, то среднее результирующее напряжение мы получим равное 2,5 вольт и т.д. Лучшую картину объяснения данной ситуации мы можем увидеть, посмотрев видеоурок, ссылка на который дана в конце данной статьи.

Это конечно очень упрощённое понятие ШИМ. Есть более серьёзные разъяснение данной технологии, но нам для наших экспериментов этого будет вполне достаточно.

То есть, подведя итоги объяснению, мы управляем результирующим напряжением, а также и свечением светодиода, угловой скоростью электродвигателя и прочими значениями за счёт изменения скважности импульсов.

Как же организован PWM в нашем модуле CCP, как его включить и как им управлять?

На помощь нам приходит техническая документация на контроллер. Посмотрим данную блок-схему

 

 

В блок-схеме описан механизм организации и управления режимом PWM в модуле CCP1. Поэтому речь мы будем вести о первом модуле CCP. Работа со вторым модулем происходит аналогично.

Мы заносим в регистр PR2 таймера TIMER2 период, с помощью чего мы задаём необходимую частоту импульсов.

PWM в нашем контроллере является 10-битным.

Количество циклов периода, во время которых шина будет находиться в состоянии логической 1, мы настраиваем с помощью регистра CCPR1L и двух битов (5:4) регистра CCP1CON. Вот так мы и получаем 10 бит настройки периода высокого состояния. Но возникает некоторая неувязка: у нас же таймер TIMER2 8-битный. Тут всё не так просто.

Общий период всего цикла PWM рассчитываеся следующим образом. Сначала мы значение в регистре PR2 увеличиваем на 1. Затем данный результат мы умножаем на 4 и ещё на коэффициент деления. Единица измерения данного периода — это количество тактов генератора. Чтобы получить его в единицах времени, соответственно результат надо умножить на период одного такого такта.

При совпадении величин периода высокого состояния и значения TMR2, умноженного на коэффициент деления (ножка Q триггера учитывает его), то есть когда счётчик таймера достигнет периода высокого состояния, цифровой компаратор передаст сигнал на контакт R триггера, который затем переведёт ножку контроллера PC2 (CCP1) в низкое состояние. А в высокое состояние ножка перейдёт, когда таймер досчитает до конца, то есть когда значение в регистре TMR2 совпадёт со значением в регистре PR2.

Таким образом, период высокого состояния ножки (длительность импульса PWM) рассчитывается следующим образом. Значение 10 битов настройки PWM мы умножаем на коэффициент деления таймера. Также, как и в случае полного периода, чтобы получить период в единицах времени, мы умножаем результат на период одного такта генератора.

Также, как мы можем догадаться, максимальная разрядность 10 бит обеспечивается только при максимальном значении регистра PR2.

Ну и, чтобы рассчитать скважность ШИМ, мы длительность импульса делим на общий период всего цикла.

Соответственно, ножка RC2 должна быть настроена на выход.

Для закрепления полученных знаний давайте создадим проект и попробуем усвоить материал на практике.

Проект мы создадим из проекта прошлого занятия CCP_CMP и назовём его CCP_PWM.

Откроем проект в MPLAB X.

Питать контроллер мы будем от программатора, так как ток потребления будет небольшой.

Теперь на время перенесёмся к нашей схеме. Во избежание шунтирования снимем перемычку с ножки RC2, идущую от ИК-приёмника

 

 

Сначала мы будем смотреть результат нашей работы с кодом с помощью логического анализатора, а по окончании — подключим светодиоды к ножкам обоих модулей. Работать мы будем одновременно с двумя модулями CCP. Ещё одно очень важное замечание. Оба сигнала ШИМ будут одного периода, разную мы можем обеспечить только скважность. Обусловлено это тем, что таймер в одну единицу времени может работать только с одной частотой и с одним периодом. Менять мы всё это в процессе выполнения программы, конечно же, можем, но изменения эти, соответственно, коснутся одновременно обоих модулей CCP.

Подключим логический анализатор к ножкам CCP1 (RC2) и CCP2 (RC1) (нажмите на картинку для увеличения изображения)

 

 

Настроим наш проект как главный, на всякий случай убедимся в настройках, что у нас плата питается именно от программатора.

 

 

Откроем файл main.c и удалим глобальную переменную

 

unsigned int per1;

 

Удалим также функцию-обработчик прерываний interrupt isr вместе с телом.

В функции main() добавим две локальные переменные

 

void main()

{

  unsigned int i=0;

  unsigned char fl=0;

 

Порт A нам не потребуется, поэтому удалим его инициализацию

 

TRISA=0X00;

PORTA=0X00;

 

Порт C настроим на выход весь, тем самым на выход будут настроены наши ножки CCP1 и CCP2

 

TRISC2=1;

TRISC=0X00;

 

Режим модулей меняем на PWM

 

CCP1CON = 0x0F; //PWM mode CCP

CCP2CON = 0x0F;

 

Весь дальнейший код до бесконечного цикла удалим.

Настроим таймер 2, добавив предделитель, настроив желаемый период и по окончании включив наш таймер

 

CCP2CON = 0x0F;

PR2 = 0xFF; //TIMER2 Period 255

T2CKPS1 = 1; //TIMER2 prescaler 1:16

T2CKPS0 = 0;

TMR2ON = 1; //TIMER2 ON

 

Вспоминая то, что мы видели выше, можно, произведя несложный рассчёт, получить время полного периода, а следовательно и частоту

 

T = (255+1)*4*16*0.25 = 4096 микросекунд.

Следовательно частота будет 4000000 / 4 / 4096 ≈ 244,14 герц.

 

На 4 мы ещё делим, так как длина одного такта это частота генератора, разделённая на 4.

Заранее мы не будем настраивать длительность импульса PWM. Мы будем его менять для каждого модуля, а следовательно и для выходных их ножек в бесконечном цикле.

И для удобства изменения длительности ипульса PWM мы добавим функцию установки данного периода выше функции main()

 

//------------------------------------------------

void SetPWM (unsigned char nm, unsigned int dc)

{

}

//------------------------------------------------

 

В качестве первого входного параметра у нас будет номер модуля, а в качестве второго — длительность импульса в том виде, в котором оно будет храниться в 10 битах соответствующих регистров контроллера.

 

 

Добавим в тело нашей функции оператор вариантов switch, который будет определять номер модуля

 

void SetPWM (unsigned char nm, unsigned int dc)

{

  switch(nm)

  {

    case 1:

      break;

    case 2:

      break;

  }

}

 

В первом кейсе мы занесём период, предназначенный для первого модуля в необходимые биты соответствующих регистров

 

case 1:

  CCPR1L = dc>>2;

  CCP1CON &= 0xCF;

  CCP1CON |= 0x30&(dc<<4);

  break;

 

Мы сначала занесём старшие 8 бит в регистр CCPR1L, затем в регистре CCP1CON очистим 5 и 4 биты, а затем, пользуясь удобной операцией сдвига и маской, очищающей все биты кроме двух младших, занесём 2 старших бита значения периода в 5 и 4 биты регистра CCP1CON.

Аналогичные действия проделаем и для второго модуля

 

case 2:

  CCPR2L = dc>>2;

  CCP2CON &= 0xCF;

  CCP2CON |= 0x30&(dc<<4);

  break;

 

Перейдём в бесконечный цикл и добавим код, который будет плавно изменять скважность PWM на обоих ножках соответствующих модулей. Причём при его возрастании на первой ножке он будет должен убывать на второй, а затем наоборот.

Сначала занесём первоначальные настройки длительностей циклов наших каналов PWM

 

while(1)

{

  SetPWM(1, i);

  SetPWM(2, 1023-i);

 

Если флаг fl1 у нас будет равен нулю, то значит возрастать будет скважность первого канала, а если единице — то второго.

В соответствии с этим условием напишем дальнейший код

 

    SetPWM(2, 1023-i);

    if(fl==0) i++;

    else i--;

    if(i>1023) fl=1;

    else if(i<=0) fl=0;

  }

}

 

Соберём код, прошьём контроллер.

После этого, если всё сделано и подключено правильно, мы должны будем наблюдать следующую картину в программе логического анализа (нажмите на картинку для увеличения изображения)

 

 

Но наблюдать в программе — это одно, а на светодиодах — интереснее. Поэтому сначала для плавности мигания добавим в конце тела бесконечного цикла небольшую задержку

 

  else if(i<=0) fl=0;

  __delay_us(500);

}

 

Мигать мы будем светодиодами, расположенными на плате — первым и вторым. Но, так как они подключены к совершенно другим ножкам (RB0 и RB1), то сначала снимем соответствующие соединительные перемычки

 

 

Отключим логически анализатор и соединим ножки контроллера CCP1 и CCP2 с соответствующими ножками светодиодов. Светодиоды начнут попеременно плавно мигать

 

 

Таким образом, в данном уроке мы изучили третий режим модулей CCP — режим PWM. И на этом мы заканчиваем изучение модулей CCP.

Всем спасибо за внимание!

 

 

Предыдущий урок Программирование МК PIC Следующий урок

 

Исходный код

 

 

Купить программатор (неоригинальный) можно здесь: PICKit3

Купить программатор (оригинальный) можно здесь: PICKit3 original

Отладочную плату PIC Open18F4520-16F877A можно приобрести здесь: PIC Open18F4520-16F877A

Логический анализатор 16 каналов можно приобрести здесь

 

 

Смотреть ВИДЕОУРОК (нажмите на картинку)

 

PIC Модуль CCP. Режим PWM

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*