Fórum témák

» Több friss téma
Cikkek » Kapcsoló kártya RS-485 buszra
Kapcsoló kártya RS-485 buszra
Szerző: dc001, idő: Márc 18, 2011, Olvasva: 18821, Oldal olvasási idő: kb. 4 perc
Lapozás: OK   9 / 11

A Makefile-ban az alábbi beállításokat lehet elvégezni:

F_CPU=7372800 – használt kvarc frekvenciája
UART_BAUD=38400 – az RS485-ös busz sebessége

ISPPORT=/dev/ttyACM0 – programozó portja
ISPBAUD=9600 – programozó sebessége
PROGRAMMER=stk500v2 – programozó típusa

A forrásból hex file-t fordítani a make paranccsal lehet. Az elkészült hex file-t az Atmega-8-ba felprogramozni a make write paranccsal és a FUSE biteket beállítani a make writefuse paranccsal tudjuk.

A programban lévő függvények:

SIGNAL(SIG_UART_RECV)

Amennyiben adat érkezik a soros porton, akkor hívódik meg ez a megszakítás. Egyrészről a beérkező adatokat egy gyűrű pufferben (RxBuffer) tárolja. Másrészről ellenőrzi, az utoljára elküldött (TxBuffer[TxCheckPtr++]) byte-ot a soros porton.
Ezzel az ellenőrzéssel történik az ütközés deteketálás az RS485-ös soros buszon. A klasszikus esetben egy kijelölt egység tölti be a master szerepét, amely megszólít egy adott a slave eszközt. Az ilyen buszon csak a master kezdeményezhet kommunikációt,a slave eszközök közöl csak a master által megszólított eszköz írhat az RS485 buszra. Mivel ennél a megvalósításnál nincs master eszköz (mindegyik egyenrangú), ezért szükséges valamilyen módszer annak szabályozására, hogy melyik eszköz írhatja a RS485-ös buszt. Amennyiben egynél több eszköz írná egyszerre a buszt, akkor az eszközök által írt információk „összekeverednek” vagyis ebben az állapotban nem biztosított az adatok megfelelő továbbítása.
Mivel az itt alkalmazott SN75176 buszmeghajtó lehetővé teszi, hogy írási művelet végrehajtásakor is olvasható a busz, ezért a visszaolvasott adatok alkalmasak ütközés detektálásra. Az ütközés detektálás úgy történik, hogy minden buszra kiírt byte visszaolvasásra és ellenőrzésre kerül. Amikor a kapcsoló kártya nem pontosan azt az adatot olvassa vissza, amelyet előzőleg kiírt, akkor nagy valószínűség szerint vele egy időben egy másik kártya is írni próbálta a buszt. Ekkor az aktuális üzenet továbbítását megszakítja és csak meghatározott idő múlva próbálja újra.
A várakozási időt minden kártya a saját azonosító kódjából határozza meg: első ütközés esetén 2ms (1x2ms) + 2ms ha az eszközazonosító 0. bitje 1, második esetben 4ms (2x2ms) + 2ms ha az azonosító 1. bitje 1, harmadszorra 6ms (3x2ms) + 2ms ha a 2. bit 1, és így tovább. Ezzel a módszerrel próbálják a kártyák egymás között eldönteni, ki kapja meg a busz írási jogát. Bármelyik eszköz csak akkor kezdheti írni a buszt, ha a buszon egy üzenet teljes mértékben továbbításra került. Annak elkerülésére, hogy egy elkezdett, de be nem fejezett üzenet blokkolja (minden kártya vár az üzenet befejezése, amely nem történik meg) a kommunikációt egy-egy üzenet az RX_TIMEOUT által meghatározott idő (20ms) után befejezettnek tekintett.

SIGNAL(SIG_UART_DATA)

Ez a megszakítási rutin jóval egyszerűbb: ha elküldésre került egy byte, akkor kiírja a következő byte-ot a soros portra. Utolsó byte esetén leállítja a további küldést: „UCSRB &= ~_BV(UDRIE);”.

void init_uart()

A soros port inicializálását végzi, alaphelyzetbe állítja küldésénél és fogadásnál használt változókat, start és stop bit-eket valamint a soros port előosztását a processzor frekvenciája (F_CPU) és a soros port sebességének (UART_BAUD) függvényében.

int isRxEmpty(void)

Igaz értékkel tér vissza, nincs fogadott adat.

int isTxEmpty(void)

Igaz értékkel tér vissza, ha a küldő buffer üres.

int isRxCmd(void)

Igaz értékkel tér vissza, ha van teljes üzenet a fogadó buffer-ben.

void dropTxData(void)

Kiüríti a küldő buffer-t és leállítja az adatküldést a soros buszra.

unsigned int getRxData(void)

Az alsó byte-on a soros port-ról beolvasott adattal, a felső byte-on státusz információval tér vissza.

void addTxHalfByte(unsigned char c)

Egy fél hexadecimális szám hozzáadása a küldő buffer-hez.

void addTxHex(unsigned char c)

Egy egész hexadecimális szám hozzáadása a küldő buffer-hez.

void commitTxData(void)

Adatküldés elindítása.

void delay(double msec)

Az msec paraméterben meghatározott ideig (milliszekundumban) várakozik és az időzítő számlálók értékeit ezzel az értékkel módosítja.

void set_output(const unsigned char _output_stat)

A paraméterként kapott byte alapján beállítja a kimeneteket.

int send_header(unsigned char id)

Üzenet fejlécének összeállítása (*+<parancs kód>+<eszköz azonosító>) a paraméterként kapott parancs kóddal.

void send_error()

Hibaüzenet küldése a buszra.

void send_status()

Státusz üzenet küldése a buszra.

void send_output(const unsigned char n)

Paraméterkénr megadott kimenet konfigurációjának küldése a buszra.

static unsigned char hex2dec(const unsigned char c)

A paraméterként megadott hexadecimális karakter decimális számmá konvertálja (pl.: 'a' → 10, 'B' → 11).

unsigned int calc_timer(unsigned char t)

A paraméterként kapott időt másodpercekre alakítja.

void process_input(const unsigned char id, const unsigned char input, const unsigned char output)

A paraméterként kapott beolvasott státusz információt (forrás eszköz valamint annak be- és kimeneteinek az állapota, vagy saját be- és kimeneteinek állapota) feldolgozza és a konfigurációjának megfelelően megváltoztatja a kimenetek állapotát.

static void read_inputs()

Bemenetek beolvasása.

void manual_config(void)

Nyomógombokkal végzett eszközazonosító beállítását kezeli le ez a függvény.

void process_command(void)

Beolvasott üzenetek feldogozása.

int main(void)

Főprogram. Első lépésben beállítja a megfelelő portokat kimenetre, bekacsolja a megfelelő felhúzó ellenállásokat és alaphelyzetbe állítja a kimeneteket. Ezután beolvassa az eszközazonosító és konfigurációs beállításokat az eeprom-ból. A következő lépés a soros port inicializálása és a megszakítások engedélyezése. A fő ciklus előtt a manual_config() függvénnyel szükség esetén megváltoztatható az eszközazonosító.
A while főciklusban először beolvassa a bemeneteket (read_inputs) majd ezeket feldolgozza (process_input). A következő lépésben a nyomógombok állapotának feldogozása történik. Amennyiben érkezett üzenet (isRxCmd) akkor azt feldolgozza (process_command). Amennyiben nem érkezett adat (isRxEmpty), akkor elküldi vagy a hibakódot (send_error), vagy a kimenet konfigurációját (send_output) vagy a státusz információt (send_status). Ha az adatküldés véget ért akkor kikapcsolja (PORTD &= ~(1<<PIND2) az SN75176 írási módját. Ha kimenetek tesztelése aktív (outtest), akkor a kimenetek aktuális értéke (output_stat) helyett a teszt kimenetek kerülnek aktiválásra. A ciklus befejező részében van megvalósítva az eszközazonosítótól függő várakozás ütközés detektálás esetén.


A cikk még nem ért véget, lapozz!
Következő: »»   9 / 11
Értékeléshez bejelentkezés szükséges!
Bejelentkezés

Belépés

Hirdetés
XDT.hu
Az oldalon sütiket használunk a helyes működéshez. Bővebb információt az adatvédelmi szabályzatban olvashatsz. Megértettem