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;
}
Kompenentsiz güzel bir örnek eline saglik.
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
CRT sorununa benziyor, C Run Time. Proje özelliginden C/C++ seçeneklerini ayarlamalisin.
Yeni proje açarken Wizarda "Console Application" seçecen.
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?
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ı ?
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;
İ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.
}
}