[ Pobierz całość w formacie PDF ] .cbInQue > 0){if (Stat.cbInQue > Buf_Size)nNumberOfBytesToRead = Buf_Size;elsenNumberOfBytesToRead = Stat.cbInQue;ReadFile(hCommDev, lpBuffer, nNumberOfBytesToRead,lpNumberOfBytesRead, NULL);}else*lpNumberOfBytesRead = 0;return TRUE;}//--------------------------------------------------------------------__fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner){}//---------zamknięcie portu i aplikacji-------------------------------void __fastcall TForm1::CloseCommClick(TObject *Sender){Close_Comm(hCommDev);Application->Terminate();}//---------otwarcie portu do transmisji-------------------------------void __fastcall TForm1::OpenCommClick(TObject *Sender){if (CheckBox1->Checked == TRUE) // wybór portulpFileName="COM1";if (CheckBox2->Checked == TRUE)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);112 dcb.DCBlength = sizeof(dcb); // aktualny rozmiar// struktury DCBGetCommState(hCommDev, &dcb);if (CheckBox3->Checked == TRUE) // wybór prędkości transmisjidcb.BaudRate=CBR_300;if (CheckBox4->Checked == TRUE)dcb.BaudRate=CBR_1200;if (CheckBox5->Checked == TRUE)dcb.BaudRate=CBR_9600;//--parametry komunikacyjne-------dcb.Parity = ODDPARITY; // ustawienie parzystościdcb.StopBits = ONESTOPBIT; // bity stopudcb.ByteSize = 7; // bity danych//--przykładowe ustawienia znaczników sterujących DCB----dcb.fParity = TRUE; // sprawdzanie parzystościdcb.fDtrControl = DTR_CONTROL_ENABLE; // sygnał DTR stale// aktywnydcb.fRtsControl = RTS_CONTROL_DISABLE;// RTS stan// nieaktywnydcb.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);GetCommMask(hCommDev, &fdwEvtMask);SetCommMask(hCommDev, EV_TXEMPTY);//DWORD &fdwEvtMask = EV_TXEMPTY | EV_CTS;//SetCommMask(hCommDev, fdwEvtMask);}else{switch ((int)hCommDev){case IE_BADID: // W przypadku błędnej identyfikacji portu// BADIDentify pokaż komunikatMessageBox(NULL, "Niewłaściwa nazwa portu lub port jest"" aktywny.", "Błąd", MB_OK);break;};}}//------------------------------------------------------------------void __fastcall TForm1::SendClick(TObject *Sender){FILE *pstream; // wskaznik do plikuif (hCommDev > 0) // powtórnie sprawdza czy port jest otwarty{strcpy(Buffer_O, query);Write_Comm(hCommDev, Buffer_O, strlen(Buffer_O));Sleep(1000); // charakterystyczne opóznienie sprzętowe113 FlushFileBuffers(hCommDev);Read_Comm(hCommDev, &Buffer_I[0], &Number_Bytes_Read,sizeof(Buffer_I));if (Number_Bytes_Read > 0) // jeżeli odebrano jakieś bajty{pstream = fopen("dane.dat","a"); // otwarcie pliku do zapisuEdit1->Text = &Buffer_I[0];//(*Edit1).Text = &Buffer_I[0];fprintf(pstream, "%s", Edit1->Text);//fprintf(pstream, "%s", (*Edit1).Text);fclose(pstream); // zamknięcie pliku}}elseMessageBox(NULL, "Port nie został otwarty do transmisji.","Błąd", MB_OK);}//--------------------------------------------------------------------Patrząc na treść funkcji obsługi zdarzenia OpenCommClick(), uważny Czytelnik zapewnedostrzegł, że sygnał DTR uczyniliśmy stale aktywnym w trakcie połączenia.Oczywiście sąurządzenia, które tego nie wymagają, ale sygnalizujemy tu pewną ogólną ideę konstrukcjiprogramów komunikacyjnych.Zauważmy też, że sygnał na linii RTS w momencie inicjalizacjiportu został ustawiony jako nieaktywny.Zrobiliśmy tak, aby komputer nie sygnalizowałurządzeniu od razu zamiaru przekazywania danych.Zamiar ten będziemy każdorazowosygnalizować wewnątrz funkcji Write_Comm(), jeżeli oczywiście urządzenie tego wymaga.Uczyniliśmy to, wykorzystując właściwości EscapeCommFunction().Należy jednak pamiętać,że po wysłaniu danego komunikatu sygnał ten trzeba każdorazowo dezaktywować za pomocą tejsamej funkcji, tak jak przedstawia to powyższy kod.W ten sam sposób, w zależności od potrzeb,można uaktywniać również inne linie sygnałowe.Można też w odpowiednich miejscach wprogramie odwoływać się do opisanych wcześniej elementów struktury COMSTAT (fCtsHold,fDsrHold, fRlsdHold).Ale o tym wszystkim musi już zadecydować osoba mająca przed sobąkonkretne urządzenie.Analizując z kolei zapis funkcji obsługi zdarzenia SendClick() dojdziemy do wniosku, żecztery punkty wymagają komentarza.1.Użycie funkcji opózniającej Sleep().Przy realizacji transmisji pomiędzy dwoma komputerami podtrzymywanie jakiegoś sztucznegoopóznienia pomiędzy wysyłaniem a odbiorem danych nie jest wymagane, rzecz jasna podwarunkiem, że transmitujemy ich stosunkowo niewiele.Jeżeli będziemy przesyłać ciąg znakówreprezentujący większy fragment tekstu, musimy pamiętać, że poszczególne znaki przesyłane będąpo kolei (szeregowo) i dopiero w buforze wejściowym zostaną połączone w jedną całość.To zreguły zabiera trochę czasu.Podobnie jest w przypadku urządzeń pomiarowych.Niestety, miernikmusi mieć czas na to, by odpowiednio zareagować na komendę, musi też mieć czas na dokonaniepomiaru i przestrojenie się.Charakterystyczny dla niego czas opóznienia (podawany zazwyczaj wmilisekundach) jest zawsze wyspecyfikowany w instrukcji obsługi, którą dostajemy od producentawraz z przyrządem.Należy przy tym zwrócić baczną uwagę na fakt, że opóznienie takiebezpośrednio zależy od aktualnej prędkości transmisji.Im mniejsza jest jej prędkość, tym dłużejmusimy czekać na odpowiedz urządzenia.1142.Czyszczenie buforów komunikacyjnych.Pomiędzy funkcje zapisującymi do portu szeregowego i odczytujące z niego informacjewstawiliśmy funkcję Win32 API, której pełny opis wyglada następująco:BOOL FlushFileBuffers(HANDLE hCommDev);Użycie jej w programie spowoduje wyczyszczenie bufora komunikacyjnego.Oznacza to, żewszystkie znajdujące się w nim jeszcze nie wykorzystane dane zostaną przekierowane do portukomunikacyjnego (lub innego urządzenia) jednoznacznie identyfikowanego przez hCommDev, podwarunkiem, że identyfikator ten zostanie zainicjowany z rodzajem dostępu GENERIC_WRITE.Jest to jeden ze sposobów zabezpieczenia się przed odbiorem własnych, wysyłanychkomunikatów.Użycie funkcji przepłukującej bufor (ang
[ Pobierz całość w formacie PDF ] zanotowane.pldoc.pisz.plpdf.pisz.plmikr.xlx.pl
|