[ Pobierz całość w formacie PDF ]
.cbInQue > 0){if (Stat.cbInQue > Buf_Size)nNumberOfBytesToRead = Buf_Size;elsenNumberOfBytesToRead = Stat.cbInQue;ReadFile(hCommDev, &Buffer_I[0], nNumberOfBytesToRead,lpNumberOfBytesRead, NULL);}153 else*lpNumberOfBytesRead = 0;return TRUE;}//--------------------------------------------------------------------__fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner){}//--------------------------------------------------------------------void __fastcall TForm1::CloseCommClick(TObject *Sender){Timer1->Enabled = FALSE;Close_Comm(hCommDev);Application->Terminate();}//--------------------------------------------------------------------void __fastcall TForm1::FormCreate(TObject *Sender){Timer1->Enabled = FALSE;CSpinEdit1->Value = 100;CSpinEdit1->ReadOnly = FALSE;CSpinEdit1->Cursor = crNo;CSpinEdit1->Hint = "Ręczne wpisywanie może być niebezpieczne !";CSpinEdit1->ShowHint = TRUE;CSpinEdit1->Increment = 100;}//--------------------------------------------------------------------void __fastcall TForm1::CSpinEdit1Change(TObject *Sender){if (CSpinEdit1->Value Value = abs(CSpinEdit1->Value);Timer1->Interval = CSpinEdit1->Value;}//--------------------------------------------------------------------void __fastcall TForm1::MeasureOFFClick(TObject *Sender){Timer1->Enabled = FALSE;}//--------------------------------------------------------------------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);dcb.DCBlength = sizeof(dcb);GetCommState(hCommDev, &dcb);if (CheckBox3->Checked == TRUE) // wybór prędkości transmisjidcb.BaudRate=CBR_300;154 if (CheckBox4->Checked == TRUE)dcb.BaudRate=CBR_1200;if (CheckBox5->Checked == TRUE)dcb.BaudRate=CBR_9600;dcb.Parity = ODDPARITY; // ustawienie parzystościdcb.StopBits = ONESTOPBIT; // bity stopudcb.ByteSize = 7; // bity danych//-przykładowe ustawienia flag sterujących DCB-dcb.fParity = TRUE; // sprawdzanie parzystościdcb.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);GetCommMask(hCommDev, &fdwEvtMask);SetCommMask(hCommDev, EV_TXEMPTY);}else{switch ((int)hCommDev){case IE_BADID:MessageBox(NULL, "Niewłaściwa nazwa portu lub port jest"" aktywny.", "Błąd", MB_OK);break;};}}//--------------------------------------------------------------------void __fastcall TForm1::MeasureONClick(TObject *Sender){if (hCommDev > 0) // powtórnie sprawdza czy port jest otwarty{strcpy(Buffer_O, query);Timer1->Enabled = TRUE;}elseMessageBox(NULL, "Port nie został otwarty do transmisji.","Błąd", MB_OK);}//--------------------------------------------------------------------void __fastcall TForm1::TimerOnTimer(TObject *Sender){Write_Comm(hCommDev, strlen(Buffer_O));Sleep(100);Beep();FlushFileBuffers(hCommDev);Read_Comm(hCommDev, &Number_Bytes_Read, sizeof(Buffer_I));if (Number_Bytes_Read > 0)155 RichEdit1->Text = Buffer_I;}//--------------------------------------------------------------------Zledząc kod powyższego wydruku, można zauważyć, że program ten obsługuje miernik, który wodpowiedzi na komendę-zapytanie CDAT?\r\n automatycznie dokonuje odpowiedniego pomiaru,dodatkowo sygnalizując ten fakt brzęczkiem.W tym przykładzie przedział czasu odczytu z łączaustaliłem na 1000 milisekund.Można oczywiście robić to szybciej, niemniej jednak musimypamiętać o funkcji synchronizacji naszego interfejsu.Testowany przyrząd nie jest w staniezwrócić odpowiedzi (czyli dokonać nowego pomiaru) częściej niż raz na sekundę, dlatego szybszeodpytywanie nie ma sensu.Przed przystąpieniem do projektowania tego typu algorytmów należyw pierwszej kolejności dokładnie przeczytać instrukcję obsługi urządzenia.Zwróćmy też uwagę,że urządzenie to wymagało, by wysyłane polecenie zakończyć parą znaków \r\n, czyli powrótkaretki (CR) i znak nowego wiersza (LF).Aplikacja nie lubi milczećJak zapewne zauważyliśmy, projektując wszystkie przedstawione do tej pory programy,zwracaliśmy baczną uwagę na to, by aplikacja powiadamiała nas o problemach, jakie napotyka wczasie działania.Korzystaliśmy ze standardowych funkcji Windows, takich jak:extern PACKAGE void __fastcall ShowMessage(const System::AnsiStringMsg);extern PACKAGE int __fastcall MessageDlg(const System::AnsiString Msg,TMsgDlgType DlgType, TMsgDlgButtons Buttons, int HelpCtx);gdzie:enum TMsgDlgType { mtWarning, mtError, mtInformation, mtConfirmation,mtCustom };typedef Set TMsgDlgButtons;oraz z funkcji:int __fastcall MessageBox(char * Text, char * Caption, int Flags);Wszystkie one zostały już użyte w odpowiednich kontekstach, dlatego nie ma potrzebyponownego prezentowania sposobu umieszczenia ich w programie.W książce tej poruszamy temat komunikacji komputerowej poprzez interfejs RS 232C.Programy pisane przez nas mogą komunikować się z różnymi urządzeniami zewnętrznymi.156Oprócz wysokiej sprawności i niezawodności muszą one posiadać nie spotykaną gdzie indziejcechę, polegającą na możliwości błyskawicznego zdiagnozowania, czy w ogóle jest się z kimłączyć, tzn.czy urządzenie zewnętrzne istnieje (jest włączone).Może zdarzyć się i taka sytuacja,że miernik najzwyczajniej w świecie może się popsuć w trakcie pomiaru lub z jakiś innychwzględów odmówić dalszej współpracy (uszkodzone łącze lub linia transmisyjna).Aplikacjasterująca przyrządem nie tylko nie powinna się wówczas zawiesić, ale jeszcze powiadomić nas ozaistniałej sytuacji.Stosowana przez nas do tej pory konstrukcja:Read_Comm(hCommDev, &Number_Bytes_Read, sizeof(Buffer_I));if (Number_Bytes_Read > 0){// wyświetl odebrane dane}jest mało praktyczna jeżeli dane przestaną napływać w wyniku uszkodzenia przyrządu, to naekranie nie zobaczymy nic.Jedyną jej zaletą jest fakt, że program powinien dalej działać.Powiedzmy, że chcemy mieć informację o tym, że urządzenie się wyłączyło
[ Pobierz całość w formacie PDF ]