- Proč časovač, když máme Delay ()?
- Časovače mikrokontroléru PIC:
- Vysvětlení programování a práce:
- Schéma zapojení a simulace Proteus:
Toto bude pátý kurz v naší sérii výukových programů PIC, který vám pomůže naučit se a používat časovače v PIC16F877A. V našich předchozích cvičeních jsme začali s Úvodem do PIC a MPLABX IDE, pak jsme napsali náš první program PIC pro blikání LED pomocí PIC a poté jsme vytvořili LED blikající sekvenci pomocí funkce delay v PIC Microcontroller. Nyní použijeme stejnou sekvenci blikání LED, kterou jsme použili v předchozím výukovém hardwaru, a pomocí toho se naučíme, jak používat časovače v našem PIC MCU. Právě jsme pro tento výukový program přidali jedno další tlačítko na LED desce. Projděte si výukový program a dozvíte se více.
Časovače jsou jedním z důležitých pracovních koní pro vloženého programátora. Každá aplikace, kterou navrhneme, bude nějak zahrnovat aplikaci načasování, jako je zapnutí nebo vypnutí něčeho po stanoveném časovém intervalu. Dobře, ale proč potřebujeme časovače, když už máme makra zpoždění (__delay_ms ()), která dělají totéž !!
Proč časovač, když máme Delay ()?
Makro zpoždění se nazývá zpoždění „výpisu“. Protože během provádění funkce Zpoždění sedí MCU výpis pouze vytvořením zpoždění. Během tohoto procesu nemůže MCU poslouchat své hodnoty ADC ani číst nic ze svých registrů. Z tohoto důvodu se nedoporučuje používat funkce zpoždění, s výjimkou aplikací, jako je blikání LED, kde časové zpoždění nemusí být přesné ani dlouhé.
Makra zpoždění mají také následující nedostatky,
- Hodnota zpoždění musí být pro makra zpoždění konstantní; během provádění programu jej nelze změnit. Proto zůstává definován programátorem.
- Zpoždění nebude ve srovnání s použitím časovačů přesné.
- Větší hodnoty zpoždění nelze vytvořit pomocí maker, například zpoždění půl hodiny nelze vytvořit pomocí maker zpoždění. Maximální zpoždění, které lze použít, je založeno na použitém oscilátoru Crystal.
Časovače mikrokontroléru PIC:
Fyzicky je časovač registr, jehož hodnota se neustále zvyšuje na 255, a poté začíná znovu: 0, 1, 2, 3, 4… 255…. 0, 1, 2, 3……atd.
PIC16F877A PIC MCU má tři časovače moduly. Jsou to jména jako Timer0, Timer1 a Timer2. Časovač 0 a časovač 2 jsou 8bitové časovače a časovač 1 je 16bitový časovač. V tomto tutoriálu budeme pro naši aplikaci používat časovač 0. Jakmile pochopíme časovač 0, bude snadné pracovat také na časovači 1 a časovači 2.
Časovač / čítač modulu Timer0 má následující funkce:
- 8bitový časovač / čítač
- Čitelné a zapisovatelné
- 8bitový softwarově programovatelný přednastavovač
- Vyberte interní nebo externí hodiny
- Přerušení při přetečení z FFh na 00h
- Výběr hran pro externí hodiny
Chcete-li začít používat časovač, měli bychom rozumět některým fantazijním pojmům, jako je 8bitový / 16bitový časovač, Prescaler, přerušení časovače a Focs. Nyní se podívejme, co každý z nich ve skutečnosti znamená. Jak již bylo řečeno, v našem PIC MCU jsou 8bitové i 16bitové časovače, hlavní rozdíl mezi nimi je v tom, že 16bitový časovač má mnohem lepší rozlišení než 8bitový časovač.
Prescaler je název pro část mikrokontroléru, která rozděluje hodiny oscilátoru dříve, než dosáhne logiky, která zvyšuje stav časovače. Rozsah ID prescaleru je od 1 do 256 a hodnota Prescaleru může být nastavena pomocí OPTION Register (stejného, který jsme použili pro pull up rezistory). Například v případě, že hodnota Prescaler je 64, pak pro každý 64 tý puls Časovač bude zvýšen o 1.
Jak se časovač zvyšuje, a když dosáhne maximální hodnoty 255, spustí přerušení a znovu se inicializuje na 0. Toto přerušení se nazývá přerušení časovače. Toto přerušení informuje MCU, že tento konkrétní čas uplynul.
Fosc znamená frekvenci oscilátoru, to je frekvence Crystal používá. Čas potřebný pro registraci časovače závisí na hodnotě Prescaler a hodnotě Fosc.
Vysvětlení programování a práce:
V tomto tutoriálu nastavíme dvě tlačítka jako dva vstupy a 8 LED jako 8 výstupů. První tlačítko se použije k nastavení časového zpoždění (500 ms na každé stisknutí) a druhé tlačítko se použije k zahájení blikání sekvence časovače. Například pokud je první tlačítko stisknuto třikrát (500 * 3 = 1 500 ms), bude zpoždění nastaveno na 1,5 s a po stisknutí tlačítka dvě se každá LED rozsvítí a zhasne s předdefinovaným časovým zpožděním. Podívejte se na ukázkové video na konci tohoto tutoriálu.
Nyní, když vezmeme v úvahu tyto základní informace, podívejme se na náš program uvedený na konci v části Kód.
Je v pořádku, pokud jste program nezískali, ale pokud ano !! Dejte si cookie a vypusťte program, abyste si mohli užít svůj výstup. Pro ostatní rozdělím program na smysluplné části a vysvětlím vám, co se děje v každém bloku.
Jako vždy prvních několik řádků kódu jsou nastavení konfigurace a soubory záhlaví, nebudu to vysvětlovat, protože jsem to již udělal ve svých předchozích cvičeních.
Dále přeskočme všechny řádky a skočme přímo do hlavní funkce prázdnoty, uvnitř které máme konfiguraci PORT pro Timer0.
void main () {/ ***** Konfigurace portu pro časovač ****** / OPTION_REG = 0b00000101; // Timer0 s externím kmitočtem a 64 jako prescalar // Také umožňuje PULL UPs TMR0 = 100; // Načte časovou hodnotu pro 0,0019968s; delayValue může být mezi 0-256 pouze TMR0IE = 1; // Povolit bit přerušení časovače v registru PIE1 GIE = 1; // Povolit globální přerušení PEIE = 1; // Povolit přerušení periferie / *********** ______ *********** /
Abychom tomu porozuměli, musíme se podívat na OPTION Register v našem datovém listu PIC.
Jak je popsáno v předchozím tutoriálu, bit 7 se používá k povolení slabého pull up rezistoru pro PORTB. Podívejte se na výše uvedený obrázek, bit 3 je nastaven na 0, aby instruoval MCU, že následující předvolba, která je nastavena, by měla být použita pro časovač a ne pro WatchDogTimer (WDT). Režim časovače se volí vymazáním bitu 5 T0CS
(OPTION_REG <5>)
Nyní se bits2-0 používá k nastavení hodnoty předvolby časovače. Jak je uvedeno v tabulce výše, aby bylo možné nastavit přednastavovací hodnotu 64, bity musí být nastaveny jako 101.
Dále se podívejme na registry spojené s Timer0
Časovač se začne zvyšovat, jakmile je nastaven, a přetéká po dosažení hodnoty 256, aby bylo možné v tomto bodě povolit přerušení časovače, musí být registr TMR0IE nastaven vysoko. Protože je časovač 0 sám o sobě periferní, musíme povolit periferní přerušení tak, že nastavíme PEIE = 1. Nakonec musíme povolit Globální přerušení, aby bylo MCU upozorněno na Přerušení během jakékoli operace, to se provádí tak, že GIE = 1.
Zpoždění = ((256-REG_val) * (Prescal * 4)) / Fosc
Výše uvedený vzorec se používá k výpočtu hodnoty zpoždění.
Kde
REG_val = 100;
Prescal = 64
Fosc = 20000000
To při výpočtu dává, Zpoždění = 0,0019968 s
Další sada řádků je nastavení I / O portů.
/ ***** Konfigurace portu pro I / O ****** / TRISB0 = 1; // Poučte MCU, aby se pin PORTB 0 použil jako vstup pro tlačítko 1. TRISB1 = 1; // Poučte MCU, že PORTB pin 1 se používá jako vstup pro tlačítko 1. TRISD = 0x00; // Instruujte MCU, aby všechny piny na PORT D byly na výstupu PORTD = 0x00; // Inicializujte všechny piny na 0 / *********** ______ *********** /
To je stejné jako v našem předchozím tutoriálu, protože používáme stejný hardware. Kromě toho, že jsme přidali další tlačítko jako vstup. To se provádí pomocí řádku TRISB1 = 1.
Dále máme naruby nekonečnou smyčku while, máme dva bloky kódu. Jeden se používá k získání vstupu časovače od uživatele a druhý k provedení sekvence zpoždění přes LED. Vysvětlil jsem je pomocí komentářů u každého řádku.
while (1) {count = 0; // Nespouštějte časovač, když jste v hlavní smyčce // ******* Získejte zpoždění čísla od uživatele **** ////// if (RB0 == 0 && flag == 0) // Kdy zadaný vstup {get_scnds + = 1; // get_scnds = get_scnds + http: // Přírůstek proměnné flag = 1; } if (RB0 == 1) // Chcete-li zabránit nepřetržitému zvyšování příznak = 0; / *********** ______ *********** /
Proměnná zvaná get_scnds se zvýší pokaždé, když uživatel stiskne tlačítko 1. Proměnná příznaku (definovaná softwarem) se používá k zadržení procesu zvyšování, dokud uživatel neodstraní prst z tlačítka.
// ******* Proveďte sekvenci se zpožděním **** ////// while (RB1 == 0) {PORTD = 0b00000001 <
Další blok se aktivuje, pokud je stisknuto tlačítko dva. Protože uživatel již definoval požadované časové zpoždění pomocí tlačítka jedna a bylo uloženo do proměnné get_scnds. Používáme proměnnou nazvanou hscnd, tato proměnná je řízena ISR (rutina služby přerušení).
Přerušení služby rutina je Interrupt, která se bude nazývat pokaždé, když Timer0 je přetéká. Podívejme se, jak je řízeno ISR v dalším bloku, jako bychom chtěli zvýšit časové zpoždění o půl sekundy (0,5 s) na každém stisknutí tlačítka, pak musíme každou půl sekundu zvyšovat proměnnou hscnd . Protože jsme naprogramovali náš časovač tak, aby přetékal každých 0,0019968 s (~ 2ms), měl by být počet proměnných pro počítání půl sekundy 250, protože 250 * 2ms = 0,5 sekundy. Takže když počet dostane 250 (250 * 2ms = 0,5 sekundy), znamená to, že to bylo půl sekundy, takže zvýšíme hscnd o 1 a inicializujeme počet na nulu.
void interrupt timer_isr () {if (TMR0IF == 1) // Byl spuštěn příznak časovače kvůli přetečení časovače {TMR0 = 100; // Načtení časovače Hodnota TMR0IF = 0; // Vymazat počet příznaků přerušení časovače ++; } if (count == 250) {hscnd + = 1; // hscnd se zvýší o každou půlsekundu count = 0; }}
Takže použijeme tuto hodnotu a porovnáme ji s naším hscnd a posuneme naši LED na základě uživatelem definovaného času. Je také velmi podobný poslednímu tutoriálu.
To je to, že máme náš program pochopený a fungující.
Schéma zapojení a simulace Proteus:
Jako obvykle umožňuje nejprve ověřit výstup pomocí Proteus, připojil jsem sem schematické soubory Proteus.
Přidejte tlačítko na naši předchozí LED desku a náš hardware je připraven k použití. Mělo by to vypadat asi takto:
Po dokončení připojení nahrajte kód a ověřte výstup. Pokud máte nějaký problém, použijte sekci komentáře. Zkontrolujte také video níže, abyste pochopili celý proces.