WebElektronika

UART megvalósítása az ATmega8-as mikrovezérlőnél

person access_time 2016.06.23.
Láthattuk korábban, hogy az AT parancsok használata során az UART alkalmazása szinte elengedhetetlen. Ezért korábban megnéztük, hogyan lehet ezt a protokollt alkalmazni egy 8 bites mikrovezérlőnél. Akkor a PIC18F mikrovezérlőt használtuk, de most a méltán népszerű ATmega8 mikrokontrollerben található UART-ot fogjuk programozni.


Az Atmel AVR8-as mikrovezérlőjét, az ATmega8-as mikrokontrollert alkalmazzuk az aszinkron kommunikáció megvalósítása során. Az UART alkalmazása azért fontos, mert ennek segítségvel tudunk AT parancsokat kiküldeni akár a Quectel M66-os moduljára.  A PD.0 és a PD.1 portbitek használhatók fel az adatok küldésére és fogadására (1. ábra).

lábkiosztás
1. ábra   A felhasznált ATmega8 lábkiosztása
 

A BaudRate beállításához szügségünk van az UBRRH és az UBRRL regiszterekre, ahol ez az érték tárolható (2. ábra).

regiszterek
2. ábra   UBRRL és az UBRRH regiszterek
 

Az UDR regiszterben kerül eltárolásra a soros porton érkező 8 bites adat, illetve ide töltjük azt a 8 bites értéket is, amelyet szeretnénk kiküldeni a mikrokontrollerből.

UDR regiszter

3. ábra   UDR regiszter
 

Az UCSRC regiszterben tudjuk beállítani az adatbitek számát (UCSZ0, UCSZ1, UCSZ2), illetve paritásmódot (UPM0, UPM1) is (4. ábra).

UCSRC regiszter
4. ábra   UCSRC regiszter felépítése
 

A programunk elején feltételes fordítást alkalmazunk, beállítjuk a kontroller működési frekvenciáját 12 MHz-re. Ezután a definiáljuk a "BAUD" "változót" 9600-as értékkel, majd meghatározzuk a Baud Rate értékét.

Az uartInit() függvénnyel inicializáljuk az ATmega8 mikrovezérlőben található UART modult, beállítjuk azt, hogy nem használunk interruptot, stb.

Az UCSRC regiszterben található UCSZ0 és az UCSZ1 bitek logikai 1-be kerülnek az uartInit() függvényben, ezért a kommunikáció 8 bites lesz (5. ábra)

adatbitek száma
5. ábra   Adatbitek számának beállítása
 

Az UPM0 és az UPM1 bitek logikai 1-be történő állítása nem történik meg, ezért default értékben maradnak (logikai 0), tehát a paritás tiltott.

Az uartTransmit() és az uartReceive() függvényekkel kényelmesebbé tesszük az UART kommunikációt.

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

#ifndef F_CPU
#define F_CPU 12000000UL
#endif

#define BAUD 9600
#define BAUDRATE ((F_CPU)/(BAUD*16UL)-1)

void uartInit()
{
    UBRRH = (BAUDRATE>>8);
    UBRRL = BAUDRATE;
    UCSRB |= (1 << TXEN) | (1 << RXEN);
    UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1);
}

void uartTransmit (unsigned char data)
{
    while (!( UCSRA & (1 << UDRE)));
    UDR = data;
}

unsigned char uartReceive (void)
{
    while(!(UCSRA) & (1 << RXC));
    return UDR;
}

int main(void)
{
    unsigned char a;
    
    DDRD = 0B11111110;
    DDRC = 0xFF;
    
    uartInit();
    while(1)
    {
        a = uartReceive();
        PORTC = a;
    }
}

 

A main() függvényben először beállítjuk a "D" port 0. bitjét bemenetre, a többi kimenet lesz. A "C" port minden bitje kimenet lesz (DDRC = 0xFF).
A portok beállítása után inicializáljuk az UART modult (meghívjuk az uartInit() függvényt), majd a while(1) végtelen ciklusban állandóan figyeljuk az UART-on érkező adatokat, amelyeket megjelenítünk a "C" porton.
Természetesen a byte típusú "a" változó elhagyható, és a PORTC = uartReceive(); értékadás is alkalmazható.