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
