Для управління моторами використовуються вбудовані в мікроконтроллер модулі PWM Раніше, коли програма створювалася в MicroC, ми використовували вбудовані в цю програму бібліотечні компоненти У компіляторі SDCC немає таких компонентів, хоча є багато корисного У прикладі з програмою «моргнути світлодіодами» ми вже зіткнулися з необхідністю створити функцію паузи, затримки Якщо й не дуже елегантно, але досить зрозуміло, ми цю функцію створили Тепер постараємося розібратися, як повторити це

«Досягнення» щодо вбудованого модуля PWM

Почати я пропоную з читання довідки до мікроконтролера PIC16F887, звернувшись до розділу Enhanced Capture / Compare / PWM (CCP1):

Модуль Enhanced Capture / Compare / PWM – це периферія, яка дозволяє користувачеві звертатися до часу і управляти різними подіями У режимі Capture периферія дозволяє оцінювати тривалість подій Цей режим дозволяє користувачеві перемикати зовнішні події, коли зумовлений інтервал часу минає Режим PWM може генерувати модулирующий імпульсний сигнал з мінливою частотою і шпаруватістю

Далі показаний регістр CCP1CON:

Рис 481 Назва бітів регістра CCP1CON І призначення його бітів:

Біти 7-6

P1M<1:0>: Біти конфігурації виходу PWM Якщо CCP1M <3:2> = 00, 01, 10:

xx = P1A призначений як Capture / Compare вхід P1B, P1C, P1D призначені як висновки порту Якщо CCP1M <3:2> = 11:

00 = Одиничний вихід P1A модулирован P1B, P1C, P1D призначені як висновки порту

01 = Прямий полномостовой вихід P1D модулирован P1A активний P1B, P1C не активні

10 = Полумостовой вихід P1A, P1B модульовані з мертвою зоною управління P1C, P1D висновки порту

11 = Інверсний полномостовой вихід P1B модулирован P1C активний P1A, P1D не активні

Біти 5-4

DC1B<1:0>: тривалості PWM мінімально значущі біти Режим захоплення (Capture):

Не використовуються

Режим порівняння (Compare): Не використовуються

Режим PWM:

Ці біти – два LSbs (біти молодшого байта) тривалості PWM (duty cycle) Вісім MSbs (біти старшого байта) знаходяться в CCPR1L

Біти 3-0

CCP1M<3:0>: Біти вибору режиму ECCP

0000 = Capture / Compare / PWM вимкнено (скидання ECCP модуля)

0001 = Не використовується (зарезервовано)

0010 = Режим порівняння (Compare), перемикає відповідний вихід (CCP1IF біт встановлений)

0011 = Не використовується (зарезервовано)

0100 = Режим захоплення (Capture), кожен спадаючий фронт

0101 = Режим захоплення, кожен наростаючий фронт

0110 = Режим захоплення, кожен 4й наростаючий фронт

0111 = Режим порівняння, кожен 16й наростаючий фронт

1000 = Режим порівняння (Compare), встановлює відповідний вихід (біт CCP1IF встановлений)

1001 = Режим порівняння, очищає відповідний вихід (біт CCP1IF встановлений)

1010 = Режим порівняння, генерація відповідного програмного переривання (CCP1IF встановлений, висновок CCP1 не змінюється)

1011 = Режим порівняння, перемикається спеціальна подія (біт CCP1IF встановлений CCP1 скидає TMR1 або TMR2)

1100 = Режим PWM P1A, P1C активний високий рівень P1B, P1D активний високий рівень 1101 = Режим PWM P1A, P1C активний високий рівень P1B, P1D активний низький рівень 1110 = Режим PWM P1A, P1C активний низький рівень P1B, P1D активний високий рівень 1111 = Режим PWM P1A, P1C активний низький рівень P1B, P1D активний низький рівень

Регістр CCP2CON:

Рис 482 Назва бітів регістра CCP2CON Призначення бітів регістра:

Біти 7-6 Не підтримуються: читаються як «0»

Біти 5-4

DC2B<1:0>: тривалості PWM мінімально значущі біти Режим захоплення (Capture):

Не використовуються

Режим порівняння (Compare): Не використовуються

Режим PWM:

Ці біти – два молодших біта LSbs тривалості PWM (duty cycle) Вісім MSbs знаходяться в CCPR2L

Біти 3-0

CCP2M<3:0>: Біти вибору режиму CCP2

0000 = Capture / Compare / PWM вимкнено (скидання модуля CCP2) 0001 = Не використовується (зарезервовано)

0010 = Не використовується (зарезервовано) 0011 = Не використовується (зарезервовано)

0100 = Режим захоплення (Capture), кожен спадаючий фронт 0101 = Режим захоплення, кожен наростаючий фронт

0110 = Режим захоплення, кожен 4й наростаючий фронт 0111 = Режим захоплення, кожен 16й наростаючий фронт

1000 = Режим порівняння (Compare), встановлює відповідний вихід (біт CCP2IF встановлений) 1001 = Режим порівняння, очищає відповідний вихід (біт CCP2IF встановлений)

1010 = Режим порівняння, генерується програмне відповідне переривання (біт CCP2IF встановлений, CCP2 висновок не змінюється)

1011 = Режим порівняння, перемикає спеціальна подія (біт CCP2IF встановлений, TMR1 скидається і перетворення A / D починається, якщо дозволено в модулі ADC Висновок CCP2 не змінюється)

11xx = Режим PWM

І далі слідують пояснення по режимам захоплення, порівняння і того режиму, який цікавить нас зараз, режиму PWM

Режим PWM

У режимі PWM генерується широтно-імпульсний сигнал на висновках CCPx Тривалість імпульсу, період і дозвіл визначаються наступними регістрами:

•      PR2

•      T2CON

•      CCPRxL

•      CCPxCON

У режимі широтно-імпульсної модуляції (PWM) модуль CCP виробляє до 10-бітового дозволу PWM виходу на висновки CCPx Оскільки висновки CCPx мультиплексовані з клямкою даних порту, TRIS для цих висновків повинен бути очищений для дозволу використання висновків, як виходів драйвера CCPx

Наступні сторінки, де наведені діаграма формування ШІМ і схема пристрою цього модуля, я сподіваюся, ви прочитаєте, а я хочу привести розділ з опис того, як почати формування ШІМ:

Завдання PWM операцій

Наступні кроки мають бути виконані при конфігуруванні CCP модуля для виконання PWM операцій:

1 Забороніть використовувати висновки PWM (CCPx) виходів драйверів як входи, встановивши повязані з ними біти TRIS

2 Встановіть період PWM завантаженням PR2 регістру

3 Конфігуруйте CPP модуль для режиму PWM завантаженням CCPxCON регістра відповідними значеннями

4 Задайте тривалість імпульсу PWM завантаженням CCPRxL регістра і DCxB <1:0> бітів регістра CCPxCON

5 Конфігуруйте і запустіть Timer2:

· Очистіть прапор переривання TMR2IF регістра PIR1

· Встановіть значення предделітеля Timer2 завантаженням T2CKPS бітів регістра T2CON

· Дозвольте роботу Timer2, встановивши біт TMR2ON регістра T2CON

6 Дозвольте вихід PWM після того, як почався новий цикл PWM:

· Дочекайтеся переповнення Timer2 (біт TMR2IF регістра PIR1 встановлений)

· Дозвольте вихід драйверів висновків CCPx очищенням повязаних з ними бітів TRIS Що було упущено мною в цьому описі Регістри PR2, PIR1 і T2CON Знайдемо і наведемо нижче формат цих регістрів

Рис 483 Біти регістрів PIR1 і T2CON

Регістр PR2 повністю служить для запису значення

Нагадаю, як підключаються двигуни (для них ми і використовуємо PWM) в ROBOPICA:

Рис 484 Підключення двигунів робота ROBOPICA

Не мудрують лукаво, слідуючи рекомендованим крокам, спробуємо отримати сигнал PWM

Проробимо всі кроки для одного двигуна, підключеного до RD0 і RD1, висновок RC2 – вихід РСР1, для програми:

#include <pic16f887h> typedef unsigned int word

word at 0x2007 CONFIG1 = 0x2FF2 / / Перше слово конфігурації void main ()

{

TRISC2 = 1

PR2 = 0xFF / / Період

CCP1CON = 0x3C / / Двійкове 00111100 CCPR1L = 0x10 / / Тривалість

PIR1 & = 0xFD / / Очищення прапора

T2CON = 1 / / Предделітель таймера TMR2ON = 1 / / Дозвіл роботи таймера while (TMR2IF == 0)

TRISC2 = 0

while(1)

{

}

}

Оттрансліруем програму, і подивимося на результат роботи цієї програми (на макетної платі або в програмі)

Рис 485 Робота пробної програми

Перш, ніж рухатися далі, давайте подивимося, як впливає зміна параметрів на характер імпульсних сигналів У першу чергу розберемося з молодшими бітами LSbs, призначення яких мені не зовсім ясно Якщо їх обнулити, то в регістр CCP1CON слід записати число (шістнадцяткове) 0x0C Подивимося, чи зміниться, і як, якщо так, імпульс на виході RC2

Рис 486 Вид імпульсів після заміни молодших бітів

Вплив цих двох бітів поки оцінити важко Повернемо їх одиничне значення і змінимо вміст регістра CCPR1L, я відразу задам, скажімо, 0xFF

Рис 487 Продовження експерименту зі зміною значення регістра CCPR1L

Висновок з побаченого, що, швидше за все, це значення сильно залежить від інших параметрів, що задаються Що справедливо, оскільки тривалість не може бути більше періоду Перевіримо це, змінивши значення регістрів PR2 і CCPR1L згідно з цим висловом Паралельно з цим я хочу використовувати при завданні параметрів не шістнадцяткові числа, а десяткові

Тобто:

PR2 = 10 / / Період CCPR1L = 5 / / Тривалість

Рис 488 Перевірка програми із заданими параметрами тривалості і періоду

Період і тривалість, задані в десятковому вигляді, відповідають цим значенням в мікросекундах Таким чином, максимальний період у цьому випадку 255 мкс

Якщо така частота велика для управління двигуном, те, що ми можемо зробити, щоб зменшити частоту

У нас є регістр, в якому задається режим розподілу частоти, предделітель таймера Збільшимо значення в цьому регістрі до 3:

T2CON = 3 / / Предделітель таймера

Нагадаю, що два молодших біта визначають режим роботи предделітеля

Рис 489 Робота програми зі зміненим параметром предделітеля

Що ж, частота близько 1 кГц До речі, звук, який може видавати робот, це сигнал з частотою близько 2 кГц

І ще одне, про що я забув згадати Регістр ANSEL, Який має старший байт ANSELH У цьому регістрі проводиться перемикання портів з аналогового входу на цифровий введення-виведення

Якщо ви подивитеся програму ROBOPICа, то побачите такі рядки:

ANSELHF0 = 0 / / RB1 ==> Цифровий Введення / Висновок ANSELHF2 = 0 / / RB2 ==> Цифровий Введення / Висновок

У SDCC можна використовувати, як ми робили з будь-яким портом, імя відповідного біта:

ANS8 = 0 / / RB1 ==> Цифровий Введення / Висновок ANS10 = 0 / / RB2 ==> Цифровий Введення / Висновок

Джерело: Гололобов ВН, – Самовчитель гри на паяльнику (Про електроніці для школярів і не тільки), – Москва 2012