Skip to content

Začiatky s ATmega8, tlačidlo a LED

napísal Lukáš, dňa: Máj 1st, 2010

LED dióda, ktorá svieti podľa tlačidla

Cieľom je napísať program pre mikroprocesor, ktorý ak je zopnuté tlačidlo, rozsvieti LED diódu. Informácie k registrom a nastaveniam portov boli čerpané najmä z datasheetu k mikroprocesoru ATmega8.

Pravidelná kontrola tlačidla

Riešenie spočíva v tom, že mikroprocesor niekoľko krát za sekundu kontroluje, či je tlačidlo zopnuté. Ak áno, rozsvieti LED diódu.

Schéma zapojenia k príkladu. Pin č. 23 (vstupný) je pre tlačidlo a pin č. 24 (výstupný) pre LED diódu. Kliknite na obrázok, zobrazí sa v novom okne a vo väčšom rozlíšení.

Schema_mikroprocesor_LED_tlacidlo

Zapojením súčiastok a mikroprocesora som dosiahol, že pokiaľ nestlačím tlačidlo, je na pine č. 23 napätie 0V, zodpovedajúce úrovni logickej 0. Po jeho zopnutí sa na pine č. 23. objaví 5V, úroveň logickej 1 (vtedy musí zareagovať aj mikroprocesor, ktorý rozsvieti LED diódu).

Riešenie prvej metódy – pravidelná kontrola

Najprv v programe zadefinujem základné knižnice.  Po nich ide hlavná časť programu. Ako prvé sa popíšu potrebné piny a určí sa, či budú slúžiť ako vstupné alebo výstupné. Nasleduje cyklus while(1), ktorý donekonečna kontroluje tlačidlo – čiže logickú úroveň na pine č. 23. a podľa neho určuje logickú hodnotu na pine č. 24., ktorý rozsvecuje LED diódu. Hotový program aj s poznámkami:

#include <avr/io.h>
#include <avr/iom8.h>

int main(void) /* Hlavná funkcia */
{
 DDRC &= ~0x01; // C0 ako vstupny
 DDRC |= 0x02; // C1 ako vystupny
 PORTC &= ~0x01; // vypnut pull-up na C0
 PORTC &= ~0x02; // C1 na nulu

while(1) /* Nekonečný cyklus */
 {
  /* Rozhodovanie */
  if(PINC & 0x01) PORTC |= 0x02;
  else PORTC = PORTC &= ~0x02;
 }
}

Ak niektorý pin mikroprocesora nastavím ako vstupný, môžem na ňom zapnúť pull-up rezistor a tým na tam nastaviť trvale úroveň logickej 1. Tlačidlo teraz zapojím voči zemi a preto nepotrebujem rezistor R3. Netreba zabudnúť, že spínanie bude opačné, úroveň logickej 0 na vstupe rozsvecuje LED diódu. Kliknite na obrázok, zobrazí sa vo väčšom.

(Obr. č. 3.) Schéma mikroprocesora pri aktivovaní pull-up rezistora

V programe nastanú len dve zmeny. Aktivujem pull-up rezistor a na pin C1 budem posielať negovanú hodnotu pinu C0.

#include <avr/io.h>
#include <avr/iom8.h>

int main(void) /* Hlavná funkcia */
{
 DDRC &= ~0x01; // C0 ako vstupny
 DDRC |= 0x02; // C1 ako vystupny
 PORTC |= 0x01; // pull-up na C0
 PORTC &= ~0x02; // C1 na nulu

while(1) /* Nekonečný cyklus */
 {
  /* rozhodovanie */
  if(PINC & 0x01) PORTC &= ~0x02;
  else PORTC = PORTC |= 0x02;
 }
}

Rozsvecovanie cez prerušenie od INT0

Doteraz to fungovalo tak, že mikroprocesor pravidelne kontroloval tlačidlo. Pomocou prerušení bude program odlišný. Keď zatlačím tlačidlo, nastane v mikroprocesore prerušenie. Ten okamžite prestane robiť aktuálnu činnosť a začne sa venovať obsluhe tohoto prerušenia. Skontroluje si, či je tlačidlo stále zopnuté a rozsvieti LED diódu. Toto rozsvecovanie robí dovtedy, pokiaľ je stlačené tlačidlo. Keď tlačidlo pustím, skončí pre neho program prerušenia. Okamžite sa vracia k pôvodnému programu a zhasína LED diódu.

Podľa môjho nastavenia registrov je prerušenie vyvolané vtedy, keď sa na pine č. 4. (PD2, označený ako INT0) zmení úroveň z logickej 0 na logickú 1. Preto je tlačidlo tentoraz pripojené na +5V a pin č. 4. cez 10kOhm rezistor na zem. Kliknite na obrázok, aby sa zväčšil.

Nasleduje samotný program. Ku knižniciam pribudla ešte jedna, ktorá popisuje prerušenia. Všimnite si najmä funkciu ISR(INT0_vect) {}, tá je volaná pri vzniku prerušenia. Oproti vývojovému diagramu som spravil zmenu. V ňom je naznačené, že pokiaľ nastane prerušenie, mikroprocesor neustále rozsvecuje diódu. V programe ale diódu rozsvieti len raz, potom už len kontroluje tlačidlo.

#include <avr/io.h>
#include <avr/iom8.h>
#include <avr/interrupt.h>

ISR(INT0_vect) /* Funkcia volana pri preruseni */
    {
     /* Rozsvieti LED diodu */
     PORTC |= 0x02;
     /* Caka, pokial je stlacene tlacidlo */
     while(PIND & 0x04) { }
    }

int main(void) /* Hlavná funkcia */
{
 DDRD &= ~0x04; /* Nastavi pin D2 ako vstupny */
 PORTD &= ~0x04; /* Vypne pull-up rezistory na pine D2 */
 DDRC |= 0x02; /* Nastavi pin C1 ako vystupny */
 PORTC &= ~0x02; /* Vynuluje pin C1 */
 GICR |= 0x40; /* Povoluje prerusenia od INT0  */
 MCUCR |= 0x01; /* INT0 reaguje na hranu */
 MCUCR |= 0x02;  /* INT0 reaguje na hranu */
 sei(); /* Globalne povolenie preruseni */

while(1) /* Nekonečný cyklus */
 {
  PORTC &= ~0x02; /* Zhasina diodu */
 }
}

Možno program vyzerá zložitejšie, ale v skutočnosti nie je. Pribudlo tam len viac nastavení kvôli prerušeniam. Ale za to som získal to, že mikroprocesor reaguje okamžite na tlačidlo a nie je mimo toho zahltený programom.

Záverom…

Tento seriál predstavuje moje poznámky, skúsenosti a ťažké začiatky s mikroprocesorom ATmega8. Ak viete ako niečo spraviť lepšie, jednoduchšie, ozvite sa, veľmi rád to zapracujem do článku. Ďalšia časť seriálu bude venovaná znova tlačidlu, tentokrát ale  stlačením tlačidla rozsvietim LED diódu a zhasnem ju až ďalším zatlačením.

Kategória → Elektronika

No comments yet

Leave a Reply

You must be logged in to post a comment.