AVR Timers-PWM Mode-Part II

 AVR Seriestento článek je pokračováním předchozího příspěvku PWM. Naučte se, jak naprogramovat časovače pro provoz v režimu PWM! Tak začněme!

Ahoj lidi! Dlouho jsme se neviděli! 🙂

v mém předchozím příspěvku jsme diskutovali o základních pojmech PWM. Pojďme to nejprve shrnout:

  • PWM je zkratka pro pulzní šířkovou modulaci.
  • může být generován porovnáním předem stanoveného průběhu s referenční úrovní napětí nebo vytvořením jednoduchých analogových obvodů.
  • pracovní cyklus křivky PWM je dán následujícím vztahem.
pracovní cyklus
  • existují tři režimy provozu PWM-rychlý PWM, fázový správný PWM a frekvenční a fázový správný PWM
  • jak vybrat časovač, provozní režim a porovnat výstupní režim pro generování požadovaného PWM.
takže teď, bez větších potíží, uvidíme, jak jej implementovat pomocí mikrokontrolérů AVR. Než budeme pokračovat, doporučuji vám projít mé předchozí příspěvky na časovače a PWM.

Vezměme si problémové prohlášení. Potřebujeme vygenerovat 50 Hz PWM signál, který má 45% Pracovní cyklus.

analýza

vzhledem k tomu, že

Frequency = 50 Hz

jinými slovy, časové období, T

T = T(on) + T(off) = 1/50 = 0.02 s = 20 ms

také vzhledem k tomu, že

Duty Cycle = 45%

řešení podle výše uvedené rovnice získáme

T(on) = 9 msT(off) = 11 ms

nyní toho lze dosáhnout dvěma způsoby:

  1. použijte časovač v režimu CTC
  2. použijte časovač v režimu PWM

metodika-režim CTC

dobře, takže zde nebudu psát žádný kód (pouze pseudo kód). Předpokládám, že po přečtení mých předchozích příspěvků jste dost chytří na to, abyste jeden napsali sami! Budeme diskutovat pouze o koncepcích.

Nejprve zvolte vhodný časovač. Pro tuto aplikaci si můžeme vybrat některý ze tří časovačů dostupných v ATMEGA32. Vyberte si vhodný předepisovač. Poté nastavte časovač a pokračujte jako obvykle. Háček spočívá v tom, že je třeba aktualizovat porovnávací hodnotu OCRx register pokaždé. Jeden takový způsob je popsán v níže uvedeném pseudo kódu.

to je analogické s tradičním LED blikačem, s výjimkou skutečnosti, že časy zapnutí a vypnutí jsou odlišné.

Pseudo kód

#include <avr/io.h>#include <avr/interrupt.h> uint8_t count = 0; // global counter // initialize timer, interrupt and variablevoid timerX_init(){ // set up timerX with suitable prescaler and CTC mode // initialize counter // initialize compare value // enable compare interrupt // enable global interrupts} // process the ISR that is firedISR (TIMERx_COMPA_vect){ // do whatever you want to do here // say, increment the global counter count++; // check for the global counter // if count == odd, delay required = 11 ms // if count == even, delay required = 9 ms // thus, the value of the OCRx should be constantly updated if (count % 2 == 0) OCRx = 9999; // calculate and substitute appropriate value else OCRx = 10999; // calculate and substitute appropriate value} int main(void){ // initialize the output pin, say PC0 DDRC |= (1 << 0); // initialize timerX timerX_init(); // loop forever while(1) { // do nothing }}

nyní je to jedna metoda. A je to velmi neefektivní. Jeho účinnost můžete zvýšit napsáním lepšího kódu C (syntaxe), koncept však zůstává stejný. Pokud máte nějakou jinou metodu / koncept, jste velmi vítáni sdílet zde! 🙂

aktualizace: jeden ze čtenářů maxEmbedded,“ coolpales “ napsal tento kód a pracoval pro něj.

Vezměte prosím na vědomí, že tento kód ještě nebyl testován! Tak, pokud to někdo z vás zkouší, Zveřejněte zde své výsledky, rád bych je viděl! 🙂

metodika-režim PWM

dobře, takže nyní se dozvíte o režimu PWM. Režim PWM v AVR je hardwarově řízen. To znamená, že všechno, tím vším, co mám na mysli „všechno“, provádí procesor AVR. Vše, co musíte udělat, je Inicializovat a spustit časovač a nastavit pracovní cyklus! Super, co?! Naučme se jak!

zde jsem použil Timer0 ATMEGA32 pro demonstraci. Můžete si také vybrat jakýkoli jiný časovač nebo mikrokontrolér AVR. Nyní se podívejme na registry.

Tccr0-Timer/Counter0 Control Register

narazili jsme na tento registr v mém tutoriálu Timer0. Zde se naučíme, jak nastavit vhodné bity pro spuštění časovače v režimu PWM.

TCCR0 Register

Tccr0 Register

budeme diskutovat pouze o těch bitech, které nás nyní zajímají.

  • Bit 6,3-WGM01: 0-režim generování křivek-tyto bity lze nastavit na “ 00 „nebo“ 01 “ v závislosti na typu PWM, který chcete vygenerovat. Tady je vyhledávací stůl.
    popis bitového režimu generování křivek

    popis bitového režimu generování křivek

  • Bit 5,4-COM01: 0 – režim porovnání shody výstupu – tyto bity jsou nastaveny pro řízení chování výstupního porovnávacího pinu (OC0, pin 4 v ATMEGA32) v souladu s bity WGM01:0. Následující vyhledávací tabulka určuje operace oc0 pin pro rychlý režim PWM.
     porovnat výstupní režim, Rychlý režim PWM

    porovnat výstupní režim, Rychlý režim PWM

    nyní se podívejme na rychlé průběhy PWM. Podrobné vysvětlení naleznete v mém předchozím tutoriálu.

     rychlý PWM

    rychlý PWM

    nyní vám dovolte připomenout, že AVR PWM je plně hardwarově řízen, což znamená, že i operace porovnání časovače se provádí procesorem AVR. Vše, co musíme udělat, je říct CPU, co má dělat, jakmile dojde k shodě. Com01: 0 kolíky přicházejí do hry zde. Vidíme, že nastavením na “ 10 „nebo“ 11 “ je výstupní pin OC0 nastaven nebo vymazán (jinými slovy určuje, zda je PWM v invertovaném režimu nebo v neinvertovaném režimu).

    podobně pro Phase Correct PWM, vyhledávací tabulka a průběhy jdou takto.

     porovnat výstupní režim, fázový správný režim PWM

    porovnat výstupní režim, fázový správný režim PWM

    Phase Correct PWM

    Phase Correct PWM

    i zde nastavení COM01: 0 na “ 10 „nebo“ 11 “ určuje chování oc0 pin. Jak je znázorněno na křivkách, existují dva případy-jeden během počítání nahoru a druhý během počítání dolů. Chování je jasně popsáno v tabulce vyhledávání.

    Upozorňujeme, že OC0 je výstupní pin. Účinky WGM a COM se tedy nedostanou do hry, pokud není registr DDRx správně nastaven. Další informace naleznete v tomto tutoriálu.

  • Bit 2: 0-CS02: 0-Clock Select bity-tyto bity jsou již popsány v tutoriálu Timer0.

OCR0-Output Compare Register

narazili jsme i na tento registr v mém tutoriálu Timer0. Tento registr používáme k uložení porovnávací hodnoty. Ale když použijeme Timer0 v režimu PWM, hodnota uložená v něm funguje jako pracovní cyklus (samozřejmě!). V prohlášení o problému je dáno, že pracovní cyklus je 45%, což znamená

OCR0 = 45% of 255 = 114.75 = 115

a to je vše! Nyní jsme připraveni na to napsat kód! 🙂

upravit: Poznámka

následující kód popisuje, jak vytvořit signál PWM požadovaného pracovního cyklu. Pokud chcete změnit jeho frekvenci, musíte změnit nejvyšší hodnotu, což lze provést pomocí registru ICRx (který není podporován 8bitovými časovači). Pro 16-bit Timer1, to může být měněno pomocí ICR1A. budu diskutovat o tom brzy, když budeme diskutovat o servo řízení.

kód

takže tady jde kód. Chcete-li se dozvědět o operacích I/O portů v AVR, podívejte se na toto. Chcete-li vědět o bitových manipulacích, podívejte se na toto. Chcete-li se dozvědět, jak používat AVR Studio 5, podívejte se na toto. Chcete-li se dozvědět, jak je tento kód strukturován, podívejte se na předchozí příspěvek TIMER0.

#include <avr/io.h>#include <util/delay.h>void pwm_init(){ // initialize TCCR0 as per requirement, say as follows TCCR0 |= (1<<WGM00)|(1<<COM01)|(1<<WGM01)|(1<<CS00); // make sure to make OC0 pin (pin PB3 for atmega32) as output pin DDRB |= (1<<PB3);} void main(){ uint8_t duty; duty = 115; // duty cycle = 45% of 255 = 114.75 = 115 // initialize timer in PWM mode pwm_init(); // run forever while(1) { OCR0 = duty; }}

problémové prohlášení

takže teď si vezměme další problémové prohlášení. Tenhle bude více praktické věci na rozdíl od předchozího!

Vezměme si tradiční LED blikač, kde potřebujeme blikat LED na určité frekvenci. Ale hej, počkejte, nediskutovali jsme o tom dlouho zpět v tomto příspěvku(přejděte dolů na konec)? Hmm, tak to upravme tak, aby zahrnovalo PWM. Na rozdíl od tradiční LED blikač (kde LED diody jsou buď zapnout nebo vypnout), umožňuje, aby to zářit při maximálním jasu, a pak pomalu snižovat jeho jas, dokud nedosáhne nuly, a pak znovu zvýšit jeho jas pomalu, dokud se nestane maximum.

analýza a kód

tak jak to uděláme? Ano, uhodli jste to správně! Snižte pracovní cyklus pomalu z 255 na nulu a poté jej zvyšte z nuly na 255. V závislosti na pracovním cyklu se mění napětí aplikované na LED, a tím i jas. Následující vzorec udává vztah mezi napětím a pracovním cyklem.

v_out rovnice

takže tady jde kód. Nebudu to vysvětlovat, můžete to dekódovat sami. Chcete-li se dozvědět o operacích I/O portů v AVR, podívejte se na toto. Chcete-li vědět o bitových manipulacích, podívejte se na toto. Chcete-li se dozvědět, jak používat AVR Studio 5, podívejte se na toto. Chcete-li se dozvědět, jak je tento kód strukturován, podívejte se na předchozí příspěvek TIMER0.

// program to change brightness of an LED// demonstration of PWM #include <avr/io.h>#include <util/delay.h> // initialize PWMvoid pwm_init(){ // initialize timer0 in PWM mode TCCR0 |= (1<<WGM00)|(1<<COM01)|(1<<WGM01)|(1<<CS00); // make sure to make OC0 pin (pin PB3 for atmega32) as output pin DDRB |= (1<<PB3);} void main(){ uint8_t brightness; // initialize timer0 in PWM mode pwm_init(); // run forever while(1) { // increasing brightness for (brightness = 0; brightness < 255; ++brightness) { // set the brightness as duty cycle OCR0 = brightness; // delay so as to make the user "see" the change in brightness _delay_ms(10); } // decreasing brightness for (brightness = 255; brightness > 0; --brightness) { // set the brightness as duty cycle OCR0 = brightness; // delay so as to make the user "see" the change in brightness _delay_ms(10); } // repeat this forever }}

tak tady končí můj další hodně očekávaný a dlouhý tutoriál! Další na řadě.. Sériová Komunikace! Uvidíme se!! 🙂

a jo, pokud máte nějaké návrhy, pochybnosti, konstruktivní kritiku atd., jste vítáni, abyste níže uvedli poznámku! Přihlásit se k mému blogu nebo chytit RSS kanály zůstat aktualizován!

Write a Comment

Vaše e-mailová adresa nebude zveřejněna.