Tải bản đầy đủ (.pdf) (23 trang)

Bài giảng Đo lường và điều khiển bằng máy tính Chương 6 Lập trình giao tiếp nối tiếp

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (120.07 KB, 23 trang )

Chương

6

LẬP TRÌNH GIAO TIẾP NỐI TIẾP
6.1 LẬP TRÌNH TRONG DOS
Ngôn ngữ QBASIC

Lệnh khởi động cổng COM n:
OPEN “COM n, [Baud], [Parity], [Data], [Stop]” for RANDOM as #m
trong đó n = 1, 2, 3, 4; m = 1  255
Ví dụ: OPEN “COM 2, 9600, E, 7, 2” FOR RANDOM AS #1
Lệnh xuất ra một chuỗi S $
PRINT #1 , S $
Lệnh đọc vào một chuỗi R $
INPUT # 1, R $
Ngoài ra còn các lệnh truy xuất thanh ghi của vi mạch UART
Ngôn ngữ Pascal và C

Dùng các lệnh truy xuất thanh ghi như ở chương 7
Trong MS DOS ở dò ng lệnh đánh

MODE COM n : 96, E, 7, 1 sẽ mở COM n

6.2 LẬP TRÌNH NGÔN NGỮ VISUAL BASIC 6.0
Ngôn ngữ Visual Basic có module phần mềm MSCOMM.OCX phục 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 ProjectComponents – 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àm tắt bằn g


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 ý.

Các tính chất chính của trình đơn là Commport, DTREnable,


LẬP TRÌNH GIAO TIẾP NỐI TIẾP

211

EOFEnable, Handshaking, InBuffersize, InputLen, InputMode, NullDiscard,
OutBuffersize, ParityReplace, Rthreshold, RTSEnable, Settmgs, Sthreshold…
được đặt khi viết chương trình, có thể thay đổi khi chạy chương trình bằn g
các lệnh điều khiển.
Tính chấ t CommPort

Đặt cổng com được sử dụng
Object.CommPort [= Value]
Value = 1 đến 16, mặc đònh là 1 khi khởi động Visual Basic.
Tính chất này phải đặt trước khi mở cổng, nếu biểu thức trong ngoặc
không có thì trả về số cổng com đang hoạt động.


CHƯƠNG 6

212

Đặt cấu hình cổng
Object.Settings [= Value]
Value = “BBBB, P, D, S”

Gía trò mặc đònh là “9600, N, 8, 1”. Trong trường hợp đặt sai giá trò sẽ báo sự
cố.
Sau đây là các giá trò cho phép:
 Baud rate: 110, 300, 600, 1200, 2400, 9600 (Default), 14400, 19200,
28800, 38400, 56000, 128000, 256000
 Parity bit: E (even), M (Mark), N (Default), O (odd), S (Space)
 Data bit: 4, 5, 6, 7, 8 (Default)
 Stop bit: 1, 1.5, 2
Ví dụ:
MSComm2. Settings = “9600, N, 8, 1”

Mở cổng
Object.PortOpen [= True/ False]


LẬP TRÌNH GIAO TIẾP NỐI TIẾP

213

Value = True : mở cổng
Value = False : đóng cổng và xóa bộ đệm truyền thu,
Cổng tự động đóng khi kết thúc chương trình áp dụng.
Nhập dữ liệu

String$= Object.Input
Dữ liệu chuỗi ở bộ đệm thu được đọc vào biến String$ . Liên quan
đến đọc dữ liệu có các lệnh sau:
Object.InputLen [= numByte%]
InputLen: qui đònh số ký tự đọc bởi Input. Chọn InputLen = 0 sẽ cho
đọc toàn bộ vùng bộ đệm.

Object.InbufferSize = [numbyte%]
InBufferSize đặt và trả về kích thước theo byte của đệm thu, mặc đònh
là 1024.
Object.InbufferCount [= Count%]
InbufferCount: cho biết số ký hiệu có trong bộ đệm nhận. Xóa bộ
đệm bằng cách cho InbufferCount = 0
Object.InputMode [= value]
InputMode: cho biết loại dữ liệu là văn bản hay nhò phân
Value = 0 : ComInputModeText
Value = 1 : ComInputModeBinary
Ví dụ:
Dim Buffer as Variant
Dim Arr() as Byte
MSComm1.CommPort = 1
MSComm1.PortOpen = True
‘Set InputMode to read binary data
MSComm1.InputMode = comInputModeBinary
Do Until MSComm1.InBufferCount > 10
DoEvents
Loop
Buffer = MSComm1.Input
' Assign to byte array for processing
Arr = Buffer

Xuất dữ liệu

Object.Output [= value]


CHƯƠNG 6


214

Xuất chuỗi ký tự hay chuỗi nhò phân ra cổng COM.
Giống như nhập dữ liệu ta có các lệnh hỗ trợ.
OutBufferSize: đặt và trả lại kích thước bộ đệm truyền
OutBufferCount: trả lại số ký tự trong bộ đệ m truyền.
Ví dụ: gởi ký tự nhấn phím
Private Sub Form_KeyPress (KeyAscii As Integer)
Dim Buffer as Variant
MSComm1.CommPort = 1
MSComm1.PortOpen = True
Buffer = Chr$(KeyAscii)
MSComm1.Output = Buffer
End Sub

Ví dụ:
‘ gởi chuỗi ký tự
MsComm1.Output = "This is a text string”
‘ gởi số nhò phân
Dim Out( ) As Byte
MsComm1.Output = Out

Gởi tín hiệu Break

object.Break [= True/False]
Đọc chân DCD

inCD= object. CDHolding
nếu inCD True thì DCD ở mức cao, nếu False DCD ở mức thấp.

Đặt thờ i gian chờ sóng mang

object. CDTimeout [= milliseconds]
Chờ khoảng thời gian cho DCD ở mức cao, nếu hết thời gian mà
CDHolding = false thì tạo sự kiện onComm CDTO (carrier detect Timeout
Error).
Đọc CTS

object. CTS Holding
True: mức 1, False: mức 0
Đặt thờ i gian chờ CTS

Khi DTE gởi RTS thì modem phải gởi trả lại CTS, tính chất object.
CTSTimeout đònh thời gian chờ, nếu quá thời gian đó mà không có CTS thì
tạo sự kiện CTSTO.


LẬP TRÌNH GIAO TIẾP NỐI TIẾP

215

Đọc DSR

object. DSRHolding
Đặt thờ i gian chờ DSR

object. DSRTimeout
Điều khiể n DTR

object. DTREnable [=True/False] nếu True thì DTR mức 1 khi mở

cổng và mức 0 khi đóng cổng, nếu False thì DTR ở mức 0
Điều khiể n RTS

object. RTSEnable [ =True/False]
Khi True RTS sẽ ở mức 1 khi mở cổng và mức 0 khi đóng cổng
Sthreshold: đặ t số byte có trong bộ đệm truyề n để bá o sự kiệ n.
Nếu Sthreshold = 1 thì sẽ gọi onComm khi bộ đệm truyền rỗng.
Nếu Sthreshold = 0 thì không gọi.
Đặt số byte của bộ đệ m thu tố i thiểu để báo sự kiệ n

object. Rthreshold [= value]
Nếu đặt bằng 1 thì sẽ gọi onComm khi nhận được 1 ký tự.
Nếu đặt bằng 0 thì không gọi.
Giao thức bắt tay

object.Handshaking [= value]
Value = 0 không bắt tay
Value = 1 bắt tay theo RTS/CTS
=2
XON/XOFF
=3
RTS/XON/XOFF
Ví dụ:
Private Sub Form_Load ( )
Dim Buffer$ as string
‘ Dùng COM 1, 9600 baud, không parity, 8 bit data, 1 bit stop
MSComm1. Comport = 1
MSComm1. Settings = “9600, N, 8, 1”
‘ Đọc toàn bộ bộ đệm
MSComm1. Inputlen = 0

‘ Mở cổng và gởi lện h đến modem chế độ trả lời bằn g chữ
MSComm1. PortOpen = True
MSComm1. Output = “ATV1Q0” & Chr$(13)
‘ Chờ trả lời “OK”, nếu có OK thì đóng cổng
Do
DoEvents
Buffer$ = Buffer$ & MSComm1. Input


CHƯƠNG 6

216
Loop Until InStr (Buffer$, “OK” & vbCrLf)
MSComm1. PortOpen = False
End Sub

Chương trình trên dùng kỹ thuật hỏi vòng. Ta có thể dùng kỹ thuật sự
kiện object.CommEvent. Khi có sự kiện xảy ra chương trình cho cổn g
object_OnComm () sẽ được gọi để xử lý các sự kiện hay các lỗi.
Ví dụ:
Private Sub MSComm1_OnComm ( )
Select Case MSComm1. CommEvent
‘ Xử lý sự kiện hay lỗi bằn g các h đặt lện h dưới mỗi phát biểu Case
‘ Lỗi
Case ComEventBreak ‘Nhận Break
Case ComEventFrame ‘Sai frame
Case ComEventOverrun ‘Mất dữ liệu
Case ComEventRXOver ‘Đệm thu tràn
Case ComEventRXParity ‘Sai Parity
Case ComEventTXFull ‘Đệm phát đầy

Case ComEventDCB ‘Sai khi đọc DCB
‘ Sự kiện
Case ComEvCD ‘Đường CD thay đổi
Case ComEvCTS ‘CTS thay đổi
Case ComEvDSR ‘DSR thay đổi từ 1 xuốn g 0
Case ComEvRing ‘RI thay đổi
Case ComEvReceive ‘Số byte đệm thu đạt mức Rthreshold
Case ComEvSend ‘Số byte đệm phát ít hơn Sthreshold
Case ComEvEOF ‘Nhận ký tự EOF kết thúc file (mã ASCII 26) trong chuỗi nhập
End Select
End Sub.

Các lỗi khi sử dụng MSComm trình bày trong bảng sau
Lỗi
comInvalidPropertyValue
comSetNotSupported
comGetNotSupported
comPortOpen
comPortInvalid

comPortAlreadyOpen

Gía trò
380
383
394
8000
8001
8002
8003

8004
8005
8006
8007
8008
8009
8010

Miêu tả
Sai thuộc tính
Thuộc tính chỉ đọc
Thuộc tính chỉ đọc
Không thực hiện khi cổng đã mở
Gía trò Timeout phải lớn hơn 0
Số cổng không giá trò
Thuộc tính chỉ có khi chương trình chạy
Thuộc tính chỉ đọc khi chương trình chạy
Cổng đã mở rồi
Số nhận dạng thiết bò không phù hợp
Vận tốc truyền không phù hợp
Số byte đã đặt không giá tri
Thông số mặc đònh sai
Thiết bò không có sẵn


LẬP TRÌNH GIAO TIẾP NỐI TIẾP

comNoOpen

comSetCommStateFailed

comPortNotOpen
comReadError
comDCBError

8011
8012
8013
8014
8015
8016
8018
8019
8020
8021

217
The function cannot allocate the queues
Thiết bò không mở
Thiết bò đã mở
Could not enable comm notification
Không thể đặt trạng thái truyền thông
Không thể đạt mặt nạ che
Hoạt động chỉ thực hiện khi cổng mở
Thiết bò bận
Error reading comm device
Internal error retrieving device control block for the port

Ví dụ: chương trình quay số điện thoại qua modem

Option Explicit

' Variable names beginning with A through Z default to Integer.
DefInt A-Z
Dim CancelFlag, Default$
Private Sub CancelButton_Click()
' CancelFlag tells the Dial procedure to exit.
CancelFlag = True
CancelButton.Enabled = False
End Sub
Private Sub Dial(Number$)
Dim DialString$, FromModem$, dummy, i As Double
i=0
DialString$ = "ATDT" + Number$ + vbCr
' Dial the number.
MSComm1.Output = DialString$
' Wait for "OK" to come back from the modem.
Do
i=i+1
dummy = DoEvents()
' If there is data in the buffer, then read it.
If MSComm1.InBufferCount Then
FromModem$ = FromModem$ + MSComm1.Input
' Check for "OK".


CHÖÔNG 6

218
If InStr(FromModem$, "OK") Then
' Notify the user to pick up the phone.
Beep

MsgBox "Please pick up the phone and either press Enter or click OK"
Exit Do
End If
End If
' Did the user choose Cancel?
If i > 100000 Then
Beep
MsgBox "TimeOut, Please check cable and modem"
Exit Do
End If
If CancelFlag Then
CancelFlag = False
Exit Do
End If
Loop
' Disconnect the modem.
MSComm1.Output = "ATH" + vbCr
End Sub
Private Sub DialButton_Click()
Dim Number$, Temp$
DialButton.Enabled = False
QuitButton.Enabled = False
CancelButton.Enabled = True
' Get the number to dial.
Number$ = InputBox$("Enter phone number:", , Default$)
If Number$ = "" Then
DialButton.Enabled = True
QuitButton.Enabled = True
CancelButton.Enabled = False
Exit Sub

End If
Temp$ = Status
Default$ = Number$
Status = "Dialing - " + Number$
' Dial the selected phone number.
Dial Number$
DialButton.Enabled = True
QuitButton.Enabled = True
CancelButton.Enabled = False


LẬP TRÌNH GIAO TIẾP NỐI TIẾP
Status = Temp$
End Sub
Private Sub Form_Load()
Default$ = "8654357"
MSComm1.CommPort = 1
MSComm1.Settings = "9600,N,8,1"
On Error Resume Next
MSComm1.PortOpen = True
If Err Then
MsgBox "COM1: not available. Change the CommPort property to another port."
Exit Sub
End If
MSComm1.InBufferCount = 0
MSComm1.InputLen = 0
End Sub
Private Sub QuitButton_Click()
' Close the port.
MSComm1.PortOpen = False

End
End Sub

Ví dụ: ghép nối vi điều khiển 8951 điều khiển port 0
ORG 0000H
MOV IE,#00000000B
MOV TMOD,#00100000
MOV TL1#,0FDH
MOV TH1,#0FDH
MOV SCON,#01010000B
SETB TR1
MOV P0,#00000000B
INDEX:

ACALL SUB_RXD
ACALL LEDOFF
ACALL LED1
ACALL LED2
ACALL LED3
ACALL LED4
ACALL LED5
ACALL LED6
ACALL LED7
SJMP INDEX

RXD :

JNB RI,$
CLR RI
MOV A,SBUF


219


CHÖÔNG 6

220
RET
LEDOFF:

CJNE A,#30H,NEXT
MOV P0,#00000000B
ACALL SUB_TXD
SJMP INDEX

LED1:

CJNE A,#31H,NEXT
CPL P0.0
ACALL SUB_TXD
SJMP INDEX

LED2:

CJNE A,#32H,NEXT
CPL P0.1
ACALL SUB_TXD
SJMP INDEX

LED3:


CJNE A,#33H,NEXT
CPL P0.2
ACALL SUB_TXD
SJMP INDEX

LED4:

CJNE A,#34H,NEXT
CPL P0.3
ACALL SUB_TXD
SJMP INDEX

LED5:

CJNE A,#35H,NEXT
CPL P0.4
ACALL SUB_TXD
SJMP INDEX

LED6:

CJNE A,#36H,NEXT
CPL P0.5
ACALL SUB_TXD
SJMP INDEX

LED7:

CJNE A,#37H,NEXT

CPL P0.6
ACALL SUB_TXD
SJMP INDEX

NEXT:
TXD :

RET
MOV SBUF,#43
JNB TI,$
CLR TI
RET
END

Chöông trình maùy tính


LAÄP TRÌNH GIAO TIEÁP NOÁI TIEÁP

Private Sub Command8_Click() ‘ Communication Setting
On Error GoTo Errlabel
MSComm1.Settings = Text1.Text
MSComm1.CommPort = Combo1.ListIndex + 1
MSComm1.RThreshold = 1
MSComm1.PortOpen = True
MSComm1.InputLen = 0
Exit Sub
Errlabel:
If Err.Number = 8002 Then MsgBox "Select com Port", vbInformation, "8051 Control I/O"
End Sub

Private Sub Command1_Click()
MSComm1.Output = "1"
valLED1 = Not valLED1
End Sub
Private Sub Command2_Click()
MSComm1.Output = "2"
valLED2 = Not valLED2

221


222
End Sub
Private Sub Command3_Click()
MSComm1.Output = "3"
valLED3 = Not valLED3
End Sub
Private Sub Command4_Click()
MSComm1.Output = "4"
valLED4 = Not valLED4
End Sub
Private Sub Command5_Click()
MSComm1.Output = "5"
valLED5 = Not valLED5
End Sub
Private Sub Command6_Click()
MSComm1.Output = "6"
valLED6 = Not valLED6
End Sub
Private Sub Command7_Click()

MSComm1.Output = "7"
valLED7 = Not valLED7
End Sub
Private Sub Command9_Click()
MSComm1.Output = "0"
valLED = Not valLED
End Sub
Private Sub MSComm1_OnComm()
Select Case MSComm1.CommEvent
Case comEvReceive
Dim Buffer As Variant
Buffer = MSComm1.Input
Label2.Caption = "Return = " & Buffer
If Buffer = "C" Then
If valLED = True Then
For x = 0 To 7 Step 1
Shape1(x).FillColor = &HFFFFFF
Next
Shape1(0).FillColor = &HFF&
valLED1 = False
valLED2 = False
valLED3 = False
valLED4 = False
valLED5 = False
valLED6 = False
valLED7 = False
Command9.Caption = "ON ALL"
Exit Sub
Else
Shape1(0).FillColor = &HFFFFFF

Command9.Caption = "OFF ALL"
End If
If valLED1 = True Then

CHÖÔNG 6


LẬP TRÌNH GIAO TIẾP NỐI TIẾP
Shape1(1).FillColor =
Else
Shape1(1).FillColor =
End If
If valLED2 = True Then
Shape1(2).FillColor =
Else
Shape1(2).FillColor =
End If
If valLED3 = True Then
Shape1(3).FillColor =
Else
Shape1(3).FillColor =
End If
If valLED4 = True Then
Shape1(4).FillColor =
Else
Shape1(4).FillColor =
End If
If valLED5 = True Then
Shape1(5).FillColor =
Else

Shape1(5).FillColor =
End If
If valLED6 = True Then
Shape1(6).FillColor =
Else
Shape1(6).FillColor =
End If
If valLED7 = True Then
Shape1(7).FillColor =
Else
Shape1(7).FillColor =
End If
End If
End Select
Errlabel:
Exit Sub
End Sub

223

&HFF&
&HFFFFFF

&HFF&
&HFFFFFF

&HFF&
&HFFFFFF

&HFF&

&HFFFFFF

&HFF&
&HFFFFFF

&HFF&
&HFFFFFF

&HFF&
&HFFFFFF

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.


CHƯƠNG 6

224

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
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



LẬP TRÌNH GIAO TIẾP NỐI TIẾP

225

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);
BOOL GetDTREnable();
void SetHandshaking(long nNewValue);
long GetHandshaking();
void SetInBufferSize(short nNewValue);
short GetInBufferSize();
void SetInBufferCount(short nNewValue);
short GetInBufferCount();



CHƯƠNG 6

226
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();

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ổn g
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++


LAP TRèNH GIAO TIEP NOI TIEP

// 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); //ủaởt caỏ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;
}

void CSerialDlg::OnExit()
{
m_ctlMSCOMM1.SetPortOpen(FALSE);
OnOK();
}
void CSerialDlg::OnSend()
{
UpdateData(TRUE);
m_receive.Empty();
Send_str(m_send);

227


CHƯƠNG 6

228
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;
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


LẬP TRÌNH GIAO TIẾP NỐI TIẾP

229

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;
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;


CHÖÔNG 6

230
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):
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


LAÄP TRÌNH GIAO TIEÁP NOÁI TIEÁP

231
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);
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;


CHệễNG 6

232
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;
sbegin
stri := ;
for f := 1 to ch do
begin
if receive [j] = Q then
exit
else
Stri := Stri + receive [j];
end;
end;
END.

-------O------

Baứi taọp gụùi yự
Vieỏt chửụng trỡnh giao tieỏp PLC OMRON vaứ SIEMENS



×