- Prečo časovač, keď máme oneskorenie ()?
- Časovače mikrokontroléra PIC:
- Vysvetlenie programovania a práce:
- Schéma zapojenia a simulácia proteínu:
Toto bude piaty tutoriál v našej sérii tutoriálov PIC, ktorý vám pomôže naučiť sa a používať časovače v PIC16F877A. V našich predchádzajúcich tutoriáloch sme začali s Úvodom do PIC a MPLABX IDE, potom sme napísali náš prvý program PIC na blikanie LED pomocou PIC a potom sme vytvorili sekvenciu blikania LED pomocou funkcie delay v mikrokontroléri PIC. Teraz použijeme rovnakú sekvenciu blikania LED, ktorú sme použili v predchádzajúcom hardvéri tutoriálu, a pomocou toho sa naučíme, ako používať časovače v našom PIC MCU. Pre tento výukový program sme práve pridali jedno ďalšie tlačidlo na doske LED. Prejdite si tutoriál a dozviete sa viac.
Časovače sú jedným z dôležitých pracovných koní pre zabudovaného programátora. Každá aplikácia, ktorú navrhneme, bude nejako zahŕňať aplikáciu načasovania, napríklad zapnutie alebo vypnutie niečoho po stanovenom časovom intervale. Dobre, ale prečo potrebujeme časovače, keď už máme oneskorené makrá (__delay_ms ()), ktoré robia to isté !!
Prečo časovač, keď máme oneskorenie ()?
Makro oneskorenia sa nazýva oneskorenie „výpisu“. Pretože počas vykonávania funkcie oneskorenia sedí MCU výpis iba vytvorením oneskorenia. Počas tohto procesu nemôže MCU počúvať svoje hodnoty ADC ani nič čítať zo svojich registrov. Preto sa neodporúča používať funkcie oneskorenia, s výnimkou aplikácií ako blikanie LED, kde nemusí byť časové oneskorenie presné alebo dlhé.
Makra oneskorenia majú aj nasledujúce nedostatky,
- Hodnota oneskorenia musí byť pre makrá oneskorenia konštantná; počas vykonávania programu sa to nedá zmeniť. Preto zostáva definovaný programátorom.
- Oneskorenie nebude presné v porovnaní s použitím časovačov.
- Väčšie hodnoty oneskorení nie je možné vytvoriť pomocou makier, napríklad oneskorenie pol hodiny nie je možné vytvoriť pomocou makier oneskorenia. Maximálne možné oneskorenie je založené na použitom oscilátore Crystal.
Časovače mikrokontroléra PIC:
Fyzicky je časovač register, ktorého hodnota sa neustále zvyšuje na 255, a potom sa začína odznova: 0, 1, 2, 3, 4… 255…. 0, 1, 2, 3……atď.
PIC16F877A PIC MCU má tri časovača moduly. Sú to názvy ako Timer0, Timer1 a Timer2. Časovač 0 a časovač 2 sú 8-bitové časovače a časovač 1 je 16-bitový časovač. V tomto tutoriále budeme používať Timer 0 pre našu aplikáciu. Keď pochopíme časovač 0, bude ľahké pracovať aj na časovači 1 a časovači 2.
Časovač / počítadlo modulu Timer0 má nasledujúce vlastnosti:
- 8-bitový časovač / počítadlo
- Čitateľné a zapisovateľné
- 8-bitový softvérovo programovateľný prednastavovač
- Vyberte si interné alebo externé hodiny
- Prerušiť pri pretečení z FFh na 00h
- Hrana pre externé hodiny
Ak chcete začať používať časovač, mali by sme pochopiť niektoré z fantazijných výrazov, ako sú 8-bitový / 16-bitový časovač, Prescaler, prerušenia časovača a Focs. Pozrime sa teraz, čo každý z nich znamená. Ako už bolo povedané, v našom PIC MCU sú 8-bitové aj 16-bitové časovače, hlavný rozdiel medzi nimi je v tom, že 16-bitový časovač má oveľa lepšie rozlíšenie ako 8-bitový časovač.
Prescaler je názov pre časť mikrokontroléra, ktorá rozdeľuje hodiny oscilátora skôr, ako dosiahne logiku, ktorá zvyšuje stav časovača. Rozsah ID preskalera je od 1 do 256 a hodnotu Prescalera je možné nastaviť pomocou registra OPTION (ten istý, ktorý sme použili pre pull up rezistory). Napríklad v prípade, že hodnota Prescaler je 64, potom pre každý 64 tý pulz Časovač bude zvýšený o 1.
Keď sa časovač zvýši a keď dosiahne maximálnu hodnotu 255, spustí prerušenie a znova sa inicializuje na 0. Toto prerušenie sa nazýva prerušenie časovača. Toto prerušenie informuje MCU, že tento konkrétny čas uplynul.
FOSC znamená frekvenciu oscilátora, to je frekvencia Crystal používa. Čas potrebný na registráciu časovača závisí od hodnoty Prescalera a hodnoty Fosc.
Vysvetlenie programovania a práce:
V tomto návode nastavíme dve tlačidlá ako dva vstupy a 8 LED ako 8 výstupov. Prvé tlačidlo sa použije na nastavenie časového oneskorenia (500 ms na každé stlačenie) a druhé tlačidlo sa použije na spustenie blikania sekvencie časovača. Napríklad, ak je prvé tlačidlo stlačené trikrát (500 * 3 = 1500ms), oneskorenie sa nastaví na 1,5 sekundy a po stlačení tlačidla dve sa každá LED rozsvieti a zhasne s preddefinovaným časovým oneskorením. Skontrolujte demonštračné video na konci tohto tutoriálu.
Teraz, s ohľadom na tieto základné informácie, pozrime sa na náš program uvedený na konci v časti Kód.
Je v poriadku, ak ste program nezískali, ale ak áno !! Dajte si cookie a odložte program, aby ste si mohli vychutnať svoj výstup. Pre ostatných rozdelím program na zmysluplné časti a vysvetlím vám, čo sa deje v jednotlivých blokoch.
Ako vždy prvých pár riadkov kódu sú Konfiguračné nastavenia a hlavičkové súbory, nebudem to vysvetľovať, pretože som to už urobil v mojich predchádzajúcich tutoriáloch.
Ďalej preskočme všetky riadky a skočme priamo do hlavnej funkcie prázdnoty, vnútri ktorej máme konfiguráciu PORT pre Timer0.
void main () {/ ***** Konfigurácia portu pre časovač ****** / OPTION_REG = 0b00000101; // Timer0 s externými frekvenciami a 64 ako predkallar // Tiež umožňuje PULL UPs TMR0 = 100; // Načítanie časovej hodnoty za 0,0019968s; delayValue môže byť medzi 0-256 iba TMR0IE = 1; // Povoliť bit prerušenia časovača v registri PIE1 GIE = 1; // Povoliť globálne prerušenie PEIE = 1; // Povoliť prerušenie periférie / *********** ______ *********** /
Aby sme tomu porozumeli, musíme sa pozrieť na OPTION Register v našom technickom liste PIC.
Ako bolo uvedené v predchádzajúcom tutoriáli, bit 7 sa používa na povolenie slabého vytiahnutia rezistora pre PORTB. Pozrime sa na vyššie uvedený obrázok, bit 3 je nastavený na 0, aby dal pokyn MCU, že nasledujúci nastavený predvoľbový merač by sa mal používať pre časovač a nie pre WatchDogTimer (WDT). Režim časovača sa vyberie vymazaním bitu 5 T0CS
(OPTION_REG <5>)
Teraz sa pomocou bits2-0 nastaví hodnota predvoľby časovača. Ako je uvedené v tabuľke vyššie, ak chcete nastaviť hodnotu predsklerátora na 64, bity musia byť nastavené ako 101.
Ďalej sa pozrime na registre spojené s Timer0
Časovač sa začne zvyšovať po nastavení a pretečie po dosiahnutí hodnoty 256, aby sa počas tohto bodu umožnilo prerušenie časovača, musí byť register TMR0IE nastavený vysoko. Pretože je časovač 0 sám o sebe periférny, musíme povoliť prerušenie periférie nastavením PEIE = 1. Nakoniec musíme povoliť globálne prerušenie, aby bolo MCU informované o prerušení počas akejkoľvek operácie, čo sa robí nastavením GIE = 1.
Oneskorenie = ((256-REG_val) * (Prescal * 4)) / Fosc
Vyššie uvedený vzorec sa používa na výpočet hodnoty oneskorenia.
Kde
REG_val = 100;
Prescal = 64
Fosc = 20000000
Toto pri výpočte dáva, Oneskorenie = 0,0019968s
Ďalšou sadou riadkov je nastavenie I / O portov.
/ ***** Konfigurácia portu pre I / O ****** / TRISB0 = 1; // Dajte MCU pokyn, aby sa pin PORTB 0 použil ako vstup pre tlačidlo 1. TRISB1 = 1; // Inštruujte MCU, aby sa pin 1 PORTB použil ako vstup pre tlačidlo 1. TRISD = 0x00; // Dajte MCU pokyn, aby všetky piny na PORT D boli výstupom PORTD = 0x00; // Inicializujte všetky piny na 0 / *********** ______ *********** /
Je to rovnaké ako v predchádzajúcom tutoriáli, pretože používame rovnaký hardvér. Ibaže sme ako vstup pridali ďalšie tlačidlo. To sa deje pomocou riadku TRISB1 = 1.
Ďalej máme nekonečne dlhú slučku naruby dva bloky kódu. Jeden sa používa na získanie vstupu časovača od používateľa a druhý na vykonanie sekvencie oneskorenia cez LED diódy. Vysvetlil som ich použitím komentárov ku každému riadku.
while (1) {count = 0; // Nespúšťajte časovač, kým ste v hlavnej slučke // ******* Získajte oneskorenie čísla od používateľa **** // //// if (RB0 == 0 && flag == 0) // Kedy zadaný vstup {get_scnds + = 1; // get_scnds = get_scnds + http: // Prírastok premennej flag = 1; } if (RB0 == 1) // Aby sa zabránilo nepretržitému zvyšovaniu príznak = 0; / *********** ______ *********** /
Premenná s názvom get_scnds sa zvyšuje vždy, keď používateľ stlačí tlačidlo 1. Na udržanie procesu zvyšovania sa používa príznaková (softvérovo definovaná) premenná, kým používateľ neodstráni prst z tlačidla.
// ******* Vykonajte sekvenciu so oneskorením **** ////// while (RB1 == 0) {PORTD = 0b00000001 <
Ďalším blokom sa aktivuje stlačenie tlačidla dva. Pretože užívateľ má už definované požadované časové oneskorenie pomocou tlačidla jedna a bolo uložené v premennej get_scnds. Používame premennú nazvanú hscnd, táto premenná je riadená ISR (rutina prerušenia služby).
Prerušenie služby rutina je Interrupt, ktorá sa bude nazývať zakaždým, keď Timer0 je preteká. Pozrime sa, ako je to riadené ISR v nasledujúcom bloku, ako by sme chceli zvýšiť časové oneskorenie o pol sekundy (0,5 s) pri každom stlačení tlačidla, potom musíme zvyšovať premennú hscnd na každú pol sekundu. Pretože sme naprogramovali náš časovač na pretečenie každých 0,0019968 s (~ 2ms), tak počítanie polsekundovej premennej počítania by malo byť 250, pretože 250 * 2ms = 0,5 sekundy. Takže keď počet dostane 250 (250 * 2ms = 0,5 sekundy), znamená to, že to bolo už pol sekundy, takže zvýšime hscnd o 1 a inicializujeme count na nulu.
void interrupt timer_isr () {if (TMR0IF == 1) // Bol spustený príznak časovača kvôli pretečeniu časovača {TMR0 = 100; // Načítanie časovača Hodnota TMR0IF = 0; // Vymazať počet príznakov prerušenia časovača ++; } if (počet == 250) {hscnd + = 1; // hscnd sa zvýši o každú polsekundu count = 0; }}
Takže použijeme túto hodnotu a porovnáme ju s našou hscnd a posunieme našu LED na základe času definovaného používateľom. Je tiež veľmi podobný minulému tutoriálu.
To je to, že máme náš program pochopený a funkčný.
Schéma zapojenia a simulácia proteínu:
Ako obvykle si najskôr overíme výstup pomocou aplikácie Proteus, pripojil som sem schematické súbory aplikácie Proteus.
Pridajte tlačidlo na našu predchádzajúcu LED dosku a náš hardvér je pripravený na použitie. Malo by to vyzerať asi takto:
Po dokončení pripojenia nahrajte kód a overte výstup. Ak máte akýkoľvek problém, použite sekciu komentárov. Celý proces si pozrite aj na videu nižšie.