Програмний шим на мікроконтролері алгоритм. Багатоканальний програмний ШІМ в AVR. Навіщо потрібен програмний ШІМ

Головна / Основний функціонал

Цифрові пристрої, наприклад, мікроконтролер може працювати з двома рівнями сигналу, тобто. нуль і одиниця або вимкнено та увімкнено. Таким чином, ви можете легко використовувати його для контролю стану навантаження, наприклад, увімкнути або вимкнути світлодіод. Також ви можете використовувати його для керування будь-яким електричним приладом, використовуючи відповідні драйвери (транзистор, симістор, реле і т.д.). Але іноді потрібно більше, ніж просто "включити" і "вимкнути" пристрій. Тому, якщо ви хочете контролювати яскравість світлодіода (або лампи) або швидкості двигуна постійного струму, то цифрові сигналипросто не можу цього вдіяти. Ця ситуація дуже часто зустрічається в цифровій техніці та називається Широтно-імпульсною модуляцією (PWM).

Майже всі сучасні мікроконтролери мають спеціалізовані апаратні засоби для створення ШІМ-сигналу. У цьому уроці ми вивчатимемо основи техніки ШІМ і надалі побачимо, як реалізувати ШІМ за допомогою мікроконтролерів AVR.

Цифрові пристрої, як мікроконтролер може генерувати лише два рівні на вихідних лініях, високий = 5В та низький = 0В. Але що, якщо ми хочемо отримати 2,5 чи 3,1 чи будь-яку напругу в межах 0-5В? Для цього замість створення постійної напруги постійного струму на виході ми будемо генерувати меандр, який має високий = 5В і низький = 0V рівні (див. малюнок 1).

Рис.1

З малюнка видно, що сигнал на деякий час залишається по черзі на низькому та високому рівні. Т0 – низький рівень, Т1 – високий рівень. Період сигналу дорівнюватиме Т = Т0+Т1. Період імпульсів- це проміжок часу між двома характерними точками двох сусідніх імпульсів. Зазвичай період вимірюють між двома фронтами або двома спадами сусідніх імпульсів і позначають великою латинською літерою T.

Період проходження імпульсів безпосередньо пов'язаний з частотою імпульсної послідовності, і його можна обчислити за формулою: Т = 1/F

Якщо довжина імпульсу T1 точно дорівнює половині періоду T, такий сигнал часто називають "меандр".

Скважністю імпульсів називається відношення періоду проходження імпульсів до їх тривалості і позначається буквою S: S = T/T1

Добре - безрозмірна величина і не має одиниць виміру, але може бути виражена у відсотках. Часто в англомовних текстах зустрічається термін Duty cycle, Це так званий коефіцієнт заповнення або величина робочого циклу ШІМ. Коефіцієнт заповнення D є величиною, зворотної шпаруватості.

Коефіцієнт заповненнязазвичай виражається у відсотках і обчислюється за такою формулою: D=1/Sабо так D = T1/T*100%

На малюнку вище (рис. 1) можна побачити, що T1 = T0, це дорівнює половині періоду часу. Так величина робочого циклу ШІМ становить 50%. Якщо частота таких імпульсів досить велика (скажімо, 5000 Гц), ми отримуємо половину від 5В тобто. 2,5В. Таким чином, якщо вихід контролера пов'язаний із двигуном (за допомогою відповідних драйверів) він працюватиме на 50% його повної швидкості. Техніка ШІМ використовує цей факт для створення будь-якої напруги між двома рівнями (наприклад, між 0-12В). Весь фокус у тому, що при зміні величини робочого циклу між 0-100% отримуємо той самий відсоток вхідної напруги на виході. Нижче наведено деякі приклади ШІМ сигналу різної шпаруватості.

Якщо на виході поставити R/С фільтр, можна отримати чистий DC рівень сигналу, а не квадратні хвилі. Але це не потрібно для колекторних двигунів або управління яскравістю світлодіодів. Для цього можна подавати ШІМ сигнал безпосередньо на драйвер (наприклад, біполярний транзистор, MOSFET тощо).


Під режимом роботи 16-розр. таймера розуміється його алгоритм рахунку та поведінка пов'язаного з ним виходу формувача імпульсів, що визначається комбінацією біт, що задають режим роботи таймера (WGMn3-0) та режим формування вихідного сигналу (COMnx1:0). У цьому біти завдання режиму формування вихідного сигналу впливають алгоритм рахунку, т.к. алгоритм рахунку залежить від стану біт завдання режиму роботи таймера. У режимах з ШІМ біти COMnx1:0 дозволяють включити/відключити інверсію на ШИМ-виході, що генерується (тобто вибрати ШІМ з інверсією або ШІМ без інверсії). Для режимів без ШІМ біти COMnx1:0 визначають, яку дію необхідно виконати у разі збігу: скинути, встановити чи інвертувати вихід (див. також “Блок формування вихідного сигналу” і "Тимчасові діаграми 16-розр. таймерів-лічильників").

Нормальний режим роботи

Самим простим режимомРобота є нормальним режимом (WGMn3-0 = 0b0000). У даному режимілічильник працює як підсумовуючий (інкрементуючий), при цьому скидання лічильника не виконується. Переповнення лічильника відбувається під час переходу через максимальне 16-разр. значення (0xFFFF) до нижньої межі рахунку (0x0000). У нормальному режимі роботи прапор переповнення таймера-лічильника TOVn буде встановлений на такому ж такті синхронізації, коли TCNTn прийме нульове значення.

Фактично, прапор переповнення TOVn є 17-м бітом таймера-лічильника за винятком, що він тільки встановлюється і не скидається. Однак програмно ця властивість може бути використана для підвищення роздільної здатності таймера, якщо використовувати переривання з переповнення таймера, при виникненні якого прапор TOVn скидається автоматично. Для нормального режиму роботи немає будь-яких особливих ситуацій, тому запис нового стану лічильника може бути виконано будь-якої миті.

У нормальному режимі можна використовувати блок захвату. Однак при цьому слід дотримуватися, щоб максимальний інтервал між виникненнями зовнішніх подій не перевищив періоду переповнення лічильника. Якщо така умова не дотримується, необхідно використати переривання з переповнення таймера-лічильника або розподільника.

Блок порівняння може використовуватись для генерації переривань. Не рекомендується використовувати вихід OCnx для створення сигналів у нормальному режимі роботи, т.к. у цьому випадку буде витрачена значна частина процесорного часу.

Режим скидання таймера під час збігу (СТС)

У режимі СТС (WGM01, WGM00 = 0b10) регістр OCR0 використовується для завдання роздільної здатності лічильника. Якщо заданий режим CTC і значення лічильника (TCNT0) збігається зі значенням регістра OCR0, лічильник обнуляється (TCNT0=0). Таким чином, OCR0 задає вершину рахунку лічильника, а, отже, і його роздільну здатність. У даному режимі забезпечується більш широкий діапазон регулювання частоти прямокутних імпульсів, що генеруються. Він також полегшує роботу лічильника зовнішніх подій.

У режимі скидання таймера при збігу (WGMn3-0 = 0b0100 або 0b1100) роздільна здатність таймера задається регістрами OCRnA або ICRn. У режимі СТС відбувається скидання лічильника (TCNTn), якщо його значення збігається зі значенням регістра OCRnA (WGMn3-0 = 0b0100) або ICRn (WGMn3-0 = 0b1100). Значення регістра OCRnA або ICRn визначає верхню межу рахунку, а, отже, і роздільну здатність таймера. У даному режимі забезпечується більш широкий діапазон регулювання частоти прямокутних імпульсів, що генеруються. Він також полегшує роботу лічильника зовнішніх подій. Тимчасова діаграма роботи таймера у режимі СТС показана малюнку 1. Лічильник (TCNTn) інкрементує свій стан до того часу, поки виникне збіг зі значенням OCRnA чи ICRn, та був лічильник (TCNTn) скидається.

Рисунок 1 – Тимчасова діаграма для режиму СТС

Після досягнення верхньої межі рахунку може генеруватися переривання за допомогою прапорів OCFnA або ICFn, відповідним використовуваним регістрів для завдання верхньої межі рахунку. Якщо переривання дозволено, процедура переривання може використовуватися для оновлення верхньої межі рахунку. Однак, завдання значення вершини рахунку близького до значення нижньої межі рахунку, коли лічильник працює без розподілу або з малим значенням розподілу, необхідно виконувати з особливою обережністю, т.к. у режимі СТС немає подвійної буферизації. Якщо значення, записане в OCRnA або ICRn, менше поточного значення TCNTn, то скидання лічильника за умовою збігу настане, коли він досягне максимального значення (0xFFFF), потім перейде в вихідний стан 0x0000 і досягне нового значення OCRnA чи ICRn. У багатьох випадках виникнення такої ситуації не є бажаним. В якості альтернативи може виступити режим ШІМ швидкої, де регістр OCRnA визначає верхню межу рахунку (WGMn3-0 = 0b1111), т.к. у цьому випадку OCRnA має подвійну буферизацію.

Для генерації сигналу в режимі CTC вихід OCnA може використовуватись для зміни логічного рівня при кожному збігу, для чого необхідно встановити режим перемикання (COMnA1, COMnA0 = 0b01). Значення OCnA буде присутнє на виведенні порту, тільки якщо для цього висновку задано вихідний напрямок. Максимальна частота сигналу, що генерується, дорівнює fOC0 = fclk_I/O/2, якщо OCRnA = 0x0000. Для інших значень OCRn частоту сигналу, що генерується, можна визначити за формулою:

де змінна N визначає коефіцієнт розподілу предделителя (1, 8, 32, 64, 128, 256 або 1024).

Так само, як і для нормального режиму роботи, прапор TOV0 встановлюється на тому ж такті таймера, коли його значення змінюється з 0xFFFF на 0x0000.

Режим швидкої ШИМ (FAST PWM)

Режим швидкої широтно-імпульсної модуляції (ШІМ) (WGMn3-0 = 0b0101, 0b0110, 0b0111, 0b1110, 0b1111) призначений для генерації ШІМ-імпульсів підвищеної частоти. На відміну від інших режимів роботи, у цьому використовується односпрямована робота лічильника. Рахунок виконується у напрямку від нижньої до верхньої межі рахунку.

Якщо встановлено неінвертуючий режим виходу, то при збігу TCNTn і OCRnx сигнал OCnx встановлюється, а верхній межі рахунку скидається. Якщо заданий режим, що інвертує, то вихід OCnx скидається при збігу і встановлюється на верхньому межі рахунку. За рахунок односпрямованості рахунку, робоча частота для даного режиму в два рази вище порівняно з режимом ШІМ із фазовою корекцією, де використовується двоспрямований рахунок. Можливість генерації високочастотних ШІМ сигналів робить використання даного режиму корисним у задачах стабілізації живлення, випрямлення та цифро-аналогового перетворення. Висока частота, при цьому дозволяє використовувати зовнішні елементифізично малих розмірів (індуктивності, конденсатори), цим знижуючи загальну вартість системи.

Роздільна здатність ШІМ може бути фіксованою 8, 9 або 10 розрядів або задаватися регістром ICRn або OCRnA, але не менше 2 розрядів (ICRn або OCRnA = 0x0003) і не більше 16 розрядів (ICRn або OCRnA = 0xFFFF). Роздільна здатність ШІМ при заданому значенні верхньої межі (ВП) обчислюється наступним чином:

У режимі швидкої ШІМ лічильник інкрементується до збігу його значення з одним з фіксованих значень 0x00FF, 0x01FF або 0x03FF (якщо WGMn3:0 = 0b0101, 0b0110 або 0b0111, відповідно), значенням в ICRn1:0 (якщо WGMn3:0 = 0b1111), а потім скидається наступним тактом синхронізації таймера. Тимчасова діаграма для швидкого ШІМ представлена ​​на малюнку 2. На малюнку показаний режим швидкої ШІМ, коли для завдання верхньої межі використовується регістр OCRnA або ICRn. Значення TCNTn на часовій діаграмі показано як графіка функції для ілюстрації односпрямованості рахунки. На діаграмі показані як інвертований, так і неінвертований ШІМ-виходи. Короткою горизонтальною лінією показані точки на графіку TCNTn, де збігаються значення OCRnx та TCNTnx. Прапор переривання OCnx встановлюється у разі збігу.

Рисунок 2 – Тимчасова діаграма для режиму швидкої ШІМ

Прапор переповнення таймера-лічильника (TOVn) встановлюється щоразу, коли лічильник досягає верхньої межі. Додатково тим же тактовим імпульсом разом з прапором TOVn можуть встановити прапори OCnA або ICFn, якщо для завдання верхньої межі використовується регістр OCRnA або ICRn відповідно. Якщо одне з цих переривань дозволено, то процедурі обробки переривання може бути виконано оновлення верхньої межі рахунку та порогів порівняння.

Якщо змінюється значення верхньої межі рахунку, необхідно дотримання умови, щоб записуване нове значення верхньої межі було більше або дорівнює значень у всіх регістрах порога порівняння. В іншому випадку збіг між TCNTn та OCRnx ніколи не виникне. Зверніть увагу, що при використанні фіксованих значень верхньої межі під час запису в регістри OCRnx відбувається маскування до 0 розрядів, що не використовуються.

Механізм модифікації регістра ICRn відрізняється від OCRnA у разі, якщо він використовується завдання верхнього краю. Реєстр ICRn не має подвійної буферизації. Це означає, що якщо ICRn записується мале значення під час роботи лічильника з малим розподілом або без нього, то є небезпека запису в регістр ICRn значення, яке виявиться менше поточного значення TCNTn. Як результат, у такій ситуації буде пропущено збіг на вершині рахунку. У цьому випадку лічильник дійде до максимального значення (0xFFFF), перезапуститься зі значення 0x0000, а потім виникне збіг. Регістр OCRnA містить схему подвійної буферизації, тому його можна модифікувати в будь-який момент часу.

class="eliadunit">

Якщо виконується запис за адресою OCRnA, фактично значення поміщається в буферний регістр OCRnA. Якщо ж виникає збіг між TCNTn і вершиною рахунку, то наступним тактом синхронізації таймера відбувається копіювання буферного регістра регістр порога порівняння OCRnA. Оновлення регістру виконується тим самим тактом, що скидання TCNTn і установка прапора TOVn.

Рекомендується використовувати регістр ICRn для завдання верхньої межі, якщо верхня межа рахунку є константою. У цьому випадку також звільняється регістр OCRnA для генерації ШІМ-сигналу на виході OCnA. Однак, якщо частота ШІМ динамічно змінюється (за рахунок зміни верхньої межі), то в цьому випадку вигідніше використовувати регістр OCRnA для завдання верхньої межі, т.к. він підтримує подвійну буферизацію.

У режимі швидкої ШІМ-блоки порівняння дозволяють генерувати ШІМ-сигнали на висновках OCnx. Якщо COMnx1:0 =0b10, то задається ШІМ без інверсії виходу, і якщо COMnx1:0 = 0b11, то задається режим ШИМ з інверсією на виході (див. таблицю 59). Фактичне значення OCnx можна спостерігати на виведенні порту, якщо йому встановлено вихідний напрямок (DDR_OCnx). ШИМ-сигнал генерується шляхом встановлення (скидання) регістра OCnx при виникненні збігу між OCRnx і TCNTn, а також шляхом скидання (установки) регістра OCnx разом зі скиданням лічильника (перехід з верхньої межі на нижню межу).

Частота ШІМ вихідного сигналу для заданого значення верхньої межі (ВП) визначається виразом:

де N - змінна, яка задає значення коефіцієнта розподілу (1, 8, 32, 64, 128, 256 або 1024).

Запис граничних значень регістр OCRnx пов'язана з особливими випадками в генерації ШІМ-імпульсів. Якщо OCRnx встановити рівним нижній межі (0x0000), то на виході буде виникати короткий імпульс кожен (ВП+1) такт синхронізації таймера. Запис у OCRnx значення рівного верхньому межі призведе до встановлення постійного рівня балка. 1 або 0 на виході (залежить від обраної за допомогою біту COMnx1:0 полярності вихідного сигналу).

Якщо потрібна генерація меандру (прямокутні імпульси зі шпаруватістю 2 або заповненням 50%) високої частоти, то необхідно використовувати режим швидкої ШІМ з установкою біт COMnA1: 0 = 0b01, яка викликає перемикання (інвертування) логічного рівня на виході OCnA при кожному збігу. Це застосовується, тільки якщо OCRnA використовується для завдання верхньої межі (WGMn3-0 = 0b1111). Максимальна частота меандру, що генерується, у цьому випадку fOCnA = fclk_I/O/2, якщо OCRnA =0x0000. Ця особливістьаналогічна переключенню OCnA в режимі СТС за винятком подвійної буферизації, яка є в режимі ШІМ швидкої.

Режим широтно-імпульсної модуляції з фазовою корекцією (Phase Correct)

Режим широтно-імпульсної модуляції з фазовою корекцією (ШІМ ФК) (WGMn3-0 = 0b0001, 0b010, 0b0011, 0b1010 або 0b1011) призначений для генерації ШІМ сигналу з фазовою корекцією і високою роздільною здатністю. Режим ШІМ ФК заснований на двонаправленій роботі таймера-лічильника. Лічильник циклічно виконує рахунок у напрямку від нижньої межі (0x0000) до верхньої межі, а потім назад від верхньої межі до нижньої межі. Якщо заданий неінвертуючий режим виходу формувача імпульсів, вихід OCnx скидається/встановлюється при збігу значень TCNTn і OCRnx під час прямого/зворотного рахунку. Якщо заданий режим виходу, то, навпаки, під час прямого рахунку відбувається установка, а під час зворотного – скидання виходу OCnx. При двонаправленій роботі максимальна частотаШИМ-сигналу менше, ніж при односпрямованій роботі, однак, за рахунок такої особливості, як симетричність в режимах ШІМ з двонаправленою роботою, ці режими вважають за краще використовувати при вирішенні завдань управління приводами.

Роздільна здатність ШІМ в даному режимі може бути фіксованою (8, 9 або 10 розрядів) або задаватися за допомогою регістра ICRn або OCRnA. Мінімальна роздільна здатність дорівнює 2-м розрядам (ICRn або OCRnA = 0x0003), а максимальна -16-ти розрядам (ICRn або OCRnA = 0xFFFF). Якщо задана верхня межа, то роздільна здатність ШІМ в даному режимі визначається так:

У режимі ШІМ ФК лічильник інкрементується доки не досягне одного з фіксованих значень 0x00FF, 0x01FF або 0x03FF (відповідно для WGMn3-0 = 0b0001, 0b0010 або 0b0011), а також значення рівного ICRn (00 WG :0 = 0b1011). Далі, при досягненні верхньої межі, лічильник змінює напрямок рахунку. Значення TCNTn залишається рівним верхньому межі протягом одного такту синхронізації таймера. Тимчасова діаграма для режиму ШІМ ФК представлена ​​малюнку 3. На малюнку показаний режим ШИМ ФК з допомогою регістра OCRnA чи ICRn для завдання верхньої межі. Стан TCNTn представлений у вигляді графіка функції для ілюстрації двоспрямованості рахунку. На малюнку представлені як неінвертований, так і інвертований ШІМ-вихід. p align="justify"> Короткі горизонтальні лінії вказують точки на графіку зміни TCNTn, де виникає збіг зі значенням OCRnx. Прапор переривання OCnx встановлюється у разі збігу.

Рисунок 3 – Тимчасова діаграма для режиму ШІМ ФК

Прапор переповнення таймера-лічильника (TOVn) встановлюється щоразу, коли лічильник досягає нижньої межі. Якщо для завдання верхньої межі використовується регістр OCRnA або ICRn, відповідно встановлюється прапор OCnA або ICFn тим же тактовим імпульсом, на якому відбулося оновлення регістра OCRnx з буферного регістра (на вершині рахунку). Прапори переривання можуть використовуватися для генерації переривання після досягнення лічильником нижньої або верхньої межі.

При зміні значення верхньої межі рахунку необхідно стежити, щоб воно було більше або дорівнює значенням у всіх регістрах порівняння. В іншому випадку збіг між TCNTn та OCRnx ніколи не виникне. Зверніть увагу, що при використанні фіксованих значень верхньої межі рахунку під час запису в регістри OCRnx розряди, що не використовуються, обнулюються. Третій період малюнку 53 ілюструє випадок, коли динамічна зміна верхньої межі рахунку призводить до генерації несиметричного імпульсу. Ця особливість ґрунтується на часі оновлення регістру OCRnx. Оскільки оновлення OCRnx виникає на вершині рахунку, то і період ШІМ починається і закінчується на вершині рахунку. Це передбачає, що тривалість зворотного рахунку визначається попереднім значенням верхньої межі, а прямого – новим значенням верхньої межі. Якщо ці значення різні, то й тривалість прямого і зворотного рахунку буде також відрізнятися. Відмінність тривалості призводить несиметричності вихідних імпульсів.

Якщо стоїть завдання зміни верхньої межі при працюючому лічильнику, замість цього режиму рекомендується використовувати режим ШІМ ФЧК (фазова і частотна корекція). Якщо використовується статичне значення верхньої межі, між даними режимами практично немає відмінностей.

У режимі ШІМ ФК блоки порівняння дозволяють генерувати ШІМ сигнали на висновках OCnx. Якщо встановити COMnx1:0 = 0b10, вихід ШИМ буде без інверсії, і якщо COMnx1:0=0b11, то з інверсією. Фактичне значення OCnx можна спостерігати на виведенні порту, якщо в регістрі напряму даних для виведення порту заданий вихідний напрямок (DDR_OCnx). ШИМ-сигнал генерується шляхом встановлення (скидання) регістра OCnx при збігу значень OCRnx і TCNTn під час прямого рахунку, а також шляхом скидання (установки) регістра OCnx при збігу між OCRnx та TCNTn під час зворотного рахунку. Результуюча частота ШІМ-сигналу в режимі ШІМ ФК при заданій верхній межі (ВП) може бути обчислена за таким виразом:

Запис граничних значень регістр OCRnx пов'язане з особливими випадками в генерації ШІМ-сигналів в режимі ШІМ ФК. Якщо встановити режим ШІМ без інверсії і OCRnx встановити рівним нижньому межі, то на виході безперервно буде встановлено лог. 0, а якщо рівним верхньому межі, то на виході постійно присутній балка. 1. Для ШІМ з інверсією зазначені рівні необхідно замінити на протилежні.

Якщо задати використання OCnA як верхню межу (WGMn3:0 = 0b1011) і встановити COMnA1:0 =0b01, то на виході OCnA буде генеруватися меандр.

Режим широтно-імпульсної модуляції з фазовою та частотною корекцією (Phase and Frequency Correct)

Режим широтно-імпульсної модуляції з фазовою та частотною корекцією (ШІМ ФЧК) (WGMn3-0 = 0b1000 або 0b1001) призначений для генерації ШІМ-імпульсів високої роздільної здатності з фазовою та частотною корекцією. Як і режим ШИМ ФК режим ШИМ ФЧК заснований на двонаправленій роботі лічильника. Лічильник циклічно вважає від нижньої межі (0x0000) до верхньої межі, а потім назад від верхньої межі до нижньої межі. Якщо заданий неінвертуючий режим ШІМ, вихід OCnx скидається, якщо виникає збіг між TCNTn і OCRnx під час прямого рахунку, і встановлюється, якщо виникає збіг під час зворотного рахунку. В режимі інвертування робота інверсна. Двонаправлена ​​робота, в порівнянні з односпрямованою, пов'язана з генерацією більш низьких частот. Однак, завдяки симетричності в режимах ШІМ з двонаправленим рахунком, їх застосування переважно в задачах керування приводами.

Основна відмінність між режимами ШІМ ФК та ​​ШІМ ФЧК полягає в моменті оновлення регістра OCRnx з буферного регістра OCRnx (див. рис. 3 і рис. 4).

Роздільна здатність ШІМ в цьому режимі може задаватися за допомогою регістра ICRn або OCRnA. Мінімальна роздільна здатність дорівнює 2-розрядам (ICRn або OCRnA = 0x0003), а максимальна роздільна здатність - 16-ти розрядам (ICRn або OCRnA = 0xFFFF). Роздільна здатність ШІМ у розрядах може бути обчислена за таким виразом:

У режимі ШІМ ФЧК лічильник інкрементується до збігу зі значенням ICRn (WGMn3:0 = 0b1000) або в OCRnA (WGMn3:0 = 0b1001). Це означає досягнення вершини рахунку, після чого відбувається зміна напряму рахунку. Значення TCNTn залишається рівним вершині рахунку протягом одного такту синхронізації таймера. Тимчасова діаграма для режиму ШІМ ФЧК показана на малюнку 54. На малюнку показаний режим ШІМ ФЧК, коли вершину рахунку задає регістр OCRnA або ICRn. Значення TCNTn показано як графіка функції для ілюстрації двунаправленности рахунки. На діаграмі показаний як неінвертуючий, так і ШИМ, що інвертує ШИМ виходи. Короткі горизонтальні лінії вказують на точки графіка TCNTn, де виникає збіг між OCRnx і TCNTn. Прапор переривання OCnx встановлюється після збігу.

Рисунок 4 – Тимчасова діаграма режиму ШІМ із фазовою та частотною корекцією

Прапор переповнення таймера-лічильника (TOVn) встановлюється тим самим тактом, коли відбулося оновлення регістрів значенням із буферного регістру (на нижній межі рахунку). Якщо для завдання верхньої межі використовується регістр OCRnA або ICRn, то після досягнення лічильником верхньої межі встановлюється прапор OCnA або ICFn відповідно. Прапори переривання можуть використовуватися для генерації переривання при досягненні лічильником верхньої або нижньої межі.

При зміні верхньої межі необхідно стежити, щоб нове значення було більше або дорівнює значенням у всіх регістрах порогу порівняння. В іншому випадку, якщо задане значення верхньої межі менше будь-якого зі значень регістрів порога порівняння, збіг між TCNTn та OCRnx ніколи не настане.

На малюнку 4 показано, що на відміну від режиму ШІМ ФК, вихідний сигнал, що генерується, симетричний на всіх періодах. Оскільки регістри OCRnx оновлюються на нижній межі рахунку, то тривалості прямого та зворотного рахунків завжди рівні. В результаті вихідні імпульси мають симетричну форму, а отже, і відкориговану частоту.

Використання регістра ICRn для завдання верхньої межі рекомендується, якщо значення верхньої межі є константою. У цьому випадку звільняється регістр OCRnA для широтно-імпульсної модуляції імпульсів на виведенні OCnA. Однак, якщо потрібна динамічна зміна частоти ШІМ за рахунок зміни верхньої межі, то для завдання верхньої межі рекомендується використовувати регістр OCRnA за рахунок наявності у нього подвійної буферизації.

У режимі ШІМ ФЧК блоки порівняння дозволяють генерувати ШІМ-імпульси на виведенні OCnx. Якщо COMnx1:0 = 0b10, то визначається неінвертуючий ШИМ вихід, а, якщо COMnx1:0=0b11, то інвертуючий (див. таблицю 60). Значення OCnx буде присутнє на відповідному виведенні порту тільки у випадку, якщо для нього задано вихідний напрямок. ШИМ сигнал генерується шляхом встановлення (скидання) регістра OCnx при збігу між OCRnx та TCNTn під час прямого рахунку та скидання (установки) регістра OCnx при збігу між OCRnx та TCNTn під час зворотного рахунку. Частота ШІМ в даному режимі при заданій верхній межі (ВП) рахунку визначається наступним чином:

де N - Коефіцієнт поділу предделителя (1, 8, 32, 64, 128, 256 або 1024).

Запис граничних значень регістр OCRnx пов'язана з особливими випадками в генерації ШИМ-сигналів в даному режимі. Якщо задати OCRnx рівним нижній межі (0x0000), то в неінвертуючому режимі на виході буде постійного бути низький логічний рівень, а при записі значення рівного верхньому межі на виході буде довго бути високий логічний рівень. В режимі інвертування наведені рівні будуть протилежними.

Якщо OCRnA використовується для завдання верхньої межі (WGMn3:0 = 0b1001) і COMnA1:0 = 0b01, то на виході OCnA буде генеруватися меандр.


Апаратна реалізація ШІМ дає безумовні переваги перед програмною, оскільки розвантажує процесор як зайвим та громіздким кодом, так і часом на його обслуговування, а також дає більше можливостей використання роботи з ШІМ. Достатньо провести ініціалізацію таймер/лічильника (занести необхідні значення в регістри використовувані таймер/лічильником) як таймер/лічильник може працювати незалежно від процесора, відповідно процесор може займатися іншими завданнями, тільки іноді звертаючись в необхідний момент для коригування або зміни режиму або отримання результатів від таймер /лічильника.

Опис прапорів переривань

T1 може генерувати переривання при наступі:

  1. переповнення рахункового регістру TCNT1;
  2. при рівності лічильного регістру TCNT1 та регістру порівняння OCR1A та OCR1B (окремо для кожного регістру);
  3. при збереженні рахункового регістра у регістрі захоплення ICR1.

T2 може генерувати переривання при наступі:

  1. переповнення рахункового регістру TCNT2;
  2. при рівності лічильного регістру TCNT2 та регістру порівняння OCR2.

Прапори всіх переривань перебувають у регістрі TIFR, а дозвіл/заборона переривань у регістрі TIMSK.

Розряди регістру TIMSK
Реєстр7 6 5 4 3 2 1 0
TIMSK OCIE2 TOIE2 TICIE1 OCIE1A OCIE1B TOIE1 OCIE0* TOIE0
  • OCIE2- Прапор дозволу переривання за подією "збіг" таймера/лічильника Т2
  • TOIE2- Прапор дозволу переривання з переповнення таймера/лічильника Т2
  • TICIE1- Прапор дозволу переривання за подією "захоплення" таймера/лічильника Т1
  • OCIE1A- Прапор дозволу переривання за подією "збіг А" таймера/лічильника Т1
  • OCIE1B- Прапор дозволу переривання за подією "збіг В" таймера/лічильника Т1
  • TOIE1- Прапор дозволу переривання з переповнення таймера/лічильника Т1
  • OCIE0*- Прапор дозволу переривання за подією "збіг" таймера/лічильника Т0 (* - відсутня в ATmega8)
  • TOIE0- Прапор дозволу переривання з переповнення таймера/лічильника Т0
  • OCF2- Прапор переривання за подією "збіг" таймера/лічильника Т2
  • TOV2- Прапор переривання з переповнення таймера/лічильника Т2
  • ICF1- Прапор переривання за подією "захоплення" таймера/лічильника Т1
  • OCF1A- Прапор переривання за подією "збіг А" таймера/лічильника Т1
  • OCF1B- Прапор переривання за подією "збіг В" таймера/лічильника Т1
  • TOV1- Прапор переривання з переповнення таймера/лічильника Т1
  • OCF0- Прапор переривання за подією "збіг" таймера/лічильника Т0
  • TOV0- Прапор переривання з переповнення таймера/лічильника Т0

Опис роботи тайтер/лічильника Т1 в контролері ATmega8/16

Шістнадцятирозрядний таймер/лічильник Т1 може використовуватися для формування часових інтервалів, підрахунку кількості зовнішніх сигналів, і для генерації сигналів з ШІМ різної шпаруватості та тривалості на висновках OC1A та OC1B. Крім того, за зовнішнім сигналом з виведення ICP1 або від аналогового компаратора, Т1 може зберігати свій поточний стан в окремому регістрі захоплення ICR1.

Розряди регістрів TCCR1A:TCC1B:TCNT1:OCR1A:OCR1B:ICR1
Реєстр7 6 5 4 3 2 1 0
TCCR1A COM1A1 COM1A0 COM1B1 COM1BO FOC1A FOC1B WGM11 WGM10
TCCR1B ICNC1 ICES1 * WGM13 WGM12 CS12 CS11 CS10
TCNT1:H R/W R/W R/W R/W R/W R/W R/W R/W
TCNT1:L R/W R/W R/W R/W R/W R/W R/W R/W
OCR1A:H R/W R/W R/W R/W R/W R/W R/W R/W
OCR1A:L R/W R/W R/W R/W R/W R/W R/W R/W
OCR1B:H R/W R/W R/W R/W R/W R/W R/W R/W
OCR1B:L R/W R/W R/W R/W R/W R/W R/W R/W
ICR1:H R/W R/W R/W R/W R/W R/W R/W R/W
ICR1: L R/W R/W R/W R/W R/W R/W R/W R/W

Кожен 16-розрядний регістр фізично розміщується у двох 8-розрядних регістрах тому під час читання записи у яких потрібно виконати дві операції. При записі першим завантажується старший байт потім молодший, читанні навпаки спочатку молодший прочитується потім старший.

TCCR1A:TCCR1B- 8-розрядні регістри керування таймером/лічильником Т1

TCNT1- 16-розрядний рахунковий регістр таймера/лічильника Т1. Залежно від режиму роботи вміст цього регістру обнулюється, інкрементується (збільшується значення на 1) або декрементується (зменшується значення на 1) за кожним імпульсом тактового сигналу таймера/лічильника.

OCR1A:OCR1B- 16-розрядні регістри порівняння

ICR1- 16-розрядний регістр захоплення,зберігає значення TCNT1 під час подачі активного фронту сигналу виведення ICP1 чи з сигналу від компаратора.

Призначення бітів

COM1A1:COM1A0:COM1B1:COM1B0- Ці розряди визначають поведінку виведення OC1A:OC1B при збігу значення лічильного регістру TCNT1 та регістру порівняння OCR1A:OCR1B

FOC1A:FOC1B- Ці розряди служать для примусового зміни стану виведення OC1A:OC1B

ICNC1- Розряд управління схемою перешкод, якщо біт дорівнює "0" захоплення буде по першому активному фронту, якщо "1" захоплення буде після четвертої однакової вибірки сигналу захоплення.

ICES1- Розряд вибору активного фронту сигналу, якщо його значення дорівнює "0", збереження рахункового регістра TCNT1 в регістрі захоплення OCR1 буде по фронту сигналу, що спадає, якщо "1" по наростаючому.

WGM13:WGM12:WGM11:WGM10- Ці розряди визначають режим роботи таймера/лічильника Т1

CS22:CS21:C20- Розряди, що визначають джерело тактового сигналу таймера/лічильника Т1.

Вибір режиму роботи таймера/лічильника Т1
WGM13WGM12WGM11WGM10Режим роботиМодуль рахунку (TOP)
0 0 0 0 Normal $FFFF
0 0 0 1 Phase correct PWM

8-розрядний

$00FF
0 0 1 0 Phase correct PWM

9-розрядний

$01FF
0 0 1 1 Phase correct PWM

10-розрядний

$03FF
0 1 0 0 CTC (скидання під час збігу) OCR1A
0 1 0 1 Fast PWM

8-розрядний

$00FF
0 1 1 0 Fast PWM

9-розрядний

$01FF
0 1 1 1 Fast PWM

10-розрядний

$03FF
1 0 0 0 ICR1
1 0 0 1 Phase and Freguensy Correct PWM OCR1A
1 0 1 0 Phase correct PWM ICR1
1 0 1 1 Phase correct PWM OCR1A
1 1 0 0 CTC (скидання під час збігу) ICR1
1 1 0 1 Зарезервовано *
1 1 1 0 Fast PWM ICR1
1 1 1 1 Fast PWM OCR1A

Вибір джерела тактового сигналу

Режим Normal

Найпростіший режим роботи Т1. По кожному імпульсу тактового сигналу відбувається інкремент лічильного регістра TCNT1 (збільшення значення 1). При переході через значення $FFFF модуля рахунку (ТОР) виникає переповнення і наступному такті починається рахунок зі значення $0000, у цей момент встановлюється прапор TOV1=1 у регістрі TIFR, і може бути згенеровано переривання якщо встановлено прапор TOIE1=1 у регістрі TIMSK. Для того, щоб згенерувати сигна заданої частоти в цьому режимі, необхідно записати в розряди COM1A1=0:COM1A0=1 для виведення OC1A або COM1B1=0:COM1B0=1 для виведення OC1B контролера.

Крім того, по кожному такту відбувається порівняння рахункового регістра TCNT1 і регістра порівняння OCR1A:OCR1B, при збігу встановлюється прапор переривання OCF1A=1:OCF1B=1 і якщо розряд OCIE1A=1:OCIE1B=1 регістра TIMSK генерується переривання. У той самий момент може бути змінено стан виведення OC1A:OC1B залежно від установок біт COM1A1:COM1A0:COM1B1:COM1B0.

Режим СТС (скидання при збігу)

У цьому режимі Т1 працює за таким же принципом, як і в режимі Normal. Відмінність полягає в тому, що максимально можливе значення рахункового регістра TCNT1 обмежується значенням регістру порівняння OCR1A або ICR1 (див. таблицю вибору режиму таймер/лічильника). При досягненні TCNT1 значення OCR1A або ICR1, значення TCNT1 обнулюється в TCNT1=$0000 У цей момент встановлюється прапор TOV1=1 COM1A1:COM1A0:COM1B1:COM1B0 Визначають поведінка виведення ОС1A:OC1B при збігу.

Режим Fast PWM (швидкодіючий ШІМ)

За допомогою цього режиму можна генерувати високочастотний сигал ШІМ. Принцип і порядок роботи не відрізняється від режиму Normal, крім наявності подвійної буферизації регістра OCR1A: OCR1B, завдяки якому виключається поява несиметричних імпульсів сигналу, а також поведінкою висновків ОС1A:OC1B (див. таблицю).


Режим Phase Correct PWM (ШИМ із точною фазою)

Відмінність цього режиму від попередніх у тому, що лічильний регістр працює як реверсивний лічильник. Так як цей режим рекомендується Atmel як найбільш підходящий для регулювання двигунів, ми його розглянемо докладніше. При досягненні рахунковим регістром TCNT1 значення модуля рахунку (ТОР) (або значення регістра ICR1 або значення регістра OCR1A, дивіться таблицю вибору режиму таймер/лічильника), відбувається зміна напряму рахунку. При досягненні лічильним регістром TCNT1 мінімального значення ($0000) також відбувається зміна напряму рахунку й у той самий момент встановлюється прапор переривання TOV1 регістру TIFR. Також при рівності вмісту рахункового регістра TCNT1 і регістру порівняння OCR1A:OCR1B ,встановлюється прапор OCF1A:OCF1B регістра TIFR і змінюється стан виведення OC1A:OC1B,согласно таблиці.

Щоб уникнути несиметричних викидів під час запису значення регістру OCR1A:OCR1B, в цьому режимі реалізована подвійна буферизація запису. Завдяки цьому дійсна зміна значення регістра змінюється в момент досягнення рахунковим регістром TCNT1 значення модуля рахунку (ТОР) (або значення регістра ICR1 або значення регістра OCR1A дивіться таблицю вибору режиму таймер/лічильника). Тому на самому початку, при ініціалізації таймер/лічильника висновок ОС1A:OC1B не змінить свій стан при збігу доти, доки регістр не досягне значення (ТОР).


Завдання:Розробимо програму управління яскравістю лампи розжарювання на 12 Вольт за допомогою ШІМу. При натисканні на кнопку "Більше" яскравість лампи збільшується, при натисканні на кнопку "Менше" яскравість зменшується. Схема нашого майбутнього пристрою показана малюнку. Як зазвичай використовуємо мікроконтролер Atmega8, який тактуватиметься від внутрішнього генератора частотою 4MHz. Власне у нас вийде димер, ці пристрої призначені для регулювання яскравості освітлювальних приладів. Зараз найбільшого поширення набули світлодіодні димери.

Для простоти до нашої схеми можна підключити світлодіод, але з лампочкою буде наочніше. Кнопки підключені до висновків PD0, PD1. Навантаження підключаємо до висновку PB1(OC1A)через резистор та польовий транзистор MOSFET, який і працюватиме у нас як ключ (у ключовому режимі). Польовий транзистор краще тому, що його затвор ізольований від силової схеми і управління виробляється електричним полем, а струм управління досягає мікроампер. Це дозволяє, використовуючи один-два транзистори, керувати навантаженням величезної потужності (до десятків ампер і десятків-сот вольт), не навантажуючи мікроконтролер. Враховуючи також той факт, що польові транзисториможна з'єднувати паралельно (на відміну біполярних), можливо отримати ще потужніший каскад на сотні ампер.

Тепер розберемося, як мікроконтролер реалізує ШІМ та напишемо програму. Як уже говорилося раніше, у нашому МК є 3 таймери, і всі вони можуть працювати в ШІМ-режимі. Ми будемо працювати з шістнадцятирозрядним таймером/лічильником. Бітамі WGM13-10налаштуємо наш таймер на роботу FastPWM з верхньою межею рахунку ICR1. Принцип програми такий, наш таймер рахує від 0 до 65535(0xFFFF), в регістр ICR1впишемо число 255, це буде верхня межа рахунку таймера (TOP), частота ШИМ сигналу буде постійною. Також наш таймер налаштований на те, що при збігу рахункового регістру та регістру порівняння (TCNT1 = OCR1A) буде перемикатися висновок контролера OC1A. Коефіцієнт заповнення ШІМ можна змінити, записавши в регістр порівняння OCR1Aпевне число від 0 до 255, чим більше це число тим більше буде коефіцієнт заповнення, тим яскравіше горітиме лампа. Залежно від того яка кнопка змінюється змінна i, а потім вона записується в регістр OCR1A.

Повний текст програми наведено нижче. У коментарях докладніше описано роботу програми.

/*** Заняття №8. Формування ШИМ сигналів ***/ #include #include int main(void) ( unsigned int i=0; //визначаємо змінну i /***Налаштування портів введення-виводу***/ PORTB = 0x00; DDRB |= (1<< PB1); PORTD |= (1 << PD1)|(1 << PD0); // подключаем внутренние нагрузочные резисторы DDRD = 0x00; /***Настройка таймера***/ TCCR1A |= (1 << COM1A1)|(0 << COM1A0) // Установим биты COM1A1-COM1A0:0b10, означает сброс вывода канала A при сравнении |(1 << WGM11)|(0 << WGM10); // Установим биты WGM13-10:0b1110, согласно таблице это TCCR1B |= (1 << WGM13)|(1 << WGM12) // будет режим - FAST PWM, где верхний предел счета задается битом ICR1 |(0 << CS12)|(0 << CS11)|(1 << CS10); // Битами CS12-10:0b001 задаем источник тактового сигнала для таймера МК, включен без делителя TCNT1 = 0x00; // начальная установка счетчика ICR1 = 0xFF; // задаем период ШИМ, здесь у нас число 255, // по формуле fPWM=fclk_I/O/N*(1+ICR1)// вычисляем частоту ШИМ, она будет равна 15625 Hz OCR1A = 0x00; // начальный коэффициент заполнения ШИМ /***Основной цикл программы***/ while(1) { if((PIND&(1 << PD0)) == 0) //если кнопка "больше" нажата { if (i < 254) { // коэффициент заполнения ШИМ изменяется от 0 до 255 i=i+1; // увеличиваем i на единицу OCR1A = i; // записываем переменную в регистр сравнения _delay_ms(30); // задержка 30ms } } if((PIND&(1 << PD1)) == 0) //если кнопка "меньше" нажата { if (i >0) // коефіцієнт заповнення ШІМ змінюється від 255 до 0 ( i--; // зменшуємо i на одиницю (так теж можна писати) OCR1A = i; // записуємо змінну в регістр порівняння _delay_ms(30); // затримка 30ms) ) ) )

Увага!Спершу подаємо харчування на мікроконтролер, потім потрібно переконатися, що транзистор приєднаний до висновку МК, і лише потім подавати живлення в ланцюг з лампою та польовим транзистором. Інакше можете спалити транзистор. Справа в тому, що у вимкненому стані "ніжки" МК "бовтаються у повітрі" - вони ні до чого не підключені, і на них виникають наведення. Цих слабких наведень достатньо, щоб частково відкрити дуже чутливий польовий транзистор. Тоді його опір між стоком і витоком впаде від кількох МОм до кількох Ом або часткою Ом і через нього потече великий струм до лампи. Але транзистор не відкриється повністю, тому що для цього потрібно подати на затвор не 1-3 наведення, а стабільні 5, і його опір буде набагато більше мінімального. Це призведе до виділення на ньому великої кількості тепла, і він задимиться, а може згоріти.

Ми торкнулися теми використання лічильника/таймера ATtiny13 у звичайному режимі та в режимі підрахунку імпульсів (CTC). У цій статті я продовжую тему таймера, але тепер ми розглянемо його застосування для реалізації широтно-імпульсної модуляції (ШІМ).

Усі мікропроцесори працюють із цифровими сигналами, тобто. з логічним нулем (0 В), та логічною одиницею (5 В або 3.3 В). Але що робити, якщо ми хочемо отримати на виході якесь проміжне значення? У таких випадках застосовують Широтно-імпульсну модуляцію(ШІМ, англ. pulse-width modulation (PWM)) - процес управління потужністю, що підводиться до навантаження, шляхом зміни шпаруватості імпульсів, при постійній частоті.
Широтно-імпульсна модуляція є періодичний імпульсний сигнал. Існують цифрові та аналогові ШІМ, однополярні та двополярні, і т.д. Але принцип їх роботи залишається однаковим незалежно від виконання і полягає в порівнянні двох видів сигналів: опорного (пилкоподібні або трикутні імпульси) і вхідного (постійного, або зміненого потрібним чином, залежно від конкретної задачі ШІМ). Ці сигнали порівнюються і при їх перетині змінюється рівень сигналу на виході ШІМ. Вихідна напруга ШІМ має вигляд прямокутних імпульсів, змінюючи їх тривалість, ми можемо регулювати середнє значення напруги на виході ШІМ.

* Якщо на виході ШІМ використовувати інтегруючу RC-ланцюг, то можна замість імпульсного отримати постійну напругу потрібної величини. Але в нашому прикладі зі світлодіодами можна обійтися і без цього, тому що людське око все одно не зможе розглянути мерехтіння світлодіода при тактовій частоті, що використовується.

Параметри ШІМ

  • T – період тактування (опорного сигналу);
  • t - тривалість імпульсу;
  • S – шпаруватість;
  • D – коефіцієнт заповнення.

Добре визначається ставленням періоду до тривалості імпульсу. Коефіцієнт заповнення - величина, зворотна шпаруватості (може виражатися у відсотках):

S=T/t=1/D

Розглянемо докладніше, як працює ШІМ в мікроконтроллерах AVR, на прикладі ATtiny13.
Як уже згадувалося в попередньому прикладі, в ATtiny13 реалізовано два різновиди ШІМ: так звані "Швидка ШІМ" (Fast PWM) і "ШИМ з корекцією фази" (Phase correct PWM). Обидва варіанти засновані на використанні вбудованого МК восьмибітного лічильника/таймера T0. Таймер використовується замість опорного сигналу. Тактова частота таймера задається головою тактової частоти процесора або від зовнішнього тактового генератора. Режим тактування задається бітами CS02 (2), CS01 (1), CS00(0) регістра TCCR0B:

  • 000 - таймер/лічильник T0 зупинено
  • 001 – тактовий генератор CLK
  • 010 - CLK/8
  • 011 - CLK/64
  • 100 - CLK/256
  • 101 - CLK/1024
  • 110 - від зовнішнього джерела на виведенні T0 (7 ніжка, PB2) по спаду сигналу
  • 111 - від зовнішнього джерела на виведенні T0 (7 ніжка, PB2) щодо зростання сигналу

Налаштування таймера для ШІМ

Режим роботи таймера задається бітами WGM01(1) та WGM00(0) регістра TCCR0A:

  • 00 - звичайний режим
  • 01 - режим корекції фази ШІМ
  • 10 - режим підрахунку імпульсів (скидання при збігу)
  • 11 - режим ШІМ

Тут нас цікавлять варіанти "01" та "11".

Біти COM0A1(7) та COM0A0(6) регістра TCCR0Aзадають, який сигнал з'явиться на виведенні OC0A (5 ніжка, PB0) при збігу лічильника (реєстр TCNT0) з регістром порівняння A ( OCR0A).

У режимі "Швидка ШІМ":

  • 10 - установка 0 на виведенні OC0A при збігу з A, установка 1 на виведенні OC0A при обнуленні лічильника (неінверсний режим)
  • 11 - установка 1 на виведенні OC0A при збігу з A, установка 0 на виведенні OC0A при обнуленні лічильника (інверсний режим)
  • 00 - висновок OC0A не функціонує
  • 01 - якщо біт WGM02 регістра TCCR0B встановлений у 0, висновок OC0A не функціонує
  • 01 - якщо біт WGM02 регістра TCCR0B встановлений в 1, зміна стану виведення OC0A на протилежне при збігу A
  • 10 - установка 0 на виведенні OC0A при збігу з A під час збільшення значення лічильника, установка 1 на виведенні OC0A при збігу з A під час зменшення значення лічильника (неінверсний режим)
  • 11 - установка 1 на виведенні OC0A при збігу з A під час збільшення значення лічильника, установка 0 на виведенні OC0A при збігу з A під час зменшення значення лічильника (інверсний режим)

Біти COM0B1(5) та COM0B0(4) регістру TCCR0Aзадають, який сигнал з'явиться на виведенні OC0B (6 ніжка, PB1) при збігу лічильника (реєстр TCNT0) з регістром порівняння B ( OCR0B).

У режимі "Швидка ШІМ":

  • 01 - резерв
  • 10 - установка 0 на виведенні OC0B при збігу з B, установка 1 на виведенні OC0B при обнуленні лічильника (неінверсний режим)
  • 11 - установка 1 на виведенні OC0B при збігу з B, установка 0 на виведенні OC0B при обнуленні лічильника (інверсний режим)

У режимі "ШИМ із корекцією фази":

  • 00 - висновок OC0B не функціонує
  • 01 - резерв
  • 10 - установка 0 на виведенні OC0B при збігу з B під час збільшення значення лічильника, установка 1 на виведенні OC0B при збігу з B під час зменшення значення лічильника (неінверсний режим)
  • 11 - установка 1 на виведенні OC0B при збігу з B під час збільшення значення лічильника, установка 0 на виведенні OC0B при збігу з B під час зменшення значення лічильника (інверсний режим)

Швидка ШІМ (Fast PWM)

У цьому режимі лічильник рахує від нуля до максимуму. При встановленні нульового значення лічильника - на виході з'являється імпульс (встановлюється логічна одиниця). При збігу з регістром порівняння - імпульс скидається (встановлюється логічний нуль). В інверсному режимі, відповідно, навпаки.

ШИМ із корекцією фази (Phase correct PWM)

У цьому режимі лічильник вважає від нуля до максимуму, а потім у зворотному напрямку до нуля. При збігу з регістром порівняння під час наростання значення лічильника – імпульс скидається (встановлюється логічний нуль). При збігу під час спадання – з'являється імпульс (встановлюється логічна одиниця). В інверсному режимі, відповідно, навпаки. Недоліком цього режиму є зменшена вдвічі тактова частота проти режимом Fast PWM. Зате при зміні шпаруватості не зміщуються центри імпульсів. Основне призначення даного режиму - робити багатофазні ШІМ сигнали, наприклад трифазну синусоїду, щоб при зміні шпаруватості не збивався кут фазового зсуву між двома ШІМ сигналами.

Щоб побачити наочно, як працює ШІМ, напишемо невелику програму (всі досліди я проводжу на своїй налагоджувальній платі, відповідно код наводжу стосовно неї):

/* * tiny13_board_pwm * Демо-прошивка налагоджувальної плати на ATtiny13. * Демонстрація роботи ШІМ на двох каналах: * неінверсний сигнал на виході OC0A, інверсний – на виході OC0B. */ #define F_CPU 1200000UL #include #include #define LED0 PB0 // OC0A #define LED1 PB1 // OC0B int main(void) ( // Світлодіоди: DDRB |= (1<< LED0)|(1 << LED1); // выходы = 1 PORTB &= ~((1 << LED0)|(1 << LED1)); // по умолчанию отключены = 0 // Таймер для ШИМ: TCCR0A = 0xB3; // режим ШИМ, неинверсный сигнал на выходе OC0A, инверсный - на выходе OC0B TCCR0B = 0x02; // предделитель тактовой частоты CLK/8 TCNT0=0; // начальное значение счётчика OCR0A=0; // регистр совпадения A OCR0B=0; // регистр совпадения B while(1) { do // Нарастание яркости { OCR0A++; OCR0B = OCR0A; _delay_ms(5); } while(OCR0A!=255); _delay_ms(1000); // Пауза 1 сек. do // Затухание { OCR0A--; OCR0B = OCR0A; _delay_ms(5); } while(OCR0A!=0); _delay_ms(1000); // Пауза 1 сек. } }

Тут бачимо, що з старті МК в регістри порівняння A і B встановлюється 0, а лічильник запускається як Fast PWM, з генерацією неинверсного ШИМ сигналу на виході OC0A і інверсного - на виході OC0B. В основному циклі значення регістрів порівняння плавно змінюються від 0 до максимуму та назад. В результаті, світлодіоди, підключені до висновків OC0A і OC0B, по черзі плавно загорятимуться і гаснуть, як би в протифазі.
Але якщо придивитися уважніше, то бачимо, що один із світлодіодів гасне не до кінця, а продовжує тьмяно світитися. Ця особливість й у Fast PWM режиму. Справа в тому, що в цьому режимі, навіть якщо записати в регістр порівняння 0, при обнуленні лічильника на виході все одно встановлюється логічна одиниця, яка скидається в наступному такті (збігається з регістром порівняння). Таким чином, у кожному періоді проскакуватимуть по одному короткому імпульсу тривалістю 1 такт, але цього достатньо для засвічування світлодіода. Цей ефект немає в інверсному режимі формування вихідних імпульсів, т.к. у разі при обнуленні лічильника відбуватиметься не короткий імпульс, а навпаки - короткий провал під час максимального заповнення ШИМ. Цей провал можна побачити на осцилографі, але таке мерехтіння світлодіода людського зору просто не помітить. Тому другий світлодіод спалахує і гасне повністю. У режимі ШІМ з корекцією фази цей ефект відсутній незалежно, інверсний сигнал формується на виході чи ні. Поміняємо значення біта WGM01(1) регістру TCCR0Aз 1 на 0.

ШІМ (PWM) - широтно-імпульсна модуляція. Не потрібно лякатися цього терміна. Це всього лише спосіб регулювання напруги. Допустимо підсвічування монітора горить надто яскраво, ви змінюєте яскравість. А що ж відбувається у цей момент насправді?

Уявімо, що підсвічування монітора це кілька світлодіодів. Живиться вся ця справа від постійної напруги. Але нам знадобилося зменшити яскравість монітора. Логічно відповісти, що це можна зробити змінним резистором. На маленьких струмах можливо. Але на великих, резистор сильно грітиметься. Сильно зростуть габарити, втрати, енергоспоживання.

Тому люди придумали схему на транзисторах, яка робить з постійної напруги пульсуючу. Виявляється, пульсуюча напруга, залежно від заповнення періоду, буде еквівалентна постійному напрузі. Тобто. якщо протягом періоду напруга 50% часу було включено, 50% вимкнено, то еквівалент постійної напруги дорівнюватиме 50% від номінального.

У цифрах це просто – було 5В постійної напруги прогнали через ШІМ – отримали 2,5В. Якщо заповнення імпульсу дорівнює 75%, еквівалентна постійна напруга буде 3,75В. Думаю, ідея зрозуміла.

Тепер приступимо до практичної реалізації. Будемо за допомогою мікроконтролера змінювати наповнення від 0 до 100%, потім від 100% до нуля. Кінцевий результат має виглядати так:

Щоб було наочно, підключимо світлодіод. В результаті у нас буде плавно вмикатися та відключатись світлодіод.

Запускаємо наш улюблений CodeVision. Створюємо проект за допомогою майстра. У розділі таймерів (Timers) вибираємо Timer 2 і виставляємо налаштування як на малюнку.

Якщо спробувати згенерувати проект, то прога може сваритися. Погоджуємося, адже у нас нога 3 порти В має бути налаштована як вихід.

Наводимо код до такого виду:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include void main (void) (PORTB = 0x00; DDRB = 0x08; // Timer/Counter 2 initialization ASSR = 0x00; TCCR2 = 0x6C; TCNT2 = 0x00; OCR2 = 0x00; TIMSK = 0x00; while (1) (); )

#include void main(void) ( PORTB=0x00; DDRB=0x08; // Timer/Counter 2 initialization ASSR=0x00; TCCR2=0x6C; TCNT2=0x00; OCR2=0x00; TIMSK=0x00; while (1) ( );

Приділимо увагу рядку OCR2 = 0x00; Ця змінна таки відповідає за величину заповнення імпульсу. Змінюється ця величина від 0 до 255(0хFF), тобто. 255 відповідає 100% заповненню (постійний струм). Отже, якщо потрібно 30% наповнення (255/100)*30=77. Далі 77 переводимо в шістнадцяткову систему OCR2 = 0x4D;

TCCR2=0x6C; Змінюючи цю величину ми можемо регулювати частоту ШІМ. Розмір частоти роботи ШІМ кратна частоті, де працює микроконтроллер. У проекті використано частоту мікроконтролера 8 МГц, частоту ШІМ використовували 125кГц, отже дільник дорівнює 8/125=64
0x6C в двійковій системі числення 1101100, відкриваємо даташит на Atmega8 і бачимо опис регістра TCCR2, так ось 1101 100 останні цифри 100 та відповідають за вибір частоти роботи ШІМ

Приступимо безпосередньо до програми:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #include #include void main (void) (PORTB = 0x00; DDRB = 0x08; ASSR = 0x00; TCCR2 = 0x6C; TCNT2 = 0x00; OCR2 = 0x00; TIMSK = 0x00; while (1)< 0xff ) { OCR2= OCR2+ 0x01 ; delay_ms(5 ) ; } while (OCR2>0x00) (OCR2 = OCR2-0x01; delay_ms(5);))); )

#include #include void main(void) ( PORTB=0x00; DDRB=0x08; ASSR=0x00; TCCR2=0x6C; TCNT2=0x00; OCR2=0x00; TIMSK=0x00; while (1) ( while(OCR2<0xff) { OCR2=OCR2+0x01; delay_ms(5); } while(OCR2>0x00) (OCR2=OCR2-0x01; delay_ms(5); )); )

Код простий до неподобства: спочатку циклі збільшуємо заповнення від 0 до 255(ff), потім зменшуємо від 255 до 0.
І насамкінець видосик, як це все має працювати. Успіхів у вивченні)

Оновлено 16.12.15. Всім привіт. Розібравшись у минулому записі з пам'яттю EEPROM, сьогодні ми поговоримо про те, що таке ШІМ (PWM)? Розшифрується як широтно-імпульсна модуляція (pulse-width modulation), це середнє значення напруги, яке змінюється шпаруватістю імпульсу. В свою чергу свердловість це тривалість імпульсу із деякою частотою повторення. Тобто. Найпростішими словами усе це зміна ширини імпульсу за постійної їх величині. Навіщо це нам треба?

ШІМ (PWM) використовується в транзисторній схемі для регулювання напруги без механіки, своєю чергою управління потужністю. Наприклад, управління яскравістю світлодіодів, управління яскравістю підсвічування на LCD-моніторі, управління двигунами і т.д. Якщо відобразити на малюнку, то вихід із мікроконтролера приблизно буде наступним, як на малюнку нижче. Де видно що шпаруватість це заповнення імпульсу, якщо вся ширина імпульсу це 5, то при 30% заповненні імпульсу, в середньому на виході ми отримаємо приблизно 1,5В. У мікроконтролерах AVR ШИМ управління задається у восьмирозрядних таймерах/лічильниках T0/(T2) та шістнадцятирозрядний T1 (T3 у деяких моделях). А також є інші моделі, де бітність ШИМа можна задавати, наприклад ATmega 128. Розглянемо налаштування шістнадцятирозрядного таймера/лічильника Т1. Дані беремо відповідно до таблиць або з довідника, або з даташита (література — стаття №1).

Загалом для такого лічильника в мк можна вибрати три режими: Fast PWM, Phase Correct PWM, Phase and Frequency Correct PWM ( залежить від моделі)

Розглянемо другий режим - ШИМ із точною фазою. Тут лічильний регістр функціонує як реверсивний лічильник, зміни стану якого змінюється від $0000 до максимального значення, а потім назад до $0000. Для керування таймером/лічильником використовуємо три регістри керування TCCR1A, TCCR1B, TCCR1C. У яких для вибору режиму таймера/лічильника необхідно встановити розряди WGMn1: WGMn0 та WGMn1: WGMn0 . Залежно від їх встановлення максимальне значення лічильника (Роздільна здатність ШІМ сигналу) є або фіксованим значенням, або визначається вмістом певних регістрів таймера/лічильника. Роздільна здатністьвизначається виразом :

g = log (TOP+1)/log2, де ТОР - модуль рахунку, вибирається з таблиці відповідно роздільної здатності.

Після того, як визначилися з режимом роботи таймера лічильника, необхідно вибрати режим роботи блоку порівняння COMnA1: COMnA0, COMnB1: COMnB0, COMnC1: COMnC0, який визначає поведінку виводу OCnx при настанні події "Збіг".

Ну і останній штрих визначимося із частотою. Нам необхідно виставити розряди CSn2…CSn0 регістру TCCR1B, які відповідають визначення джерела тактового сигналу. Ось таким програмним чином виглядає налаштування ШИМ-керування на виході OC1A. Наприклад:

/*Налаштування ШИМ */
TCCR1A=(1</*На виведенні OC1A одиниця, коли OCR1A==TCNT1, Скидається в 0 при OCR1A==TCNT1 і встановлюється в 1 при досягненні максимального значення восьми бітний ШИМ Phase Correct PWM номер режиму 1 . модуль рахунку ТОР $00FF*/
TCCR1B=(1<OCR1A = 50; /* при модулі рахунку 255 і при напрузі 5 на виході OC1A отримаємо приблизно 1 В*/

З програми видно, що для отримання ШІМ використовуємо регістр порівняння OCR1A. При досягненні лічильником максимального значення, в даному випадку 255, відбувається зміна напрямку рахунку, але лічильник залишається в цьому стані протягом одного періоду сигналу. У цьому полягає більш повільна частота роботи проти першим режимом. Але в цьому полягає симетричність зміни лічильника. Що більш підходить для керування двигуном. У такому ж такті відбувається оновлення вмісту регістру порівняння. При досягненні лічильником мінімального значення відбувається зміна напрямку рахунку і одночасно встановлюється прапор переривання TOV1 регістра TIFR. При рівній вмісту рахункового регістра та будь-якого регістра порівняння встановлюється відповідний прапор OCF1A/OCF1B/OCF1C регістра TIFR. Одночасно змінюється стан виходу блоку порівняння OCnx. Ч астота сигналу, що генерується fOCn = f / (2 * N * TOP), де N - коефіцієнт поділу представника, f - Частота кварцу. Також можна подивитися ще приклади налаштування та використання ШІМ, наприклад .

На цьому сьогодні все. У наступному пості розглянемо контролер аматорського верстата ЧПУ. Я постараюся використати попередні пости з цього блогу для набору програми як конструктор. Так буде більш зрозуміло, коли один раз написали і його використали в наступному проекті. Всім до побачення.

У пристроях мікроконтролерів іноді потрібно генерувати аналоговий сигнал. Залежно від частоти аналогового сигналу, необхідного дозволу і типу мікроконтролера, що використовується, виконати це можна декількома способами. А саме: за допомогою широтно-імпульсної модуляції, використовуючи функціонал апаратних таймерів або програмну реалізацію, за допомогою вбудованого цифроаналогового перетворювача (ЦАП`а), за допомогою зовнішніх схем цифроаналогових перетворювачів на дискретних елементах або за допомогою зовнішніх мікросхем цифроаналогових.

1. Принцип генерації аналогового сигналу за допомогою ШІМ (PWM)

ШИМ сигнал є цифровий сигнал, у якого період повторення постійний, а тривалість змінюється. Відношення тривалості ШІМ сигналу до його періоду називається коефіцієнтом заповнення. Пропустивши такий сигнал через низькочастотний фільтр, що, по суті, рівносильно інтегруванню, ми отримаємо на виході фільтра рівень напруги пропорційний коефіцієнту заповнення.


Таким чином, мені цей коефіцієнт можна генерувати аналогові сигнали довільної форми. Причому як змінні, наприклад, синусоїда, пила чи людська мова, так і постійні (довільний рівень напруги).

1.1 Характеристики сигналу

Максимальна амплітуда вихідного аналогового сигналувизначатиметься амплітудою логічної одиниці цифрового ШІМ сигналу. Якщо мікроконтролер живиться від +5, то грубо кажучи, амплітуда вихідного аналогового сигналу буде від 0 до 5 В.

Мінімальний крок зміни аналогового сигналу(дозвіл) визначатиметься виразом:


dUa = Umax/2^n,


де Umax максимальна амплітуда аналогового сигналу (В), а n - розрядність лічильника, що реалізує ШІМ.

Наприклад, ШІМ сигнал формується за допомогою програмного 8-розрядного лічильника. Кількість градацій ШІМ сигналу, які можна отримати за допомогою цього лічильника, дорівнює 2^8 = 256. Тоді роздільна здатність аналогового сигналу при Umax = 5 В буде рівна


dUa = 5/256 = 0,0195 ст.


Частота ШИМ сигналувизначатиме так:


Fpwm = Fcpu/(K*2^n),


де Fcpu – тактова частота мікроконтролера (Гц), K – коефіцієнт предделителя лічильника, n – розрядність лічильника.

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

Fpwm = 8000000/(8*256) = ~3906 Гц


Частота вихідного аналогового сигналувизначатиметься виразом:

Fa = Fpwm/Ns = Fcpu/(K*2^n*Ns),


де Fpwm – частота ЩИМ сигналу, а Ns – кількість відліків аналогового сигналу.

Наприклад, ШІМ сигнал реалізується на 8-розрядному лічильнику з коефіцієнтом предделителя рівним 8 і тактовою частотою мікроконтролера 8 МГц. У пам'яті мікроконтролера записано 32 відліки синусоїдального сигналу, які є один його період. Тоді частота вихідної синусоїди дорівнюватиме:

Fa = 8000000 / (8 * 2 ^ 8 * 32) = ~ 122 Гц

Розрядність ЦАП`a зробленого на основі ШІМ еквівалентна розрядності використовуваного лічильника.

1.2 Апаратна реалізація ШІМ

Усі сучасні мікроконтролери мають у своєму складі таймери/лічильники. Один або кілька режимів цих таймерів призначені для генерації ШІМ сигналу. Як правило, цей сигнал генерується на спеціальних висновках. Наприклад, у мікроконтролера mega16 фірми Atmel 8-розрядний таймер/лічильник Т0 має два режими генерації ШІМ сигналу (швидкий ШІМ і ШІМ з точною фазою), а для виведення сигналу використовується пін порту B - OC0 (PINB3).

Гідність апаратної реалізації ШІМ сигналу - це низьке завантаження мікроконтролера (переривання викликається один раз на період ШІМ сигналу), простота використання та точність (якщо в системі мало переривань). З недоліків можна відзначити - обмежена роздільна здатність лічильників, невисока частота, обмежена кількість каналів, на яких можна генерувати ШІМ сигнали. Хоча існують спеціальні мікроконтролери спеціально "заточені" для генерації великої кількості ШІМ сигналів.

1.3 Програмна реалізація ШІМ

Також можна генерувати ШІМ сигнал програмно.Для цього потрібно просто створити програмний лічильник і за сигналом апаратного таймера інкрементувати його значення та відслідковувати досягнення крайніх значень лічильника, в яких ШІМ сигнал змінює стан.

Перевага програмної реалізації - простота, необмежену кількість каналів, необмежений дозвіл. Звичайно, умовно необмежена, з урахуванням доступної пам'яті.Недоліки програмної реалізації – високе завантаження мікроконтролера. Переривання повинні викликатися на кожен інкремент лічильника і щоразу потрібно перевіряти, чи не досяг він одного з крайніх значень. Також програмна реалізація має меншу точність (більше тремтіння фронтів сигналу) та ще меншу частоту (через перший недолік).

Однак, незважаючи на це, програмна реалізація ШІМу теж має місце бути, якщо потрібно генерувати постійний аналоговий сигнал або змінний, але з невисокою частотою.

Нижче наведено приклад коду, який виконує функцію генерацію аналогового сигналу за допомогою апаратної та програмної широтно-імпульсної модуляції. Код написаний для мікроконтролера atmega16, тактова частота 8 МГц, компілятор IAR. На виходах PB2 та PB3 генеруються дві синусоїди (різної частоти) з 32 двох відліків.


#include
#include
#include

#define SPWM_PIN 2

//таблиця синуса
__flash uint8_t tableSin =
{
152,176,198,218,234,245,253,255,
253,245,234,218,198,176,152,128,
103, 79, 57, 37, 21, 10, 2, 0,
2, 10, 21, 37, 57, 79,103,128
};

uint8_t softCount = 0;
uint8_t softComp = 0;

int main(void)
{
//Налаштування портів
PORTB = 0;
DDRB = 0xff;

//Дозвол переривання за збігом Т0
TIMSK = (1<//Режим FastPWM, неінв. ним сигнал, предделитель 8
TCCR0 = (1< (0<

//обнулюємо рахунковий регістр
TCNT0 = 0;
OCR0 = 0;

Enable_interrupt();
while(1);
return 0;
}

//переривання таймера Т0
#pragma vector = TIMER0_COMP_vect
__interrupt void Timer0CompVect(void)
{
static uint8_t i = 0;
static uint8_t j = 0;

OCR0 = tableSin [i];
i = (i + 1) & 31;

//програмний ШІМ
softCount++;
if (softCount == 0)(
PORTB |= (1<softComp = tableSin [j];
j = (j + 1) & 31;
}

If (softCount == softComp)(
PORTB &= ~(1< }
}

1.4 Фільтр для ШІМ

Частота зрізу фільтра повинна бути між максимальною частотою аналогових сигналів, що генеруються, і частотою ШІМ сигналу. Якщо частота зрізу фільтра буде обрана близько до межі смуги аналогового сигналу, це призведе до його ослаблення. А якщо частота зрізу фільтра буде близько до частоти ШІМ сигналу, аналоговий сигнал просто не "виділиться". Чим вище частота ШІМ сигналу, тим простіше реалізувати вихідний фільтр.

Розглянемо приклад. ШИМ сигнал генерується апаратним 8-розрядним лічильником з коефіцієнтом предделителя рівним 8, тактова частота мікроконтролера 8МГц, кількість відліків аналогового сигналу - 32.

Частота ШИМ сигналу дорівнюватиме:

Fpwm = Fcpu/(K*2^n) = 8000000/(8*256) = ~3906 Гц

Частота аналогового сигналу дорівнюватиме:

Fa = Fpwm/Ns = 3906/32 = 122 Гц

Виберемо частоту зрізу рівну 200 Гц та розрахуємо номінали пасивного низькочастотного RC фільтра. Частота зрізу такого фільтра визначається виразом:

Fc = 1/(2*Pi*R*C),

де R - номінал резистора (Ом), а C -ємність конденсатора (Ф).

Задавшись номіналом одного з компонентів, можна обчислити номінал другого. Для резистора номіналом 1 кОм, ємність конденсатора дорівнюватиме:


C = 1/(2*Pi*Fc*R) = 1/(6.28*1000*200) = ~0.8 мкФ


Вибираємо найближче значення з ряду E12 – 0.82 мкФ. За таких номіналів фільтра ми отримаємо вже схожий аналоговий сигнал.

Однак, як правило, однієї ланки пасивного фільтра буде замало. Тому що після нього аналоговий сигнал все ще міститиме велику кількість гармонік.

© 2022 androidas.ru - Все про Android