Seri port programlama örnek

Başlatan d_yol, 20 Mart 2007, 22:51:51

d_yol

Merhaba arkadaşlar,
bu forumda hep seri port ile ilgili sorular gördüm. Genelde hazır komponentler kullanılıyor. Ama size nasıl seri porta komponent olmadan kullanacağınızı göstermek istiyorum. Kod aşağıda:

#include "stdio.h"
#include "windows.h"

int main(int argc, char* argv[])
{
    DCB dcb;
    HANDLE hCom;
    COMMTIMEOUTS CommTimeOuts;
    DWORD nWrite;
    DWORD nRead;
    char TextLine[255];

    // Port açma
    hCom = CreateFile((LPCTSTR)"\\\\.\\COM1", GENERIC_READ|GENERIC_WRITE, 
                       0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    // Açıldımı ?
    if (hCom == INVALID_HANDLE_VALUE)
        return 0;
    
    // Giriş çıkış buffer ayarla
    SetupComm(hCom, 4096, 4096);

	
    // mevcut ayarları oku
    GetCommState(hCom, &dcb);
	
    dcb.BaudRate = 19200;               /* Baudrate at which running       */
    dcb.fBinary = TRUE;                 /* Binary Mode (skip EOF check)    */
    dcb.fParity = FALSE;				/* Enable parity checking          */
    dcb.fOutxCtsFlow = FALSE;           /* CTS handshaking on output       */
    dcb.fOutxDsrFlow = FALSE;           /* DSR handshaking on output       */
    dcb.fDtrControl = DTR_CONTROL_ENABLE; /* DTR Flow control                */
    dcb.fDsrSensitivity = FALSE;        /* DSR Sensitivity              */
    dcb.fTXContinueOnXoff = FALSE;      /* Continue TX when Xoff sent */
    dcb.fOutX = FALSE;                  /* Enable output X-ON/X-OFF        */
    dcb.fInX = FALSE;                   /* Enable input X-ON/X-OFF         */
    dcb.fErrorChar = FALSE;             /* Enable Err Replacement          */
    dcb.fNull = FALSE;                  /* Enable Null stripping           */
    dcb.fRtsControl = RTS_CONTROL_ENABLE; /* Rts Flow control                */
    dcb.fAbortOnError = FALSE;          /* Abort all reads and writes on Error */
    dcb.ByteSize = 8;                   /* Number of bits/byte, 4-8        */
    dcb.Parity = 0;                     /* 0-4=None,Odd,Even,Mark,Space    */
    dcb.StopBits = ONESTOPBIT;          /* 0,1,2 = 1, 1.5, 2               */

    // ayar yap
    SetCommState(hCom, &dcb);

    // Timeout ayarla (2s)
    CommTimeOuts.ReadIntervalTimeout = 0;
    CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
    CommTimeOuts.ReadTotalTimeoutConstant = 2000;
    CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
    CommTimeOuts.WriteTotalTimeoutConstant = 2000;
	
    // ayarları yaz
    SetCommTimeouts(hCom, &CommTimeOuts);
 
    // DTR RTS aktif yap
    EscapeCommFunction(hCom, SETDTR);
    EscapeCommFunction(hCom, SETRTS);


    // buffer leri önceden boşalt
    PurgeComm(hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
    
    // seri porta bilgi gönder
    WriteFile(hCom, "BU BIR TEST", (DWORD) strlen("BU BIR TEST"), &nWrite, NULL);
		
    // seri portdan bilgi oku
    ReadFile(hCom, TextLine, sizeof(TextLine), &nRead, NULL);

    // Okunanı yaz
    printf("%*s", nRead, TextLine);

    // port kapat
    CloseHandle(hCom);

	return 0;
}

Digimensch

Kompenentsiz güzel bir örnek eline saglik.

strom

Hocam visual C++ 6.0 ile derleme yaptığımda
--------------------Configuration: seri - Win32 Debug--------------------
Compiling...
Text1.cpp
Linking...
LIBCD.lib(wincrt0.obj) : error LNK2001: unresolved external symbol _WinMain@16
Debug/seri.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.

seri.exe - 2 error(s), 0 warning(s)

diye bir hata mesajı aldım.Sizce ne demek istiyor bu mesajda

picusta

CRT sorununa benziyor, C Run Time. Proje özelliginden C/C++ seçeneklerini ayarlamalisin.

d_yol

Yeni proje açarken Wizarda "Console Application" seçecen.

Gökhan BEKEN

Konu mumya olmuş :D
Ben bu örneği kullanıyorum ama sorunum var, gelen verinin ne zaman geleceği belli değil.
ReadFile(hCom, gelenVeri, sizeof(gelenVeri), &nRead, NULL);
fonksiyonu ile okuma yapmak işimi görmüyor. Bana c# dilindeki gibi handler lazım. Veri gelince kesmeye girecek ve o fonksiyonda gelen verileri diziye aktaracağım.
Bunu nasıl yapabiliriz?
Özel mesaj okumuyorum, lütfen göndermeyin.

AsHeS

Alıntı yapılan: meftun - 17 Temmuz 2014, 02:09:23
Konu mumya olmuş :D
Ben bu örneği kullanıyorum ama sorunum var, gelen verinin ne zaman geleceği belli değil.
ReadFile(hCom, gelenVeri, sizeof(gelenVeri), &nRead, NULL);
fonksiyonu ile okuma yapmak işimi görmüyor. Bana c# dilindeki gibi handler lazım. Veri gelince kesmeye girecek ve o fonksiyonda gelen verileri diziye aktaracağım.
Bunu nasıl yapabiliriz?

İlgili fonksiyonu  bir thread içerisine koysanız olmaz mı ?

Gökhan BEKEN

Hocam, C ile hiç multithread çalışması yapmadım, lakin kullandığım projede OpenGL'in arka planda çalışan kendi threadlari var. Mesela klavyeye handler fonksiyonu var. Ben de arka planda handler olarak değil de sürekli çalışan bir fonksiyonun içinde yukarıda ki yazdığım ReadFile ile okumaya çalışıyorum, fakat veriler sürekli ve 100ms'de bir geldiği için bazen yakalayamıyor yanlış veya eksik veri okuyor.

Şunu da belirtiyim,
CommTimeOuts.ReadTotalTimeoutConstant = 2000;
kısmı bende 200 değil 100, bu kısım gelen veriyi çok etkiliyor, daha düşük yaptım ama çözüm olmadı.

Bu kısım ne işe yarıyor bilmiyorum:
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
Özel mesaj okumuyorum, lütfen göndermeyin.

AsHeS

#8
İlgili comm portu açma işleme ve dinleme kısımlarını threade bırakın siz sadece bir handler fonksiyonu ile datanızı çözdürün. Eğer gerekirse CriticalSection yapısı kullanırsınız.

Thread Örneği;
#include <windows.h> 
#include <stdio.h>
DWORD WINAPI thread_function( LPVOID lpParam ) 
{
    while(1)
    { 
          printf("Say Hello\n\r");
          Sleep(100);//Derleyiciye göre değişebilir
    }
    return 0; 
}

int main()
{
HANDLE threadH;
threadH = CreateThread( NULL, 0,  thread_function, NULL, 0, NULL);
if (threadH == NULL)   return 0;

while(1)
{
    printf("Asenkron \n\r");
    Sleep(5000);//Derleyiciye göre değişir.
}
}