Obsah:

Mikrokontrolér AVR. LED bliká pomocí časovače. Časovače Přerušení. Režim CTC časovače: 6 kroků
Mikrokontrolér AVR. LED bliká pomocí časovače. Časovače Přerušení. Režim CTC časovače: 6 kroků

Video: Mikrokontrolér AVR. LED bliká pomocí časovače. Časovače Přerušení. Režim CTC časovače: 6 kroků

Video: Mikrokontrolér AVR. LED bliká pomocí časovače. Časovače Přerušení. Režim CTC časovače: 6 kroků
Video: Vánoční speciál - trailer AVRConfig 2024, Listopad
Anonim
Image
Image

Ahoj všichni!

Časovače jsou důležitým konceptem v oblasti elektroniky. Každá elektronická součástka pracuje na časové bázi. Tato časová základna pomáhá synchronizovat veškerou práci. Všechny mikrokontroléry pracují na nějaké předdefinované hodinové frekvenci, všechny mají možnost nastavit časovače. AVR se chlubí tím, že má velmi přesný, přesný a spolehlivý časovač. Nabízí spoustu funkcí, což z něj činí rozsáhlé téma. Nejlepší na tom je, že časovač je zcela nezávislý na CPU. Běží tedy paralelně s CPU a nedochází k žádným zásahům CPU, díky čemuž je časovač docela přesný. V této části vysvětlím základní pojmy časovačů AVR. Píši jednoduchý program v kódu C pro ovládání LED blikače pomocí časovačů.

Krok 1: Popis

Prohlášení k problému 1: Začněme blikat první LED diodou (zelená) každých 50 ms
Prohlášení k problému 1: Začněme blikat první LED diodou (zelená) každých 50 ms

V ATMega328 existují tři typy časovačů:

Timer/Counter0 (TC0) - je 8bitový modul časovače/čítače pro všeobecné použití se dvěma nezávislými jednotkami OutputCompare a podporou PWM;

Timer/Counter1 (TC1) - 16bitová jednotka Timer/Counter umožňuje přesné načasování provádění programu (správa událostí), generování vln a měření časování signálu;

Timer/Counter2 (TC2) -je obecný, kanálový, 8bitový modul časovače/čítače s PWM a asynchronním provozem;

Krok 2: Prohlášení o problému 1: Rozsviťme první LED (zelená) každých 50 ms

Prohlášení o problému 1: Rozsvítíme první LEDku (zelená) každých 50 ms
Prohlášení o problému 1: Rozsvítíme první LEDku (zelená) každých 50 ms
Prohlášení o problému 1: Rozsvítíme první LEDku (zelená) každých 50 ms
Prohlášení o problému 1: Rozsvítíme první LEDku (zelená) každých 50 ms

Metodologie:

- použití prescaleru Timer0 ke snížení vysokofrekvenčního elektrického signálu na nižší frekvenci dělením celých čísel;

- použití přerušení pokaždé, když časovač 0 přetéká;

Timer0 (8 bitů) se počítá od 0 do 255, poté přetékají, tato hodnota se mění při každém hodinovém impulsu.

F_CPU = 16MHz: Časová perioda = 1000ms / 16000000Hz = 0,0000625ms

Počet časovačů = (požadované zpoždění / časové období) -1 = (50ms / 0,0000625ms) = 799999

Hodiny již tikaly 799 999krát, aby poskytly zpoždění pouze 50 ms!

Ke snížení počtu časovačů můžeme použít techniku frekvenčního dělení, která se nazývá předkalkulace. AVR nám nabízí následující hodnoty prescaleru: 8, 64, 256 a 1024. V tabulce jsou shrnuty výsledky použití různých prescalerů.

Hodnota čítače by měla být vždy celé číslo. Vyberme předřazovač 256!

Ve většině mikrokontrolérů existuje něco, co se nazývá Přerušení. Toto přerušení lze spustit vždy, když jsou splněny určité podmínky. Nyní, kdykoli je spuštěno přerušení, AVR zastaví a uloží provádění hlavní rutiny, věnuje se volání přerušení (provedením speciální rutiny, nazývané rutina přerušení služby, ISR) a jakmile je s ní provedeno, vrátí se do hlavní rutina a pokračuje v jejím provádění.

Vzhledem k tomu, že požadované zpoždění (50 ms) je větší než maximální možné zpoždění: 4, 096 ms = 1000 ms / 62500 Hz * 256, časovač evidentně přeteče. A kdykoli časovač přetéká, spustí se přerušení.

Kolikrát by mělo být vyhození přerušeno?

50ms / 4,096ms = 3125 /256 = 12,207 Pokud by časovač přeletěl 12krát, uplynulo by 12 * 4,096ms = 49,152ms. Ve 13. iteraci potřebujeme zpoždění 50 ms - 49,152 ms = 0,848 ms.

Při frekvenci 62500 Hz (prescaler = 256) trvá každé zaškrtnutí 0,016 ms. K dosažení zpoždění 0,848 ms by to tedy vyžadovalo 0,848 ms / 0,016 ms = 53 tiků. Ve 13. iteraci tedy povolíme, aby časovač napočítal až 53 a poté jej resetoval.

Inicializujte časovač 0/čítač (viz obrázek):

TCCR0B | = (1 << CS02) // nastavení časovače s předřazením = 256 TCNT0 = 0 // inicializace čítače TIMSK0 | = (1 << TOIE0) // povolení přetečení přerušení sei () // povolení globálních přerušení tot_overflow = 0 // inicializace proměnné čítače přetečení

Krok 3: Prohlášení o problému 2: Pojďme bliknout druhá LED dioda (modrá) každých 1 s

Prohlášení o problému 2: Pojďme bliknout druhá LED dioda (modrá) každé 1 s
Prohlášení o problému 2: Pojďme bliknout druhá LED dioda (modrá) každé 1 s
Prohlášení o problému 2: Pojďme bliknout druhá LED dioda (modrá) každé 1 s
Prohlášení o problému 2: Pojďme bliknout druhá LED dioda (modrá) každé 1 s
Prohlášení o problému 2: Pojďme bliknout druhá LED dioda (modrá) každé 1 s
Prohlášení o problému 2: Pojďme bliknout druhá LED dioda (modrá) každé 1 s

Metodologie:

- použití předzesilovače Timer1 ke snížení vysokofrekvenčního elektrického signálu na nižší frekvenci dělením celých čísel;

- pomocí Vymazat časovač v režimu porovnávání (CTC);

- používání přerušení s režimem CTC;

Timer1 (16 bitů), který se počítá od 0 do 65534, poté přetékají. Tato hodnota se mění při každém hodinovém impulsu.

F_CPU = 16MHz: Časová perioda = 1000ms / 16000000Hz = 0,0000625ms Časovač = (požadované zpoždění / časové období) -1 = (1000ms / 0,0000625ms) = 15999999

Hodiny již tikly 15999999krát, aby došlo ke zpoždění 1 s!

Ke snížení počtu časovačů můžeme použít techniku frekvenčního dělení, která se nazývá předkalkulace. AVR nám nabízí následující hodnoty prescaleru: 8, 64, 256 a 1024. V tabulce jsou shrnuty výsledky použití různých prescalerů. Hodnota čítače by měla být vždy celé číslo. Vyberme předřazovač 256!

V režimu Clear Timer on Compare (CTC) se k manipulaci s rozlišením čítače používá registr OCR1A nebo ICR1. V režimu CTC se počitadlo vynuluje, když hodnota čítače (TCNT1) odpovídá buď OCR1A nebo ICR1. OCR1A nebo ICR1 definují nejvyšší hodnotu pro čítač, tedy také jeho rozlišení. Tento režim umožňuje větší kontrolu výstupní frekvence porovnávání a také zjednodušuje činnost počítání externích událostí. Musíme říci AVR, aby resetoval Timer1/Counter, jakmile jeho hodnota dosáhne hodnoty 62500, aby se dosáhlo zpoždění 1 s.

Inicializujte časovač 1/čítač (viz obrázek):

TCCR1B | = (1 << WGM12) | (1 << CS12) // nastavení časovače s prescalerem = 256 a režimem CTC TCNT1 = 0 // inicializace čítače TIMSK1 | = (1 << OCIE1A) // povolení porovnání přerušení OCR1A = 62500 // inicializace porovnávací hodnoty

Krok 4: Prohlášení o problému 3: Pojďme bliknout Třetí LED (červená) každých 16 ms

Prohlášení o problému 3: Pojďme bliknout Třetí LED (červená) každých 16 ms
Prohlášení o problému 3: Pojďme bliknout Třetí LED (červená) každých 16 ms
Prohlášení o problému 3: Pojďme bliknout Třetí LED (červená) každých 16 ms
Prohlášení o problému 3: Pojďme bliknout Třetí LED (červená) každých 16 ms
Prohlášení o problému 3: Pojďme bliknout Třetí LED (červená) každých 16 ms
Prohlášení o problému 3: Pojďme bliknout Třetí LED (červená) každých 16 ms
Prohlášení o problému 3: Pojďme bliknout Třetí LED (červená) každých 16 ms
Prohlášení o problému 3: Pojďme bliknout Třetí LED (červená) každých 16 ms

Metodologie:

- použití předzesilovače Timer2 ke snížení vysokofrekvenčního elektrického signálu na nižší frekvenci dělením celých čísel;

- pomocí Vymazat časovač v režimu porovnávání (CTC);

- používání hardwarového režimu CTC bez přerušení;

Timer2 (8 bitů), který se počítá od 0 do 255, poté přetékají. Tato hodnota se mění při každém hodinovém impulsu.

F_CPU = 16MHz: Časová perioda = 1000ms / 16000000Hz = 0,0000625ms

Počet časovačů = (požadované zpoždění / časové období) -1 = (16ms / 0,0000625ms) = 255999

Hodiny již tikly 255999krát, aby poskytly zpoždění 16 ms!

V tabulce jsou shrnuty výsledky použití různých předzměnců. Hodnota čítače by měla být vždy celé číslo. Vyberme předřazovač 1024!

V režimu CTC se počitadlo vynuluje, když hodnota čítače (TCNT2) odpovídá buď OCR2A nebo ICR2. Kolík PB3 je také kolíkem porovnávání výstupu TIMER2 - OC2A (viz diagram).

Regulační registr časovače/čítače2 A - TCCR2A Bit 7: 6 - COM2A1: 0 - režim porovnávání výstupu pro porovnávací jednotku A. Protože potřebujeme přepnout LED, zvolíme možnost: Přepnout OC2A na porovnávací shodě Kdykoli dojde ke srovnávací shodě, Pin OC2A se automaticky přepíná. Není třeba kontrolovat žádný příznakový bit, není třeba se starat o žádná přerušení.

Inicializujte Timer2/Counter

TCCR2A | = (1 << COM2A0) | (1 << WGM21) // nastavení časovače OC2A pin v přepínacím režimu a režimu CTC TCCR2B | = (1 << CS22) | (1 << CS21) | (1 << CS20) // nastavení časovače s prescalerem = 1024 TCNT2 = 0 // inicializace čítače OCR2A = 250 // inicializace porovnávací hodnoty

Krok 5: Zápis kódu pro program v C. Odeslání souboru HEX do paměti flash mikrokontroléru

Zápis kódu pro program v C. Odeslání souboru HEX do paměti Flash mikrokontroléru
Zápis kódu pro program v C. Odeslání souboru HEX do paměti Flash mikrokontroléru
Zápis kódu pro program v C. Odeslání souboru HEX do paměti Flash mikrokontroléru
Zápis kódu pro program v C. Odeslání souboru HEX do paměti Flash mikrokontroléru

Psaní a vytváření aplikace mikrokontroléru AVR v kódu C pomocí integrované vývojové platformy - Atmel Studio.

F_CPU definuje taktovací frekvenci v Hertzech a je běžný v programech využívajících knihovnu avr-libc. V tomto případě jej rutiny zpoždění používají k určení způsobu výpočtu časových zpoždění.

#ifndef F_CPU

#define F_CPU 16000000UL // sdělující krystalovou frekvenci ovladače (16 MHz AVR ATMega328P) #endif

#include // header umožňující řízení toku dat přes piny. Definuje piny, porty atd.

První soubor zahrnutí je součástí avr-libc a bude použit téměř ve všech projektech AVR, na kterých pracujete. io.h určí CPU, který používáte (což je důvod, proč určujete část při kompilaci) a následně zahrne příslušné záhlaví definice IO pro čip, který používáme. Jednoduše definuje konstanty pro všechny vaše piny, porty, speciální registry atd.

#include // header povolit přerušení

volatile uint8_t tot_overflow; // globální proměnná pro počítání počtu přetečení

Metodika prohlášení o problému: LED dioda Flash nejprve (zelená) každých 50 ms

- použití prescaleru Timer0 ke snížení vysokofrekvenčního elektrického signálu na nižší frekvenci dělením celých čísel;

- použití přerušení pokaždé, když časovač 0 přetéká;

void timer0_init () // inicializace timer0, přerušení a proměnná

{TCCR0B | = (1 << CS02); // nastavení časovače s prescalerem = 256 TCNT0 = 0; // inicializace čítače TIMSK0 | = (1 << TOIE0); // povolit přetečení nterrupt sei (); // povolit globální přerušení tot_overflow = 0; // inicializace proměnné čítače přetečení}

Metodika prohlášení o problému: Bliká druhá LED dioda (modrá) každé 1 s

- použití předzesilovače Timer1 ke snížení vysokofrekvenčního elektrického signálu na nižší frekvenci dělením celých čísel;

- pomocí Vymazat časovač v režimu porovnávání (CTC);

- používání přerušení s režimem CTC;

void timer1_init () // inicializace timeru1, přerušení a proměnné {TCCR1B | = (1 << WGM12) | (1 << CS12); // nastavení časovače s prescalerem = 256 a režimem CTC TCNT1 = 0; // inicializace čítače OCR1A = 62500; // inicializace porovnat hodnotu TIMSK1 | = (1 << OCIE1A); // povolit porovnání přerušení}

Metodika prohlášení o problému: Třetí LED dioda bliká každých 16 ms

- použití předzesilovače Timer2 ke snížení vysokofrekvenčního elektrického signálu na nižší frekvenci dělením celých čísel;

- pomocí Vymazat časovač v režimu porovnávání (CTC);

- používání hardwarového režimu CTC bez přerušení;

void timer2_init () // inicializace timeru2 {TCCR2A | = (1 << COM2A0) | (1 << WGM21); // nastavení časovače OC2A pin v přepínacím režimu a režimu CTC TCCR2B | = (1 << CS22) | (1 << CS21) | (1 << CS20); // nastavení časovače s prescalerem = 1024 TCNT2 = 0; // inicializace čítače OCR2A = 250; // inicializace porovnávací hodnoty}

Rutina přerušení přetečení TIMER0 volána vždy, když přetéká TCNT0:

ISR (TIMER0_OVF_vect)

{tot_overflow ++; // sledujte počet přetečení}

Tento ISR je spuštěn vždy, když dojde k shodě, proto zde přepněte led:

ISR (TIMER1_COMPA_vect) {PORTC ^= (1 << 1); // toggle led here}

int main (neplatné)

{DDRB | = (1 << 0); // připojení 1 (zelená) vedla na pin PB0 DDRC | = (1 << 1); // připojení 2 (modré) LED na pin PC1 DDRB | = (1 << 3); // připojení 3 (červená) vedla na pin PB3 (OC2A) timer0_init (); // inicializace timeru0 timer1_init (); // inicializace timer1 timer2_init (); // inicializace timer2 while (1) // smyčka navždy {

Pokud by časovač 0 přeletěl 12krát, uplynulo by 12 * 4,096 ms = 49,152 ms. Ve 13. iteraci potřebujeme zpoždění 50 ms - 49,152 ms = 0,848 ms. Ve 13. iteraci tedy povolíme, aby časovač napočítal až 53 a poté jej resetoval.

if (tot_overflow> = 12) // zkontrolujte, zda ne. přetečení = 12 POZNÁMKA: Použije se '> ='

{if (TCNT0> = 53) // zkontrolujte, zda počet časovačů dosáhne 53 {PORTB ^= (1 << 0); // přepíná LED TCNT0 = 0; // reset počítadla tot_overflow = 0; // reset počítadla přetečení}}}}

Odeslání souboru HEX do flash paměti mikrokontroléru:

do okna výzvy systému DOS zadejte příkaz:

avrdude –c [jméno programátora] –p m328p –u –U flash: w: [název vašeho hex souboru] V mém případě je to: avrdude –c ISPProgv1 –p m328p –u –U flash: w: Timers.hex

Tento příkaz zapíše hex soubor do paměti mikrokontroléru. Podívejte se na video s podrobným popisem vypalování flash paměti mikrokontroléru:

Vypalování flash paměti mikrokontroléru…

OK! Mikrokontrolér nyní pracuje v souladu s pokyny našeho programu. Pojďme to zkontrolovat!

Krok 6: Výroba elektrického obvodu

Výroba elektrického obvodu
Výroba elektrického obvodu
Výroba elektrického obvodu
Výroba elektrického obvodu
Výroba elektrického obvodu
Výroba elektrického obvodu

Připojte komponenty podle schématu.

Doporučuje: