WebElektronika

Portkezelés az Atmel AVR mikrovezérlőknél

person access_time 2015.10.27.
Folytatjuk a 8 bites Atmel AVR-ek megismerését, először a portkezelést tekintjük át néhány példa segítségével.


Mint a Microchip által gyártott mikrovezérlőknél, itt is három regiszter felel a porthasználatért.

  • DDRx : ennek a regiszternek a segítségével állítjuk be a port irányát. Bitenként is változtatható az irány. Fontos azonban az, hogy az adott számhoz tartozó irány ellentétes a PIC mikrovezérlőknél. Tehát a 0 a bemenetet, 1 a kimenetet jelenti.
  • PINx : ezzel a regiszterrel tudunk beolvasni az adott portról
  • PORTx : ennek a regiszternek az értéke jelenik meg az adott porton

 

Nézzünk most meg néhány példát a portkezelésre! Használjuk fel az Atmel Atmega8A-t!

Indítsuk el az Atmel Studio-t és hozzunk létre egy projektet, és válasszuk ki az Atmega8A-t (1. ábra).

kep
1. ábra   A projekt létrehozása és a mikrovezérlő típusának kiválasztása
 

 

1. példa

Az első példában a B port összes bitjét kimenetre állítjuk (DDRB = 0xFF;), majd az alsó négy bitre hexa 5-öt írunk, a felső négy bitre pedig logikai nullát teszünk (0x05). A while(1); ciklus miatt a main() függvény nem ér véget.

#include <avr/io.h>

int main(void)
{
    DDRB = 0xFF;    // B port kimenet
    PORTB = 0x05;    // alsó 4 bit : 0 1 0 1
                                     // felső 4 bit log 0-ban
    
    while(1);
}

 

Az alsó két páros B portbiten logikai 1 lesz.

 

2. példa

Ebben a példában szintén kimenet a B port. Most az io.h header file-on kívül szükségünk lesz a delay.h-ra is, mert kb 1 másodperces késleltetésre van szükségünk, ehhez felhasználjuk a _delay_ms()-t is. Fordításkor kapunk egy megjegyzést, hogy nem állítottuk be a működési frekvenciát, de ez a működést nem fogja zavarni.

#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
    DDRB = 0xFF;    // B port kimenet

    while(1)
    {
        PORTB = 0x0A;
        _delay_ms(1000);
        PORTB = 0x05;
        _delay_ms(1000);
    }
}

 

A while(1) végtelen ciklusban negáljuk az alsó négy bit állapotát.

 

3. példa

Most felhasználjuk a D port 2. bitjét is, ezen fogjuk beolvasni a nyomógomb állapotát. Ezért a DDRD regiszter 2. bitjére logikai nullát írunk, a többi bit kimenet lesz (1). 
A while(1) ciklusban állandóan figyeljük a nyomógomb állapotát (PIND 2. bit), amelyet ha nem nyomtuk meg, akkor a B port 0. bitjére logikai 1 kerül, a PB1-re pedig 0. Ha megnyomjuk a nyomógombot, akkor a B port két legalós bitje állapotot vált.

#include <avr/io.h>

int main(void)
{

    DDRB = 0xFF;
    DDRD = 0b11111011;    // D2 bemenet
                                                 // többi D kimenet

    while(1)
    {
        if (PIND & 0x04)
                 PORTB = (1<<PB0) | (0<<PB1);
        else
                 PORTB = (0<<PB0) | (1<<PB1);
    }
}

 

Az if-es szerkezet feltételvizsgálatában a PIND regisztert (ezzel olvasunk be a portról) maszkoljuk a 0x04-gyel, azaz a 2. bit logikai egyben van. Tehát, ha a nyomógombot nem nyomjuk le, akkor feltétel logikai 1-ben van.
 

4. példa

Hasonló ennek a példának a felépítése az előzőéhez, azzal a különbséggel, hogy a nyomógomb lenyomásával (és felengedésével) a PORTB értékét növeljük eggyel, azaz, számoljuk (és megjelenítjük) a PORTB-n a gomblenyomást.

#include <avr/io.h>

int main(void)
{

    DDRB = 0xFF;
    DDRD = 0xFB;    // 1111 1011

    while(1)
    {
        while((PIND & 0x04));
        while(!(PIND & 0x04));
        PORTB++;
    }
}

 

5. példa

Az utolsó példánkban készítettünk egy sajátfüggvényt (VillogBPort()), amelynek segítségével be tudjuk állítani a B port adott bitjének (hely) az értékét.

#include <avr/io.h>
#include <util/delay.h>

void VillogBPortBit(int hely, int ertek);

int main(void)
{
    DDRB = 0xFF;

    while(1)
    {
        VillogBPortBit(3,1);
        _delay_ms(1000);
        VillogBPortBit(3,0);
        _delay_ms(1000);
    }
}

void VillogBPortBit(int hely, int ertek)
{
    if (ertek == 0)
        PORTB &= ~(1 << hely);
    else
        PORTB |= (1 << hely);
}

 

Hasonló a while(1) ciklus felépítése a második példáéhoz, de itt az állapotváltásért ez a sajátfüggvény felel.