Giáo trình Đo lường và điều khiển bằng máy tính - Chương 8: Lập trình giao tiếp nối tiếp
vụ cho truyền thông, với Visual Basic 4.0 là MSCOMM16.OCX
còn với Visual Basic 6.0 là MSCOMM32.OCX
Muốn cài trình đơn truyền thông vào thanh công cụ ta vào
Project- Components – Controls chọn Microsoft Comm Control
6.0/ OK (Hình 8.1), biểu tượng hình điện thoại sẽ hiện trên thanh
công cụ. Có thể nhắp chuột kép để đưa vào form của chương
trình. Các bước trên có thể làmtắt bằng phím Ctrl T. Thành
phần Comm khi mới đưa vào form thường được gán tên MSComm1
cho cổng Com1 và ta có thể sửa tên hay thay đổi cổng com tùy ý.
& Else Shape1(6).FillColor = &HFFFFFF End If If valLED7 = True Then Shape1(7).FillColor = &HFF& Else Shape1(7).FillColor = &HFFFFFF End If End If End Select Errlabel: Exit Sub End Sub Chương 8: LẬP TRÌNH GIAO TIẾP NỐI TIẾP Trang 225 Thành phố Hồ Chí Minh, tháng 4 năm 2006 8.3 LẬP TRÌNH DÙNG DELPHI 5.0 VÀ VISUAL C++6.0 MSComm có thể cài trong Delphi theo các bước sau: Vào menu Component – Import ActiveX Control -- Microft Comm Control 6.0 – Install để cài MSComm vào ActiveX. Sau đó vào toolbar ActiveX. tìm icon điện thoại để kéo vào Form. Các lệnh MSComm trong Delphi tương tự trong Visual Basic Đối với Visual C thì lập trình MSComm phức tạp hơn, sau đây là ví dụ cài đặt MSComm trong Visual C Tác giả: TS Nguyễn Đức Thành Trang 226 Cài đặt MSCOMM trong Visual C Nếu muốn thêm component truyền thông nối tiếp vào project bạn vào menu Project- Add to Project- Components and Controls Gallery Chọn mục Registered ActiveX Controls – Microsoft Communication Controls, version 6.0- Insert. Hình biểu tượng điện thoại xuất hiện trên thanh Control. Lập trình MSCOMM trong Visual C++ phức tạp hơn lập trình trong Visual Basic và Delphi, các hàm của lớp CMScomm được định nghĩa trong mscomm.h, sau đây là một đoạn trong file này cần tham khảo để gọi hàm cho đúng void SetCDHolding(BOOL bNewValue); BOOL GetCDHolding(); void SetCommID(long nNewValue); long GetCommID(); void SetCommPort(short nNewValue); short GetCommPort(); void SetCTSHolding(BOOL bNewValue); BOOL GetCTSHolding(); void SetDSRHolding(BOOL bNewValue); BOOL GetDSRHolding(); void SetDTREnable(BOOL bNewValue); Chương 8: LẬP TRÌNH GIAO TIẾP NỐI TIẾP Trang 227 Thành phố Hồ Chí Minh, tháng 4 năm 2006 BOOL GetDTREnable(); void SetHandshaking(long nNewValue); long GetHandshaking(); void SetInBufferSize(short nNewValue); short GetInBufferSize(); void SetInBufferCount(short nNewValue); short GetInBufferCount(); void SetBreak(BOOL bNewValue); BOOL GetBreak(); void SetInputLen(short nNewValue); short GetInputLen(); void SetNullDiscard(BOOL bNewValue); BOOL GetNullDiscard(); void SetOutBufferSize(short nNewValue); short GetOutBufferSize(); void SetOutBufferCount(short nNewValue); short GetOutBufferCount(); void SetParityReplace(LPCTSTR lpszNewValue); CString GetParityReplace(); void SetPortOpen(BOOL bNewValue); BOOL GetPortOpen(); void SetRThreshold(short nNewValue); short GetRThreshold(); void SetRTSEnable(BOOL bNewValue); BOOL GetRTSEnable(); void SetSettings(LPCTSTR lpszNewValue); CString GetSettings(); void SetSThreshold(short nNewValue); short GetSThreshold(); void SetOutput(const VARIANT& newValue); VARIANT GetOutput(); void SetInput(const VARIANT& newValue); VARIANT GetInput(); void SetCommEvent(short nNewValue); short GetCommEvent(); void SetEOFEnable(BOOL bNewValue); BOOL GetEOFEnable(); void SetInputMode(long nNewValue); long GetInputMode(); Tác giả: TS Nguyễn Đức Thành Trang 228 Ví dụ muốn truyền chuỗi what ta dùng đoạn lệnh sau CString strOutput = "What"; UCHAR myData = 0x00; strOutput += myData; m_Comm.SetPortOpen(true); // mở cổng m_Comm.SetOutput(COleVariant(strOutput)); Sau đây trình bày phần chính của chương trình serialDlg.cpp giao tiếp qua cổng Com, mời các bạn phân tích ý nghĩa các dòng lệnh, đề nghị tham khảo thêm hướng dẫn của VC++ // serialDlg.cpp : implementation file BOOL CSerialDlg::OnInitDialog() { CDialog::OnInitDialog(); SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon if(m_ctlMSCOMM1.GetPortOpen()) m_ctlMSCOMM1.SetPortOpen(FALSE); m_ctlMSCOMM1.SetCommPort(1); //đặt cấu hình port m_ctlMSCOMM1.SetSettings("9600,n,8,1"); m_ctlMSCOMM1.SetInputMode(0); m_ctlMSCOMM1.SetRThreshold(1); m_ctlMSCOMM1.SetSThreshold(0); m_ctlMSCOMM1.SetInputLen(0); m_ctlMSCOMM1.SetPortOpen(TRUE); return TRUE; } Chương 8: LẬP TRÌNH GIAO TIẾP NỐI TIẾP Trang 229 Thành phố Hồ Chí Minh, tháng 4 năm 2006 void CSerialDlg::OnExit() { m_ctlMSCOMM1.SetPortOpen(FALSE); OnOK(); } void CSerialDlg::OnSend() { UpdateData(TRUE); m_receive.Empty(); Send_str(m_send); UpdateData(FALSE); } void CSerialDlg::Send_str(CString str) { LPCSTR pstr=str; //đặt con trỏ cho chuỗi int i = str.GetLength(); BSTR bstr = SysAllocStringLen(0,i); //dành chỗ cho chuỗi Unicode bstr MultiByteToWideChar(CP_ACP,0,pstr,i+1,bstr,i+1); //đổi sang mã Unicode VARIANT dataout; dataout.vt=VT_BSTR; dataout.bstrVal=bstr; m_ctlMSCOMM1.SetOutput(dataout); //xuất chuỗi ra } void CSerialDlg::OnMscomm1() { if(m_ctlMSCOMM1.GetCommEvent()==2) { m_receive +=Get_str(); UpdateData(FALSE); } . } CString CSerialDlg::Get_str() { CHAR str[256]; VARIANT datain; Tác giả: TS Nguyễn Đức Thành Trang 230 datain.vt=VT_BSTR; datain=m_ctlMSCOMM1.GetInput(); WideCharToMultiByte(CP_ACP,0,datain.bstrVal,-1,str,256,NULL,NULL); return str; } Ngoài cách sử dụng công cụ MSComm còn có thể dùng các hàm của WinAPI 32. Do tính chất phức tạp của các hàm và giới hạn của giáo trình, xin trình bày vắn tắt để áp dụng vào chương trình trong Delphi và VC. Chi tiết có thể đọc trong Win 32 Program Reference. Sau đây là các hàm - Createfile, mở cổng COM hàm này trả về một biến (handle). Nếu không mở cổng được, biến trả về là –1, đóng cổng dùng lệnh closehandle, biến trả về là khác zero, nếu trả về zero là có lỗi. - Get Commstate: lấy cấu hình hiện tại của cổng cất vào khối DCB (device control block) - Set Commstate: đặt cấu hình cổng theo nội dung của DCB - Purge Comm: xóa bộ đệm vào ra, chấm dứt đọc, viết. - Writefile: viết data (xuất ra cổng Com) - Readfile: đọc cổng - EscapeCommFunction đặt: và xóa RTS hay DTR Unit modem: // chương trình minh họa các lệnh điều khiển modem dùng winapi và delphi 6.0 interface uses Windows, SysUtils; Var parity, stopbit, databit, cong:byte; tdo: dword; v, d, ta, td: real; hPort : longint; Send: array [1..50] of char; Receive: array [1..100] of char; i, sobyte: integer; kq: byte; Chương 8: LẬP TRÌNH GIAO TIẾP NỐI TIẾP Trang 231 Thành phố Hồ Chí Minh, tháng 4 năm 2006 stri: string; Procedure Close_Com; Procedure Open_Com (nCom: byte); Procedure Set_Com (baud:Dword; Prt:byte; Stpbits:byte; dtbits: byte); Procedure Gan_chuoi (Str: string); Procedure Dial (phone: string); Procedure Hang_up; Procedure Flush_Com; Function Send_Com (send_str: string; dWByte: Dword): Boolean; Function Get_Com_Buffer: longint; Function Receive_Com (dwByte: Dword): Boolean; Procedure doi_chuoi (ch: byte); Implementation { $R *.DFM} Procedure Close_Com; begin if hPort –1 then CloseHandle (hPort); hPort := –1; end; Procedure Open_Com (nCom : byte); var sCom: string; begin sCom := ‘COM’ + IntToStr (nCom); if hPort –1 then Close Com; hPort := CreateFile (Pchar (sCom), GENERIC_READ OR GENERIC_WRITE, 0, NIL, OPEN_EXISTING; FILE_ATTRIBUTE_NORMAL, longint (0)); end; Procedure Set_Com(baud: Dword, Prt: byte; Stpbits:byte;dtbits: byte); var dcbPort:TDCB; // khai bao kieu DCB begin if hPort –1 then begin if GetCommState (hPort, dcbPort) then begin dcbPort. BaudRate:= baud; dcbPort. Bytesize: = dtBits; dcbPort. Parity : = prt; dcbPort.StopBits : = DtpBits; dcbPort. Elags : = dcbport.flags or (RTS_CONTROL_ENABLE) OR (DTR_CONTROL_ENABLE): Tác giả: TS Nguyễn Đức Thành Trang 232 SetCommState (hPort, dcbPort); end; end; end; Procedure Gan_chuoi (Str : string); var i : byte; s: string; begin s:= Str; for i:= 1 to length (s) do send [i] := s [i]; end; Function Send_Com (send_str: string; dwByte: Dword): Boolean; var dwWritten: Dword; begin result:= strue; Gan_chuoi (send_str); if (hPort –1) then begin WriteFile (hPort, send, dwByte, dwWritten, nil); if dwWritten dwByte then begin result := false; exit; end; end else result := false; end; Procedure Flush_Com; begin if hPort –1 then // Loai bo cac ky tu trong in/out buffer PurgeComm (hPort, PURGE_RXABORT OR PURGE_TXABORT OR PURGE_RXCLEAR OR PURGE_TXCLEAR); end; Procedure Dial (phone : string); var s : string; begin Open_Com (cong); Set_Com (tdo, parity, stopbit, databit); Chương 8: LẬP TRÌNH GIAO TIẾP NỐI TIẾP Trang 233 Thành phố Hồ Chí Minh, tháng 4 năm 2006 s := ‘ATDT’ + Phone+#13; Flush_Com; Send_Com (s, length (s)); end; Function Get_Com_Buffer : longint; var statPort : TCOMSTAT; dwErrorCode : dWord; begin Result := 0; if hPort –1 then begin ClearCommError (hPort, dwErrorCode, @statPort); // Khoi phuc co bao loi Result := statPort. CbInQue; // lay so byte trong in buffer end; end; Function Receive_Com (dwByte : Dword) : Boolean; Var dwRead : Dword; begin begin ReadFile (hPort, Receive, dwByte, dwRead, nil); if dwRead dwByte then begin result := false; exit; end else result := true; end; end; Procedure Hang_Up: var s : string; begin s := ‘ATH0’ +#13; Open_Com (cong); Set_Com (tdo, parity, stopbit, databit); Flush_Com; Send_Com (s, length (s)); Close_Com; end; Procedure doi_chuoi (ch : byte); var f : byte; Tác giả: TS Nguyễn Đức Thành Trang 234 sbegin stri := ‘ ‘; for f := 1 to ch do begin if receive [j] = ‘Q’ then exit else Stri := Stri + receive [j]; end; end; END. -------O------ Bài tập gợi ý Viết chương trình giao tiếp PLC OMRON và SIEMENS
File đính kèm:
- Giáo trình Đo lường và điều khiển bằng máy tính - Chương 8 Lập trình giao tiếp nối tiếp.pdf