RTV forum PL | NewsGroups PL

Problemy z odbiorem danych przez RS232 w aplikacji C++ Builder 6 na Windows XP

RS232 i program na PC w C++Buiderze

NOWY TEMAT

elektroda NewsGroups Forum Index - Elektronika Polska - Problemy z odbiorem danych przez RS232 w aplikacji C++ Builder 6 na Windows XP

Krzysztof Urbanski
Guest

Sat Nov 27, 2004 12:58 pm   



Witam
Zrobilem sobie i oprogramowalem urzadzenie na atmedze ktore ma sie
komunikowac przez RSa z PCtem. Na terminalu wszystko dziala dobrze.
Postanowilem napisac sobie aplikacje w C++ Builerze 6 pod WinXP. Wzrouje
sie na ksiazce Andrzeja Daniluka "RS232C Praktyczne programowanie".
Wysylanie czegos z PC do uC dziala idealnie. Niestety nie chce mi
dzialac odbior znakow. Czy sa z tym jakies problemy pod XP czy problem
tkwi tylko w tym ze ja nie umiem tego wlasciwie oprogramowac ? Smile Robie
to praktycznie tak samo jak w przykladach z tej ksiazki jednak program
przy dojsciu do :

return ReadFile(hCommDev, lpBuffer, nNumberOfBytesToRead,
lpNumberOfBytesRead, NULL);

w funkcji Read_Comm, przestaje odpowiadac.
Moze ktos wie o co chodzi ?

//----------------------------------------------------------
#define cbOutQueue 64 //rozmiar bufora danych wyjściowych
#define cbInQueue 64 //rozmiar bufora danych wejściowych

TForm1 *Form1;

char Buffer_I[cbInQueue]; // bufor danych wejściowych
DWORD Number_Bytes_Read; // Number Bytes to Read - liczba
// bajtów do czytania
HANDLE hCommDev; // identyfikator portu
DWORD fdwEvtMask; // informacja o aktualnym stanie transmisji
COMSTAT Stat; // dodatkowa informacja o zasobach portu
DWORD Errors; // reprezentuje typ ewentualnego błędu

LPCTSTR sbuffer1 = "Niewłaściwa nazwa portu lub port jest"
" aktywny.";
LPCTSTR sbuffer2 = "Błąd";
LPCTSTR sbuffer3 = "Port nie został otwarty do transmisji.";

//----------------zamyka port------------------------------
BOOL __fastcall Close_Comm(HANDLE hCommDev)
{
return Win32Check(CloseHandle(hCommDev));
}
//---------zamyka port i aplikację-------------------------
void __fastcall TForm1::ZamknijClick(TObject *Sender)
{
Close_Comm(hCommDev);
Application->Terminate();
}
//-------------------odczyt danych-------------------------
BOOL __fastcall Read_Comm(HANDLE hCommDev, LPVOID lpBuffer,
LPDWORD lpNumberOfBytesRead, DWORD Buf_Size)
{
DWORD nNumberOfBytesToRead;
ClearCommError(hCommDev, &Errors, &Stat);
*lpNumberOfBytesRead = 0;
if (Stat.cbInQue > 0)
{
if (Stat.cbInQue > Buf_Size)
nNumberOfBytesToRead = Buf_Size;
else
nNumberOfBytesToRead = Stat.cbInQue;
}
return ReadFile(hCommDev, lpBuffer, nNumberOfBytesToRead,
lpNumberOfBytesRead, NULL);
}
//---------otwarcie portu do transmisji--------------------
void __fastcall TForm1::OtworzClick(TObject *Sender)
{
LPCTSTR lpFileName; // wskaźnik do nazwy portu
DCB dcb; // struktura kontroli portu szeregowego

lpFileName="COM2";

hCommDev = CreateFile(lpFileName, GENERIC_READ |
GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, 0, NULL);

if (hCommDev != INVALID_HANDLE_VALUE)
// sprawdza, czy port jest otwarty prawidłowo
{
SetupComm(hCommDev, cbInQueue, cbOutQueue);
dcb.DCBlength = sizeof(dcb); // aktualny rozmiar
// struktury DCB
GetCommState(hCommDev, &dcb);
dcb.BaudRate=CBR_9600;
dcb.Parity = NOPARITY; // ustawienie parzystości
dcb.StopBits = ONESTOPBIT; // bity stopu
dcb.ByteSize = 8; // bity danych
dcb.fParity = FALSE; // sprawdzanie parzystości
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = FALSE;
dcb.fDsrSensitivity = FALSE;
dcb.fAbortOnError = FALSE;
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
dcb.fErrorChar = FALSE;
dcb.fNull = FALSE;
SetCommState(hCommDev, &dcb);
}
else
{
switch ((int)hCommDev)
{
case IE_BADID:
MessageBox(NULL,sbuffer1,sbuffer2, MB_OK);
break;
};
}
}
//---------------------------------------------------------
void __fastcall TForm1::OdbierzClick(TObject *Sender)
{

if ((hCommDev != INVALID_HANDLE_VALUE) && (hCommDev > 0))
// powtórnie sprawdza czy port jest otwarty
{
FlushFileBuffers(hCommDev);
Read_Comm(hCommDev, &Buffer_I[0], &Number_Bytes_Read,
sizeof(Buffer_I));

if (Number_Bytes_Read > 0)
// jeżeli odebrano jakieś bajty
{
Edit1->Text = &Buffer_I[0];
}
}
else
MessageBox(NULL, sbuffer3, sbuffer2, MB_OK);
}
//---------------------------------------------------------


--
Pozdrawiam
Krzysztof Urbanski
krzysztof-u@[usun_to]wp.pl

point
Guest

Sat Nov 27, 2004 2:08 pm   



Krzysztof Urbanski wrote:
Quote:
Witam
Zrobilem sobie i oprogramowalem urzadzenie na atmedze ktore ma sie
komunikowac przez RSa z PCtem. Na terminalu wszystko dziala dobrze.
Postanowilem napisac sobie aplikacje w C++ Builerze 6 pod WinXP.

Olej win API i wykorzystaj gotowy komponent do Buidera:
http://sourceforge.net/projects/comport/
Do ustawiania opcji UARTa jest gotowy dialog, zapis/odczyt to proste
wywołanie metody klasy: uart->write(), odczyt jako callback itp. Jest
nawet sterowanie RTS do RS485.

Jurek Szczesiul
Guest

Sat Nov 27, 2004 4:20 pm   



Sat, 27 Nov 2004 13:58:49 +0100, na pl.misc.elektronika, Krzysztof Urbanski
napisał(a):

Quote:
jednak program
przy dojsciu do :

return ReadFile(hCommDev, lpBuffer, nNumberOfBytesToRead,
lpNumberOfBytesRead, NULL);



Quote:
//-------------------odczyt danych-------------------------
BOOL __fastcall Read_Comm(HANDLE hCommDev, LPVOID lpBuffer,
LPDWORD lpNumberOfBytesRead, DWORD Buf_Size)
{
DWORD nNumberOfBytesToRead;
ClearCommError(hCommDev, &Errors, &Stat);
*lpNumberOfBytesRead = 0;
if (Stat.cbInQue > 0)
{
if (Stat.cbInQue > Buf_Size)
nNumberOfBytesToRead = Buf_Size;
else
nNumberOfBytesToRead = Stat.cbInQue;
}
return ReadFile(hCommDev, lpBuffer, nNumberOfBytesToRead,
lpNumberOfBytesRead, NULL);
}
Tak na pierwszy rzut oka :

Wywołujesz synchronicznie ReadFile poza warunkiem sprawdzającym czy jest
cos do odczytu. Jeśli nic nie ma to funkcja czeka na transmisję a ponieważ
jest wołana w głównym wątku programu - tym samym wiesza go. Na ogół przy
obsłudze synchronicznej upycha się pętlę sprawdzania transmisji
przychodzącej oraz odczyt bufora w potomnym wątku. To działa sprawnie ale
ma wadę - ciągłe obciążenie procesora. Dlatego lepiej używać wywołań
asynchronicznych i oczekiwac na ich rezultat także w oddzielnym wątku
funkcją WaitForxxx.

--
Pozdrowienia
Jurek Szczesiul

Q
Guest

Sat Nov 27, 2004 6:29 pm   



ntg, ale btw poczytaj sobie to lepiej:
http://msdn.microsoft.com/library/en-us/dnfiles/html/msdn_serial.asp

moki
Guest

Sat Nov 27, 2004 7:18 pm   



Po pierwsze uzyj funkcji
SetCommTimeouts(hPort,&tout);
to cie zabezpieczy przed zwisem programu przy odczycie


--
Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/

Krzysztof Urbanski
Guest

Sun Nov 28, 2004 2:24 pm   



Dzieki wszystkim. Pomeczylm sie i teraz juz zaczyna mi to jakos dzilac.


--
Pozdrawiam
Krzysztof Urbanski
krzysztof-u@[usun_to]wp.pl

elektroda NewsGroups Forum Index - Elektronika Polska - Problemy z odbiorem danych przez RS232 w aplikacji C++ Builder 6 na Windows XP

NOWY TEMAT

Regulamin - Zasady uzytkowania Polityka prywatnosci Kontakt RTV map News map