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
25 trang | 
Chia sẻ: luyenbuizn | Lượt xem: 1133 | 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 chapter8_.pdf