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
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 ý.
25 trang |
Chia sẻ: luyenbuizn | Lượt xem: 990 | Lượt tải: 0
Bạn đang xem trước 20 trang nội dung tài liệu Lập trình giao tiếp nối tiếp, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
Chương 8
LẬP TRÌNH GIAO TIẾP NỐI TIẾP
8.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
8.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
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àm tắ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 ý.
Chương 8: LẬP TRÌNH GIAO TIẾP NỐI TIẾP Trang 211
Thành phố Hồ Chí Minh, tháng 4 năm 2006
Các tính chất chính của trình đơn là Commport, DTREnable,
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ằng 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.
Tác giả: TS Nguyễn Đức Thành Trang 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”
Chương 8: LẬP TRÌNH GIAO TIẾP NỐI TIẾP Trang 213
Thành phố Hồ Chí Minh, tháng 4 năm 2006
Mở cổng
Object.PortOpen [= True/ False]
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
Tác giả: TS Nguyễn Đức Thành Trang 214
Arr = Buffer
Xuất dữ liệu
Object.Output [= value]
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
Chương 8: LẬP TRÌNH GIAO TIẾP NỐI TIẾP Trang 215
Thành phố Hồ Chí Minh, tháng 4 năm 2006
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.
Đọ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
Tác giả: TS Nguyễn Đức Thành Trang 216
‘ 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ệnh đến modem chế độ trả lời bằng 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
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ổng 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ằng cách đặt lệnh 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ống 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
Chương 8: LẬP TRÌNH GIAO TIẾP NỐI TIẾP Trang 217
Thành phố Hồ Chí Minh, tháng 4 năm 2006
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 Gía trị Miêu tả
comInvalidPropertyValue 380 Sai thuộc tính
comSetNotSupported 383 Thuộc tính chỉ đọc
comGetNotSupported 394 Thuộc tính chỉ đọc
comPortOpen 8000 Không thực hiện khi cổng đã mở
8001 Gía trị Timeout phải lớn hơn 0
comPortInvalid 8002 Số cổng không giá trị
8003 Thuộc tính chỉ có khi chương trình chạy
8004 Thuộc tính chỉ đọc khi chương trình chạy
comPortAlreadyOpen 8005 Cổng đã mở rồi
8006 Số nhận dạng thiết bị không phù hợp
8007 Vận tốc truyền không phù hợp
8008 Số byte đã đặt không giá tri
8009 Thông số mặc định sai
8010 Thiết bị không có sẵn
8011 The function cannot allocate the queues
comNoOpen 8012 Thiết bị không mở
8013 Thiết bị đã mở
8014 Could not enable comm notification
comSetCommStateFailed 8015 Không thể đặt trạng thái truyền thông
8016 Không thể đạt mặt nạ che
comPortNotOpen 8018 Hoạt động chỉ thực hiện khi cổng mở
8019 Thiết bị bận
comReadError 8020 Error reading comm device
comDCBError 8021 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
Tác giả: TS Nguyễn Đức Thành Trang 218
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".
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.
Chương 8: LẬP TRÌNH GIAO TIẾP NỐI TIẾP Trang 219
Thành phố Hồ Chí Minh, tháng 4 năm 2006
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
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()
Tác giả: TS Nguyễn Đức Thành Trang 220
' 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
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
Chương 8: LẬP TRÌNH GIAO TIẾP NỐI TIẾP Trang 221
Thành phố Hồ Chí Minh, tháng 4 năm 2006
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: RET
TXD : MOV SBUF,#43
JNB TI,$
CLR TI
RET
END
Chương trình máy tính
Tác giả: TS Nguyễn Đức Thành Trang 222
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
Chương 8: LẬP TRÌNH GIAO TIẾP NỐI TIẾP Trang 223
Thành phố Hồ Chí Minh, tháng 4 năm 2006
Private Sub Command2_Click()
MSComm1.Output = "2"
valLED2 = Not valLED2
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
Tác giả: TS Nguyễn Đức Thành Trang 224
Command9.Caption = "ON ALL"
Exit Sub
Else
Shape1(0).FillColor = &HFFFFFF
Command9.Caption = "OFF ALL"
End If
If valLED1 = True Then
Shape1(1).FillColor = &HFF&
Else
Shape1(1).FillColor = &HFFFFFF
End If
If valLED2 = True Then
Shape1(2).FillColor = &HFF&
Else
Shape1(2).FillColor = &HFFFFFF
End If
If valLED3 = True Then
Shape1(3).FillColor = &HFF&
Else
Shape1(3).FillColor = &HFFFFFF
End If
If valLED4 = True Then
Shape1(4).FillColor = &HFF&
Else
Shape1(4).FillColor = &HFFFFFF
End If
If valLED5 = True Then
Shape1(5).FillColor = &HFF&
Else
Shape1(5).FillColor = &HFFFFFF
End If
If valLED6 = True Then
Shape1(6).FillColor = &HFF&
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_C
Các file đính kèm theo tài liệu này:
- chapter8_.pdf