. : New eShop! - Mobilní verze - Pandatron.cz - Pandatron.sk - Diskuzní fórum - Zakázkový vývoj : .
 
Sériová komunikace v C++Builderu
1. října 2010 - 8:23 | Milan Štohanzl | Sériová komunikace v C++Builderu | Komentářů: 2  

Sériová komunikace v C++Builderu

Přehledný návod na využití knihovny Tserial v systému C++Builderu pro zajištění sériové komunikace počítače s libovolným sériovým zařízením.

Následující článek tvoří přehledný návod na vytvoření sériové komunikace v systému C++Builderu. Využívá přitom knihovnu Tserial od autora Thierry Schneider (thierry tetraedre.com), která je v podobě souborů Tserial.cpp a Tserial.h dostupná na internetové stránce: http://www.tetraedre.com/advanced/serial. Knihovna je určena pro tzv. „programy bez událostí“ (non-events-driven programs). To znamená, že například při příjmu dat do PC nemáme k dispozici hardwarové přerušení od přijímacího bufferu COM linky v PC.

Přehled funkcí z knihovny Tserial:

  • int Tserial:: connect (char *port_arg, int rate_arg, serial_parity parity_arg)
  • void Tserial::disconnect(void)
  • void Tserial::sendChar(char data)
  • void Tserial::sendArray(char *buffer, int len)
  • char Tserial::getChar(void)
  • int Tserial::getArray (char *buffer, int len)
  • int Tserial::getNbrOfBytes (void)

Všechny tyto funkce jsou popsány a představeny na následujícím jednoduchém příkladu:

1. Do adresáře nahrát soubory: Tserial.h a Tserial.cpp.
V projektu vložit knihovnu: #include "Tserial.h" a tlačítkem "Add file to projects (Shift+F11)" vybrat Tserial.cpp soubor.

2. Vytvořit ukazatele na Tserial:
Tserial *com;
Tuto deklaraci vložit v místě stejné deklarace pro formulář (např. TForm1 *Form1;).

3. Otevření portu:
Otevření portu je vhodné vyvolat jako následek nějaké události, například klik na tlačítko.
Kód bude následovný:

    com = new Tserial();          //Vytvoření nové relace
    if (com!=0){                  //Test vytvořené komunikace

      /* Zde mohou proběhnout úpravy formuláře spojené s otevřením portu */

      com->connect("COM1",9600, spNONE);  //Vlastní otevření portu
    }

COM1 zde představuje název COM portu, chceme-li jej vytvořit jako proměnou, musí mít následující tvar a být typu char.
9600 zde představuje přenosovou rychlost v baud/s. Proměnná je typu int.

spNONE zde představuje použití parity:

  • spNONE - žádná parita
  • spODD - lichá parita
  • spEVEN - sudá parita

4. Uzavření portu:
Je vhodné uzavření portu vyvolat, stejně jako jeho otevření, klikem na tlačítko.

Kód bude následovný:

    if(com!=0){                   //Je-li port otevřen
      com->disconnect();          //Uzavření portu

      /* Zde mohou proběhnout úpravy formuláře spojené s uzavřením portu */

      delete com;                 //Smazaní proměnné com
      com = 0;                    //Nastaveni proměnné na hodnotu neaktivního portu
    }

Je důležité, aby všechny otevřené porty byly vždy korektně uzavřeny. Proto je vhodné tento kód vložit i do události na uzavření formuláře apod.
Chceme-li před uzavřením portu odvysílat ještě nějaká data (upozornit zařízení, že už nebudeme nic zpracovávat), je potřeba mezi odeslání dat a uzavření portu vložit nějaké zpoždění, jinak by mohlo docházet k problémům. Zpoždění je možno vytvořit pomocí časovače (Timer se nalézá v záložce System) anebo pomocí prázdné smyčky for.

5. Odesílání dat přes COM (z PC do zařízení):
Kdekoliv v programu lze nyní odesílat znaky typu char přes sériovou linku, samozřejmě jen v případě, že je port nastavený a otevřený (jak bylo ukázáno v bodě 3.).

Pro odeslání dat obsahuje knihovna Tserial.c dvě funkce:

a) sendChar(char);

Tato funkce umožňuje odeslat jeden znak typu char. Kód může být následující:

    com->sendChar('A');           //Odešle znak A přes COM

Místo znaku zde může být samozřejmě i proměnná typu char nebo číslo reprezentující znak char v ASCII tabulce.

b) sendArray(char *,int);

Tato funkce umožňuje odeslat řetězec znaků známé délky typu char. Kód může být následující:

    char buff[5];                 //Vytvoří řetězec typu char délky 5 (4+NULL znak)
    buff[0] = 'R';                //Naplní pozici 0 znakem R
    buff[1] =  13;                //Naplní pozici 1 znakem ukrytým pod číslem 13
    buff[2] =  10;                //Naplní pozici 2 znakem ukrytým pod číslem 10
    com->sendArray(buff,4);       //Odeslání dat

Poznámka: Znaky, ukryté pod číslem 13 a 10, nebo libovolným, odpovídají ASCII tabulce. Znak pod číslem 13 se často označuje jako CR a znak pod číslem 10 jako LF.

Jak odeslat řetězec neznámé délky? Lze použít funkce z knihoven Builderu, které vracejí hodnotu délky řetězce a použít sendArray();. Tyto funkce neznám a proto věc obcházím následovně:

    char buff[] = ......;         //Řetězec neznámé délky
    char *point;                  //Vytvoříme si ukazatel na char

    /* pro odeslání použijeme kód: */

    point  =  &buff[0];           //point ukazuje na začátek buff
    while(*point) {
      com->sendChar(*(point++));  //Odesílání znaku a inkrementace ukazatele
    }

Cyklus while se provádí tak dlouho, dokud ukazatel odkazuje na platná data v rámci pole buff. Zápis (*(point++)) znamená, že bereme data z oblasti, kam ukazuje point a pokaždé hodnotu ukazatele inkrementujeme. To zajistí, že postupně projdeme až na konec řetězce buff.

6. Příjem dat přes COM (ze zařízení do PC):
Problematika příjmu dat je trochu komplikovanější a proto zde uvedu pouze pár příkladů, které jsem sám otestoval a které fungují. Bohužel knihovna neumožňuje zpracovávat události přijímacího bufferu COM linky PC.

Jedním ze způsobů, jak lze data přijímat, je testovat pravidelně otevřený port. Toho lze dosáhnout vložením časovače do projektu a v reakci na jeho přetečení testovat přijímací buffer linky COM. Kód může být následující:

    char buff[6];                 //Vytvoření proměnné buff délky 6
    if (com->getNbrOfBytes() == 0) return;   //Test přijímacího bufferu PC
    com->getArray(buff,5);        //Naplnění proměnné buff daty

int getNbrOfBytes(); Je funkce z knihovny Tserial a vrací hodnotu počtu bajtů v přijímacím bufferu. Díky tomu můžeme přijímat i zprávy proměnné délky. Tento kód se však omezuje na příjem dat známé délky (5 bajtů).
if (com->getNbrOfBytes() == 0) return; Zajistí, že v případě prázdného přijímacího bufferu nebude následující kód vykonáván a vlastní obsluha přetečení časovače bude v takovém případě rychle ukončena.
Poznámka: Je nutné zajistit, aby předchozí kód nebyl vykonáván v případě, kdy není COM port otevřený. Toho lze dosáhnout testováním podmínky:

    if(com!=0){                   //Je-li port otevřen

na začátku kódu. Mnohem efektivnější je nastavit implicitně časovač jako neaktivní (parametr Enabled jako false). Při otevření portu poté stačí jan přidat kód aktivující časovač a při uzavírání portu opět časovač deaktivovat. Například:

Form1 -> Timer1 -> Enabled = true; //Aktivace časovače
Form1 -> Timer1 -> Enabled = false; //Deaktivace časovače

Stejně jako u odesílání dat je v rámci knihovny Tserial vytvořena funkce příjmu pouze jediného bajtu. Funkce se volá: com->getChar(); a vrací char.

Poznámka k práci s Časovačem v Borland C++ builderu:
Vložení modulu časovače:

Timer vybereme ze záložky System a kliknutím na formulář vložíme do projektu.
Dle následujícího obrázku nastavíme Timer implicitně na neaktivní (Enabled=false). Interval přetečení je zde nastaven na 200, což znamená 200 ms. Implicitní hodnota 1000 znamená přetečení 1x za sekundu. V záložce Events je jediná položka OnTimer. Dvojklikem do místa, kde ukazuje šipka, se vygeneruje kód, kde můžeme psát kód (viz bod 6).

Poznámka k příjmu dat: Přijímání dat pravidelným testováním přijímacího bufferu je vhodné u aplikací, které pravidelně odesílají nějaká data (například měřící zařízení). Když vytvoříme přesně definované zprávy se záhlavím a zápatím, na které přijatá data testujeme, je příjem dat téměř bezproblémový.

V přiložených zdrojových souborech naleznete dva prográmky. Jeden slouží k odesílání dat přes sériovou linku a druhý k příjmu dat ze sériové linky. Jsou vytvořeny pouze jako demonstrační příklady a slouží k praktickému vysvětlení toho, co zde bylo řečeno.

Autor: Milan Štohanzl (stohanmiseznam.cz).

Odkazy & Download:
Domovská stránka výrobce C++Builderu
Serial Communication for WIN32







GooglePlus1 FaceBook Twitter del.icio.us DiGG Google StumbleUpon Google Buzz Email RSS PDF Tisk

Komentáře (2):

Zobrazit starší 30 dnů (2)...



Název příspěvku: Vaše jméno: host
                 
  Zakázat formátování [Zakáže kódování a nahrazování smajlíky.]
Připojit soubory
reklama:
WIZ107SR-RS232
Převodník TCP/IP <-> RS232 s RJ45 konektorem.
Skladem od 600 Kč

Informace uvedené v článcích jsou platné v době jejich vydání a samotné články jsou určeny pouze jako zdroj informací. Autor článku ani správce webu nenesou žádnou zodpovědnost za případné újmy na majetku a zdraví. Názvy společností a výrobků, loga a další multimediální materiál mohou být ochrannými známkami příslušných společností.
RSS kanály: | |
+420 723 846 377
info@pandatron.cz
Všechna práva vyhrazena | mobilní verze | © Copyright 2000 - 2016 ISSN 1803-6007